import { useEffect, useMemo, useState } from 'react'

import { brandDefaults } from './brand/brandDefaults'
import type { Brand } from './email/types'
import { interpolate } from './email/interpolate'
import { renderEmailTemplate } from './email/render'
import { BrandEditor } from './components/BrandEditor'
import { TemplatePicker } from './components/TemplatePicker'
import { VariablesForm } from './components/VariablesForm'
import { EmailPreview } from './components/EmailPreview'
import { ExportPanel } from './components/ExportPanel'
import { templateRegistry } from './templates/templates'

function initDataForTemplate(templateVars: { key: string; defaultValue?: string }[]) {
  // Keep defaults stable when brand changes; this function only depends on template.
  const next: Record<string, string> = {}
  for (const v of templateVars) next[v.key] = v.defaultValue ?? ''
  return next
}

export default function App() {
  const templates = templateRegistry
  const [brand, setBrand] = useState<Brand>(brandDefaults)
  const [templateId, setTemplateId] = useState<string>(templates[0]?.id ?? '')
  const template = useMemo(() => templates.find((t) => t.id === templateId) ?? templates[0], [templateId, templates])

  const [data, setData] = useState<Record<string, string>>(() => {
    return initDataForTemplate(template?.variables ?? [])
  })

  const handleTemplateChange = (nextId: string) => {
    setTemplateId(nextId)

    // Update variables immediately so the preview/exports switch reliably.
    const nextTemplate = templates.find((t) => t.id === nextId)
    if (nextTemplate) setData(initDataForTemplate(nextTemplate.variables))
  }

  const subject = useMemo(() => {
    if (!template) return ''
    return interpolate(template.subjectTemplate, { ...data, hotelName: brand.hotelName })
  }, [template, data, brand.hotelName])

  const [html, setHtml] = useState<string>('')
  const [text, setText] = useState<string>('')
  const [loading, setLoading] = useState(false)
  const [error, setError] = useState<string | null>(null)

  useEffect(() => {
    if (!template) return

    let cancelled = false
    // Clear previous output immediately so the iframe can't appear "stuck".
    setHtml('')
    setText('')
    const handle = setTimeout(async () => {
      setLoading(true)
      setError(null)
      try {
        const res = await renderEmailTemplate({ brand, template, data })
        if (cancelled) return
        setHtml(res.html)
        setText(res.text)
      } catch (e) {
        if (cancelled) return
        setError(e instanceof Error ? e.message : 'Failed to render template')
        setHtml('')
        setText('')
      } finally {
        if (cancelled) return
        setLoading(false)
      }
    }, 350)

    return () => {
      cancelled = true
      clearTimeout(handle)
    }
  }, [brand, template, data])

  const styles = {
    page: {
      minHeight: '100vh',
      padding: 18,
      background: '#0b1220',
      color: '#e5e7eb',
      fontFamily:
        'ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial, "Apple Color Emoji", "Segoe UI Emoji"',
    },
    grid: {
      display: 'grid',
      gridTemplateColumns: 'repeat(auto-fit, minmax(360px, 1fr))',
      gap: 16,
      alignItems: 'start',
    },
    card: {
      background: '#0f172a',
      border: '1px solid rgba(148, 163, 184, 0.25)',
      borderRadius: 14,
      padding: 14,
    },
    sectionTitle: {
      margin: 0,
      fontSize: 14,
      fontWeight: 700,
      color: '#f1f5f9',
    },
  }

  return (
    <div style={styles.page}>
      <div style={{ maxWidth: 1280, margin: '0 auto', display: 'grid', gap: 16 }}>
        <header style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline' }}>
          <div>
            <div style={{ fontSize: 18, fontWeight: 800 }}>Resend-ready Email Templates</div>
            <div style={{ fontSize: 12, opacity: 0.75, marginTop: 4 }}>
              Edit branding + variables, preview the branded email, then export HTML + plain text.
            </div>
          </div>
          <div style={{ fontSize: 12, opacity: 0.75 }}>
            Template: <strong style={{ color: '#fff' }}>{template?.name ?? '-'}</strong>
          </div>
        </header>

        <div style={styles.grid}>
          <aside style={styles.card}>
            <div style={{ display: 'grid', gap: 14 }}>
              <BrandEditor brand={brand} onChange={setBrand} />
              <TemplatePicker templates={templates} value={templateId} onChange={handleTemplateChange} />
              {template ? <VariablesForm key={templateId} template={template} data={data} onChange={setData} /> : null}

              <div style={{ display: 'grid', gap: 8 }}>
                <div style={{ ...styles.sectionTitle, fontSize: 14 }}>Status</div>
                {loading ? (
                  <div style={{ fontSize: 13, opacity: 0.9 }}>Rendering email...</div>
                ) : error ? (
                  <div style={{ fontSize: 13, color: '#fca5a5', whiteSpace: 'pre-wrap' }}>{error}</div>
                ) : (
                  <div style={{ fontSize: 13, opacity: 0.85 }}>Preview generated.</div>
                )}
              </div>
            </div>
          </aside>

          <main style={styles.card}>
            {template ? (
              <div style={{ display: 'grid', gap: 16 }}>
                <EmailPreview key={templateId} html={html} loading={loading} />

                <ExportPanel key={templateId} subject={subject} html={html} text={text} loading={loading} />
              </div>
            ) : (
              <div>No template selected.</div>
            )}
          </main>
        </div>
      </div>
    </div>
  )
}
