import { useEffect, useState } from 'react'
import { Plus, Trash2, X } from 'lucide-react'
import { api } from '../lib/api'
import type { Account, Folder, MatchType, NewRule, Rule, RuleAction, RuleCondition } from '../types'

const inputClass =
  'rounded-lg border border-zinc-200 bg-white px-3 py-1.5 text-[13px] text-zinc-800 outline-none transition focus:border-indigo-400 focus:ring-2 focus:ring-indigo-100 dark:border-zinc-700 dark:bg-zinc-900 dark:text-zinc-100 dark:focus:ring-indigo-500/20'

function Field({ label, children }: { label: string; children: React.ReactNode }) {
  return (
    <label className="flex flex-col gap-1">
      <span className="text-[11.5px] font-medium text-zinc-500 dark:text-zinc-400">{label}</span>
      {children}
    </label>
  )
}

function conditionsSummary(conditions: RuleCondition[], matchType: MatchType) {
  const parts = conditions.map((c) => `${c.field === 'subject' ? 'Betreff' : 'Absender'} enthält „${c.contains}“`)
  const joiner = matchType === 'all' ? ' UND ' : ' ODER '
  return parts.join(joiner)
}

function actionLabel(r: Rule, accountFolders: Record<string, Folder[]>) {
  switch (r.action) {
    case 'move_to': {
      const folders = r.account_id ? accountFolders[r.account_id] ?? [] : []
      const folder = folders.find((f) => f.name === r.action_value)
      return `verschieben nach „${folder?.display_name ?? r.action_value}“`
    }
    case 'mark_read':
      return 'als gelesen markieren'
    case 'flag':
      return 'markieren'
    case 'delete':
      return 'löschen'
  }
}

const emptyCondition = (): RuleCondition => ({ field: 'from', contains: '' })

export function RulesModal({
  open,
  onClose,
  accounts,
  accountFolders,
  onToast,
}: {
  open: boolean
  onClose: () => void
  accounts: Account[]
  accountFolders: Record<string, Folder[]>
  onToast: (msg: string) => void
}) {
  const [rules, setRules] = useState<Rule[]>([])
  const [loading, setLoading] = useState(false)

  const [accountId, setAccountId] = useState('')
  const [conditions, setConditions] = useState<RuleCondition[]>([emptyCondition()])
  const [matchType, setMatchType] = useState<MatchType>('all')
  const [action, setAction] = useState<RuleAction>('move_to')
  const [actionValue, setActionValue] = useState('')
  const [saving, setSaving] = useState(false)

  const ruleAccounts = accounts.filter((a) => a.protocol === 'imap' || a.protocol === 'pop3')
  const targetFolders = accountId ? accountFolders[accountId] ?? [] : []
  const validConditions = conditions.filter((c) => c.contains.trim())
  const isPop3 = accounts.find((a) => a.id === accountId)?.protocol === 'pop3'

  function refresh() {
    setLoading(true)
    api
      .listRules()
      .then(setRules)
      .catch((e) => onToast(`Regeln konnten nicht geladen werden: ${e}`))
      .finally(() => setLoading(false))
  }

  useEffect(() => {
    if (open) refresh()
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [open])

  if (!open) return null

  function updateCondition(index: number, patch: Partial<RuleCondition>) {
    setConditions((prev) => prev.map((c, i) => (i === index ? { ...c, ...patch } : c)))
  }

  function addCondition() {
    setConditions((prev) => [...prev, emptyCondition()])
  }

  function removeCondition(index: number) {
    setConditions((prev) => (prev.length > 1 ? prev.filter((_, i) => i !== index) : prev))
  }

  async function handleAdd(e: React.FormEvent) {
    e.preventDefault()
    if (validConditions.length === 0) return
    if (action === 'move_to' && !actionValue) return
    setSaving(true)
    try {
      const newRule: NewRule = {
        account_id: accountId || null,
        conditions: validConditions.map((c) => ({ field: c.field, contains: c.contains.trim() })),
        match_type: matchType,
        action,
        action_value: action === 'move_to' ? actionValue : undefined,
      }
      await api.createRule(newRule)
      setConditions([emptyCondition()])
      setMatchType('all')
      setActionValue('')
      refresh()
      onToast('Regel erstellt')
    } catch (err) {
      onToast(`Fehlgeschlagen: ${err}`)
    } finally {
      setSaving(false)
    }
  }

  async function handleToggle(r: Rule) {
    setRules((prev) => prev.map((x) => (x.id === r.id ? { ...x, enabled: !x.enabled } : x)))
    try {
      await api.setRuleEnabled(r.id, !r.enabled)
    } catch (err) {
      onToast(String(err))
    }
  }

  async function handleDelete(r: Rule) {
    setRules((prev) => prev.filter((x) => x.id !== r.id))
    try {
      await api.deleteRule(r.id)
    } catch (err) {
      onToast(String(err))
    }
  }

  return (
    <div className="animate-overlay-in fixed inset-0 z-50 flex items-center justify-center bg-zinc-900/40 p-6 backdrop-blur-sm dark:bg-black/60">
      <div className="animate-panel-in flex max-h-[85vh] w-full max-w-lg flex-col overflow-hidden rounded-[28px] border border-white/70 bg-white/95 shadow-[0_24px_70px_-12px_rgba(15,15,25,0.35)] ring-1 ring-black/[0.03] backdrop-blur-2xl dark:border-white/10 dark:bg-zinc-900/90 dark:shadow-[0_24px_70px_-12px_rgba(0,0,0,0.6)]">
        <div className="flex items-center justify-between border-b border-zinc-200/70 px-6 py-4 dark:border-zinc-800/70">
          <h2 className="text-[15px] font-semibold tracking-tight text-zinc-800 dark:text-zinc-100">
            Regeln verwalten
          </h2>
          <button
            onClick={onClose}
            className="rounded-full p-1.5 text-zinc-400 transition hover:bg-zinc-100 hover:text-zinc-600 dark:hover:bg-zinc-800"
          >
            <X size={16} />
          </button>
        </div>

        <div className="flex-1 space-y-4 overflow-y-auto px-6 py-5">
          <form onSubmit={handleAdd} className="space-y-2.5 rounded-2xl border border-zinc-200/80 bg-zinc-50/60 p-3.5 dark:border-zinc-800 dark:bg-zinc-950/40">
            <p className="text-[11px] font-semibold tracking-wide text-zinc-400 uppercase">Neue Regel</p>
            <Field label="Konto">
              <select
                className={inputClass}
                value={accountId}
                onChange={(e) => {
                  setAccountId(e.target.value)
                  const nowPop3 = accounts.find((a) => a.id === e.target.value)?.protocol === 'pop3'
                  if (nowPop3 && action === 'move_to') setAction('mark_read')
                }}
              >
                <option value="">Alle Konten</option>
                {ruleAccounts.map((a) => (
                  <option key={a.id} value={a.id}>
                    {a.label}
                    {a.protocol === 'pop3' ? ' (POP3)' : ''}
                  </option>
                ))}
              </select>
            </Field>

            <div className="space-y-1.5">
              <div className="flex items-center justify-between">
                <span className="text-[11.5px] font-medium text-zinc-500 dark:text-zinc-400">Bedingungen</span>
                {conditions.length > 1 && (
                  <div className="flex rounded-lg bg-zinc-200/60 p-0.5 text-[11px] dark:bg-zinc-800/60">
                    <button
                      type="button"
                      onClick={() => setMatchType('all')}
                      className={`rounded-md px-2 py-0.5 transition ${matchType === 'all' ? 'bg-white font-medium text-zinc-800 shadow-sm dark:bg-zinc-700 dark:text-zinc-100' : 'text-zinc-500'}`}
                    >
                      Alle (UND)
                    </button>
                    <button
                      type="button"
                      onClick={() => setMatchType('any')}
                      className={`rounded-md px-2 py-0.5 transition ${matchType === 'any' ? 'bg-white font-medium text-zinc-800 shadow-sm dark:bg-zinc-700 dark:text-zinc-100' : 'text-zinc-500'}`}
                    >
                      Eine (ODER)
                    </button>
                  </div>
                )}
              </div>
              {conditions.map((c, i) => (
                <div key={i} className="flex gap-2">
                  <select
                    className={`${inputClass} w-28 shrink-0`}
                    value={c.field}
                    onChange={(e) => updateCondition(i, { field: e.target.value })}
                  >
                    <option value="from">Absender</option>
                    <option value="subject">Betreff</option>
                  </select>
                  <input
                    className={`${inputClass} flex-1`}
                    value={c.contains}
                    onChange={(e) => updateCondition(i, { contains: e.target.value })}
                    placeholder="z. B. newsletter@ oder Rechnung"
                  />
                  <button
                    type="button"
                    onClick={() => removeCondition(i)}
                    disabled={conditions.length === 1}
                    className="shrink-0 rounded-lg p-1.5 text-zinc-400 transition hover:bg-red-50 hover:text-red-600 disabled:opacity-30 dark:hover:bg-red-950/40"
                  >
                    <Trash2 size={13} />
                  </button>
                </div>
              ))}
              <button
                type="button"
                onClick={addCondition}
                className="flex items-center gap-1 text-[11.5px] font-medium text-indigo-600 transition hover:text-indigo-700 dark:text-indigo-400"
              >
                <Plus size={12} /> Bedingung hinzufügen
              </button>
            </div>

            <div className="grid grid-cols-2 gap-2.5">
              <Field label="Aktion">
                <select className={inputClass} value={action} onChange={(e) => setAction(e.target.value as RuleAction)}>
                  {!isPop3 && <option value="move_to">In Ordner verschieben</option>}
                  <option value="mark_read">Als gelesen markieren</option>
                  <option value="flag">Markieren</option>
                  <option value="delete">Löschen</option>
                </select>
                {isPop3 && (
                  <p className="mt-1 text-[10.5px] text-zinc-400">
                    POP3 hat keine Server-Ordner, „Verschieben“ ist daher nicht verfügbar.
                  </p>
                )}
              </Field>
              {action === 'move_to' && (
                <Field label="Zielordner">
                  <select
                    className={inputClass}
                    value={actionValue}
                    onChange={(e) => setActionValue(e.target.value)}
                    disabled={!accountId}
                  >
                    <option value="">{accountId ? 'Ordner wählen…' : 'Erst Konto wählen'}</option>
                    {targetFolders.map((f) => (
                      <option key={f.name} value={f.name}>
                        {f.display_name}
                      </option>
                    ))}
                  </select>
                </Field>
              )}
            </div>
            <button
              type="submit"
              disabled={saving || validConditions.length === 0 || (action === 'move_to' && !actionValue)}
              className="w-full rounded-full bg-gradient-to-b from-indigo-500 to-indigo-600 py-2 text-[13px] font-medium text-white shadow-lg shadow-indigo-600/25 transition hover:from-indigo-400 hover:to-indigo-500 disabled:opacity-60"
            >
              {saving ? 'Speichere…' : 'Regel hinzufügen'}
            </button>
          </form>

          <div>
            <p className="mb-1.5 text-[11px] font-semibold tracking-wide text-zinc-400 uppercase">
              Aktive Regeln
            </p>
            {loading ? (
              <p className="text-xs text-zinc-400">Lade…</p>
            ) : rules.length === 0 ? (
              <p className="text-xs text-zinc-400">Noch keine Regeln angelegt.</p>
            ) : (
              <div className="space-y-1.5">
                {rules.map((r) => (
                  <div
                    key={r.id}
                    className="flex items-center gap-2.5 rounded-xl border border-zinc-200/80 px-3 py-2 dark:border-zinc-800"
                  >
                    <input
                      type="checkbox"
                      checked={r.enabled}
                      onChange={() => handleToggle(r)}
                      className="rounded border-zinc-300"
                    />
                    <div className="min-w-0 flex-1 text-[12.5px] text-zinc-700 dark:text-zinc-300">
                      <span className="font-medium">{conditionsSummary(r.conditions, r.match_type)}</span>
                      {' → '}
                      {actionLabel(r, accountFolders)}
                      {r.account_id && (
                        <span className="text-zinc-400">
                          {' '}
                          ({accounts.find((a) => a.id === r.account_id)?.label ?? '?'})
                        </span>
                      )}
                    </div>
                    <button
                      onClick={() => handleDelete(r)}
                      className="shrink-0 rounded-full p-1 text-zinc-400 transition hover:bg-red-50 hover:text-red-600 dark:hover:bg-red-950/40"
                    >
                      <Trash2 size={13} />
                    </button>
                  </div>
                ))}
              </div>
            )}
          </div>
        </div>
      </div>
    </div>
  )
}
