import { useEffect, useState } from 'react'
import { Globe, Plus, RefreshCw, Trash2, X } from 'lucide-react'
import clsx from 'clsx'
import { api } from '../lib/api'
import type { CaldavAccount, NewCaldavAccount } from '../types'

const inputClass =
  'w-full 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>
  )
}

export function CaldavModal({
  open,
  onClose,
  onToast,
  onSynced,
}: {
  open: boolean
  onClose: () => void
  onToast: (msg: string) => void
  onSynced: () => void
}) {
  const [accounts, setAccounts] = useState<CaldavAccount[]>([])
  const [loading, setLoading] = useState(false)
  const [syncing, setSyncing] = useState<string | null>(null)
  const [showForm, setShowForm] = useState(false)
  const [label, setLabel] = useState('')
  const [url, setUrl] = useState('')
  const [username, setUsername] = useState('')
  const [password, setPassword] = useState('')
  const [saving, setSaving] = useState(false)
  const [error, setError] = useState<string | null>(null)

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

  useEffect(() => {
    if (open) {
      refresh()
      setShowForm(false)
      setLabel('')
      setUrl('')
      setUsername('')
      setPassword('')
      setError(null)
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [open])

  if (!open) return null

  async function handleAdd(e: React.FormEvent) {
    e.preventDefault()
    setError(null)
    setSaving(true)
    try {
      const newAccount: NewCaldavAccount = { label: label.trim() || url.trim(), url: url.trim(), username: username.trim(), password }
      const created = await api.addCaldavAccount(newAccount)
      setShowForm(false)
      refresh()
      onToast('Kalender verbunden — synchronisiere…')
      await handleSync(created.id)
    } catch (err) {
      setError(String(err))
    } finally {
      setSaving(false)
    }
  }

  async function handleSync(id: string) {
    setSyncing(id)
    try {
      const count = await api.syncCaldavCalendar(id)
      onToast(`${count} Termine synchronisiert`)
      onSynced()
    } catch (e) {
      onToast(`Synchronisierung fehlgeschlagen: ${e}`)
    } finally {
      setSyncing(null)
    }
  }

  async function handleDelete(a: CaldavAccount) {
    if (!window.confirm(`Kalender „${a.label}“ trennen? Lokal zwischengespeicherte Termine werden entfernt.`)) return
    setAccounts((prev) => prev.filter((x) => x.id !== a.id))
    try {
      await api.deleteCaldavAccount(a.id)
      onSynced()
    } catch (e) {
      onToast(String(e))
    }
  }

  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-md 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="flex items-center gap-2 text-[15px] font-semibold tracking-tight text-zinc-800 dark:text-zinc-100">
            <Globe size={16} className="text-zinc-400" /> CalDAV-Kalender
          </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">
          <p className="text-[11.5px] text-zinc-400">
            Für Nextcloud, iCloud, Radicale & Co. — trag die direkte Kalender-Adresse ein (kein automatisches Erkennen
            der Kalenderliste). Bei iCloud/Nextcloud brauchst du meist ein App-Passwort statt deines normalen Passworts.
          </p>

          {showForm ? (
            <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">
              <Field label="Name">
                <input className={inputClass} value={label} onChange={(e) => setLabel(e.target.value)} placeholder="z. B. Privat" />
              </Field>
              <Field label="Kalender-URL">
                <input
                  className={inputClass}
                  value={url}
                  onChange={(e) => setUrl(e.target.value)}
                  placeholder="https://cloud.example.com/remote.php/dav/calendars/user/personal/"
                  required
                />
              </Field>
              <Field label="Benutzername">
                <input className={inputClass} value={username} onChange={(e) => setUsername(e.target.value)} required />
              </Field>
              <Field label="Passwort / App-Passwort">
                <input className={inputClass} type="password" value={password} onChange={(e) => setPassword(e.target.value)} required />
              </Field>
              {error && (
                <p className="rounded-lg bg-red-50 px-3 py-2 text-[11.5px] text-red-600 dark:bg-red-950/40 dark:text-red-400">
                  {error}
                </p>
              )}
              <div className="flex gap-2">
                <button
                  type="submit"
                  disabled={saving || !url.trim() || !username.trim() || !password}
                  className="rounded-full bg-gradient-to-b from-indigo-500 to-indigo-600 px-4 py-1.5 text-[12.5px] font-medium text-white shadow-lg shadow-indigo-600/25 transition hover:from-indigo-400 hover:to-indigo-500 disabled:opacity-60"
                >
                  {saving ? 'Verbinde…' : 'Verbinden'}
                </button>
                <button
                  type="button"
                  onClick={() => setShowForm(false)}
                  className="rounded-full px-4 py-1.5 text-[12.5px] font-medium text-zinc-500 transition hover:bg-zinc-100 dark:hover:bg-zinc-800"
                >
                  Abbrechen
                </button>
              </div>
            </form>
          ) : (
            <button
              type="button"
              onClick={() => setShowForm(true)}
              className="flex w-full items-center justify-center gap-1.5 rounded-2xl border border-dashed border-zinc-300 py-2.5 text-[12.5px] font-medium text-zinc-500 transition hover:border-indigo-300 hover:text-indigo-600 dark:border-zinc-700 dark:text-zinc-400 dark:hover:border-indigo-800"
            >
              <Plus size={14} /> Kalender verbinden
            </button>
          )}

          <div>
            {loading ? (
              <p className="text-xs text-zinc-400">Lade…</p>
            ) : accounts.length === 0 ? (
              <p className="text-xs text-zinc-400">Noch kein CalDAV-Kalender verbunden.</p>
            ) : (
              <div className="space-y-1.5">
                {accounts.map((a) => (
                  <div
                    key={a.id}
                    className="flex items-center gap-2.5 rounded-xl border border-zinc-200/80 px-3 py-2 dark:border-zinc-800"
                  >
                    <div className="min-w-0 flex-1">
                      <p className="truncate text-[12.5px] font-medium text-zinc-700 dark:text-zinc-300">{a.label}</p>
                      <p className="truncate text-[11px] text-zinc-400">{a.url}</p>
                    </div>
                    <button
                      onClick={() => handleSync(a.id)}
                      disabled={syncing === a.id}
                      title="Jetzt synchronisieren"
                      className="shrink-0 rounded-full p-1.5 text-zinc-400 transition hover:bg-zinc-100 hover:text-zinc-600 disabled:opacity-40 dark:hover:bg-zinc-800 dark:hover:text-zinc-300"
                    >
                      <RefreshCw size={13} className={clsx(syncing === a.id && 'animate-spin')} />
                    </button>
                    <button
                      onClick={() => handleDelete(a)}
                      className="shrink-0 rounded-full p-1.5 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>
  )
}
