import { useEffect, useState } from 'react'
import { Link, useNavigate, useParams } from 'react-router-dom'
import { ArrowLeft } from 'lucide-react'
import { InvoiceDraftFields } from '../components/InvoiceDraftFields'
import { isEmptyRichText, RichTextEditor } from '../components/RichTextEditor'
import { useToast } from '../context/ToastContext'
import { ApiError, isAbortError } from '../lib/api'
import {
  createInvoiceTemplate,
  getInvoiceTemplate,
  listInvoiceItemTemplates,
  updateInvoiceTemplate,
} from '../services/invoiceService'
import type { InvoiceItemTemplate } from '../types/invoice'
import {
  buildAccountsPayload,
  buildKeyPointsPayload,
  buildTemplateItemsPayload,
  draftsFromInvoiceTemplate,
  emptyDraftItem,
  type DraftAccount,
  type DraftKeyPoint,
  type DraftLineItem,
} from '../utils/invoiceDraft'
import pageStyles from '../components/PageContent.module.css'
import tableStyles from './BusinessesPage.module.css'
import invoiceStyles from './BusinessInvoicesPage.module.css'
import styles from './SettingsPage.module.css'

export function InvoiceTemplateEditorPage() {
  const { templateId } = useParams()
  const isEdit = Boolean(templateId)
  const navigate = useNavigate()
  const { showToast } = useToast()

  const [itemTemplates, setItemTemplates] = useState<InvoiceItemTemplate[]>([])
  const [loading, setLoading] = useState(isEdit)
  const [error, setError] = useState('')
  const [name, setName] = useState('')
  const [topText, setTopText] = useState('')
  const [items, setItems] = useState<DraftLineItem[]>([emptyDraftItem()])
  const [keyPoints, setKeyPoints] = useState<DraftKeyPoint[]>([])
  const [accounts, setAccounts] = useState<DraftAccount[]>([])
  const [selectedItemTemplateId, setSelectedItemTemplateId] = useState('')
  const [submitting, setSubmitting] = useState(false)
  const [formError, setFormError] = useState('')

  useEffect(() => {
    const controller = new AbortController()

    async function load() {
      setLoading(true)
      setError('')
      try {
        const itemsRes = await listInvoiceItemTemplates(controller.signal)
        setItemTemplates(itemsRes.items.filter((t) => t.isActive))

        if (templateId) {
          const template = await getInvoiceTemplate(templateId, controller.signal)
          const drafts = draftsFromInvoiceTemplate(template)
          setName(drafts.name)
          setTopText(drafts.topText)
          setItems(drafts.items)
          setKeyPoints(drafts.keyPoints)
          setAccounts(drafts.accounts)
        }
      } catch (err) {
        if (isAbortError(err)) return
        setError(err instanceof ApiError ? err.message : 'Unable to load template editor.')
      } finally {
        setLoading(false)
      }
    }

    void load()
    return () => controller.abort()
  }, [templateId])

  async function handleSave() {
    setFormError('')
    if (!name.trim()) {
      setFormError('Template name is required.')
      return
    }
    let lineItems
    try {
      lineItems = buildTemplateItemsPayload(items)
    } catch (err) {
      setFormError(err instanceof Error ? err.message : 'Invalid line items.')
      return
    }

    const payload = {
      name: name.trim(),
      topText: isEmptyRichText(topText) ? undefined : topText,
      items: lineItems,
      keyPoints: buildKeyPointsPayload(keyPoints),
      accounts: buildAccountsPayload(accounts),
    }

    setSubmitting(true)
    try {
      if (templateId) {
        await updateInvoiceTemplate(templateId, payload)
        showToast('Invoice template updated.', 'success')
      } else {
        await createInvoiceTemplate(payload)
        showToast('Invoice template created.', 'success')
      }
      navigate('/settings')
    } catch (err) {
      setFormError(err instanceof ApiError ? err.message : 'Unable to save invoice template.')
    } finally {
      setSubmitting(false)
    }
  }

  return (
    <main className={pageStyles.content}>
      <div className={pageStyles.pageHeader}>
        <div>
          <Link to="/settings" className={invoiceStyles.backLink}>
            <ArrowLeft size={16} />
            Back to settings
          </Link>
          <h2 className={pageStyles.pageTitle}>
            {isEdit ? 'Edit invoice template' : 'Add invoice template'}
          </h2>
          <p className={pageStyles.pageSubtitle}>
            Define name, top text, line items, key points, and bank accounts for reuse when issuing
            invoices.
          </p>
        </div>
      </div>

      {error ? <p className={styles.alertError}>{error}</p> : null}
      {loading ? <p className={tableStyles.meta}>Loading…</p> : null}

      {!loading ? (
        <section className={styles.section}>
          <div className={invoiceStyles.metaGrid}>
            <div className={`${tableStyles.field} ${styles.span2}`}>
              <label htmlFor="tpl-name">Name</label>
              <input
                id="tpl-name"
                value={name}
                onChange={(e) => setName(e.target.value)}
                placeholder="e.g. Standard website package"
              />
            </div>
          </div>

          <div className={`${tableStyles.field} ${invoiceStyles.fullField}`}>
            <label>Top text</label>
            <RichTextEditor
              value={topText}
              onChange={setTopText}
              placeholder="Optional intro shown at the top of the invoice"
              editorMinHeight={88}
            />
          </div>

          <InvoiceDraftFields
            itemTemplates={itemTemplates}
            items={items}
            keyPoints={keyPoints}
            accounts={accounts}
            selectedItemTemplateId={selectedItemTemplateId}
            onSelectedItemTemplateId={setSelectedItemTemplateId}
            onItemsChange={setItems}
            onKeyPointsChange={setKeyPoints}
            onAccountsChange={setAccounts}
          />

          {formError ? <p className={styles.alertError}>{formError}</p> : null}

          <div className={tableStyles.actionsRow}>
            <button
              type="button"
              className={`${tableStyles.btn} ${tableStyles.btnGhost}`}
              onClick={() => navigate('/settings')}
              disabled={submitting}
            >
              Cancel
            </button>
            <button
              type="button"
              className={`${tableStyles.btn} ${tableStyles.btnPrimary}`}
              onClick={() => void handleSave()}
              disabled={submitting}
            >
              {submitting ? 'Saving…' : isEdit ? 'Save changes' : 'Create template'}
            </button>
          </div>
        </section>
      ) : null}
    </main>
  )
}
