import { useEffect, useState } from 'react'
import { api } from '../api/client'
import { Spinner } from '../components/Spinner'
import { Layout } from '../components/Layout'

interface UserOut {
  id: string; first_name: string; last_name: string; email: string; role: string; company_id: string
}

interface CaldavConfigOut {
  id: string
  enabled: boolean
  principal_url: string
  calendar_url: string | null
  username: string
  calendar_display_name: string
  verify_ssl: boolean
  name_template?: string
  last_error: string | null
  updated_at: string
}

const EMPTY = {
  enabled: false,
  principal_url: '',
  calendar_url: '',
  username: '',
  password: '',
  calendar_display_name: '',
  verify_ssl: true,
  name_template: 'full',
}

const PLACEHOLDER_DOCS = [
  { ph: '$vorname',         desc: 'Vollständiger Vorname',          example: 'Patrick' },
  { ph: '$nachname',        desc: 'Vollständiger Nachname',         example: 'Perlbach' },
  { ph: '$vorname_short',   desc: 'Erster Buchstabe des Vornamens', example: 'P' },
  { ph: '$nachname_middle', desc: 'Erste 3 Buchstaben des Nachnamens', example: 'Per' },
  { ph: '$kuerzel',         desc: 'Manuell gesetztes Kürzel (Fallback: Initialen)', example: 'PP' },
  { ph: '$typ',             desc: 'Abwesenheitsart',                example: 'Urlaub' },
]

const TEMPLATE_PRESETS = [
  { label: 'Vollständiger Name', value: '$vorname $nachname – $typ' },
  { label: 'Vorname abgekürzt',  value: '$vorname_short. $nachname – $typ' },
  { label: 'Kürzel',             value: '$kuerzel – $typ' },
  { label: 'Nur Art',            value: '$typ' },
]

function renderPreview(template: string): string {
  return template
    .replace('$vorname_short',   'P')
    .replace('$nachname_middle', 'Per')
    .replace('$vorname',         'Patrick')
    .replace('$nachname',        'Perlbach')
    .replace('$kuerzel',         'PP')
    .replace('$typ',             'Urlaub')
}

const ADMIN_ROLES = ['COMPANY_ADMIN', 'SUPER_ADMIN']

function ConfigForm({
  title,
  hint,
  config,
  onSave,
  onTest,
  onResync,
  showResync,
  showNameFormat,
}: {
  title: string
  hint: string
  config: CaldavConfigOut | null
  onSave: (data: typeof EMPTY) => Promise<void>
  onTest: () => Promise<void>
  onResync?: () => Promise<void>
  showResync?: boolean
  showNameFormat?: boolean
}) {
  const [form, setForm] = useState(EMPTY)
  const [saving, setSaving] = useState(false)
  const [testing, setTesting] = useState(false)
  const [resyncing, setResyncing] = useState(false)
  const [error, setError] = useState('')
  const [success, setSuccess] = useState('')

  useEffect(() => {
    if (config) {
      setForm({
        enabled: config.enabled,
        principal_url: config.principal_url,
        calendar_url: config.calendar_url ?? '',
        username: config.username,
        password: '',
        calendar_display_name: config.calendar_display_name,
        verify_ssl: config.verify_ssl,
        name_template: config.name_template ?? 'full',
      })
    }
  }, [config])

  const save = async () => {
    setSaving(true); setError(''); setSuccess('')
    try {
      await onSave({ ...form, calendar_url: form.calendar_url || null, password: form.password || null } as typeof EMPTY)
      setForm(f => ({ ...f, password: '' }))
      setSuccess('Gespeichert.')
    } catch (e: unknown) { setError(e instanceof Error ? e.message : 'Fehler') }
    finally { setSaving(false) }
  }

  const test = async () => {
    setTesting(true); setError(''); setSuccess('')
    try { await onTest(); setSuccess('Verbindung erfolgreich!') }
    catch (e: unknown) { setError(e instanceof Error ? e.message : 'Verbindungsfehler') }
    finally { setTesting(false) }
  }

  const resync = async () => {
    if (!onResync) return
    setResyncing(true); setError(''); setSuccess('')
    try { await onResync(); setSuccess('Neu synchronisiert.') }
    catch (e: unknown) { setError(e instanceof Error ? e.message : 'Fehler') }
    finally { setResyncing(false) }
  }

  const inp = 'w-full border border-gray-300 rounded-lg px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500'

  return (
    <div className='bg-white rounded-xl shadow-sm border border-gray-200 p-6 space-y-5'>
      <div>
        <h2 className='text-base font-semibold text-gray-800'>{title}</h2>
        <p className='text-xs text-gray-400 mt-0.5'>{hint}</p>
      </div>

      {error   && <div className='bg-red-50 border border-red-200 rounded-lg p-3 text-sm text-red-700'>{error}</div>}
      {success && <div className='bg-green-50 border border-green-200 rounded-lg p-3 text-sm text-green-700'>{success}</div>}

      {config?.last_error && (
        <div className='bg-yellow-50 border border-yellow-200 rounded-lg p-3 text-xs text-yellow-700'>
          Letzter Sync-Fehler: {config.last_error}
        </div>
      )}

      <label className='flex items-center gap-2 text-sm text-gray-700 cursor-pointer'>
        <input type='checkbox' checked={form.enabled} onChange={e => setForm(f => ({ ...f, enabled: e.target.checked }))} className='rounded' />
        CalDAV-Sync aktiviert
      </label>

      <div className='grid grid-cols-2 gap-3'>
        <div className='col-span-2'>
          <label className='block text-sm font-medium text-gray-700 mb-1'>Server-URL (Principal oder Kalender-URL) *</label>
          <input type='url' value={form.principal_url} onChange={e => setForm(f => ({ ...f, principal_url: e.target.value }))}
            placeholder='https://cloud.example.de/remote.php/dav/calendars/user/abwesenheiten/' className={inp} />
          <p className='text-xs text-gray-400 mt-1'>Nextcloud: Einstellungen → Kalender → Kalender-Link (WebDAV)</p>
        </div>
        <div>
          <label className='block text-sm font-medium text-gray-700 mb-1'>Benutzername *</label>
          <input type='text' value={form.username} onChange={e => setForm(f => ({ ...f, username: e.target.value }))} className={inp} />
        </div>
        <div>
          <label className='block text-sm font-medium text-gray-700 mb-1'>
            Passwort {config ? '(leer = unverändert)' : '*'}
          </label>
          <input type='password' value={form.password} onChange={e => setForm(f => ({ ...f, password: e.target.value }))}
            placeholder='••••••••' className={inp} autoComplete='new-password' />
        </div>
        <div>
          <label className='block text-sm font-medium text-gray-700 mb-1'>Kalender-Name (optional)</label>
          <input type='text' value={form.calendar_display_name} onChange={e => setForm(f => ({ ...f, calendar_display_name: e.target.value }))}
            placeholder='Abwesenheiten' className={inp} />
        </div>
        <div className='flex items-end pb-2'>
          <label className='flex items-center gap-2 text-sm text-gray-700 cursor-pointer'>
            <input type='checkbox' checked={form.verify_ssl} onChange={e => setForm(f => ({ ...f, verify_ssl: e.target.checked }))} className='rounded' />
            SSL-Zertifikat prüfen
          </label>
        </div>
      </div>

      {showNameFormat && (
        <div className='space-y-3'>
          <div>
            <label className='block text-sm font-medium text-gray-700'>
              Anzeige-Name im Firmenkalender
            </label>
            <p className='text-xs text-gray-400 mt-0.5'>
              Erstelle ein eigenes Template mit Platzhaltern. Im persönlichen Kalender steht immer nur die Abwesenheitsart.
            </p>
          </div>

          {/* Schnellauswahl */}
          <div className='flex flex-wrap gap-2'>
            {TEMPLATE_PRESETS.map(p => (
              <button
                key={p.value}
                type='button'
                onClick={() => setForm(f => ({ ...f, name_template: p.value }))}
                className={`text-xs px-3 py-1.5 rounded-lg border transition-colors ${
                  form.name_template === p.value
                    ? 'border-blue-400 bg-blue-50 text-blue-700 font-medium'
                    : 'border-gray-200 text-gray-600 hover:border-gray-300 hover:bg-gray-50'
                }`}
              >
                {p.label}
              </button>
            ))}
          </div>

          {/* Template-Eingabe */}
          <div>
            <input
              type='text'
              value={form.name_template}
              onChange={e => setForm(f => ({ ...f, name_template: e.target.value }))}
              placeholder='$vorname $nachname – $typ'
              className={inp}
            />
            {/* Live-Vorschau */}
            <div className='mt-1.5 flex items-center gap-2'>
              <span className='text-xs text-gray-400'>Vorschau:</span>
              <span className='text-xs font-medium text-gray-700 bg-gray-100 px-2 py-0.5 rounded font-mono'>
                {renderPreview(form.name_template || '$vorname $nachname – $typ')}
              </span>
            </div>
          </div>

          {/* Platzhalter-Referenz */}
          <div className='rounded-lg border border-gray-100 bg-gray-50 p-3'>
            <p className='text-xs font-medium text-gray-600 mb-2'>Verfügbare Platzhalter:</p>
            <div className='grid grid-cols-1 gap-1'>
              {PLACEHOLDER_DOCS.map(p => (
                <div key={p.ph} className='flex items-baseline gap-2 text-xs'>
                  <button
                    type='button'
                    onClick={() => setForm(f => ({ ...f, name_template: f.name_template + p.ph }))}
                    className='font-mono text-blue-700 bg-blue-50 px-1.5 py-0.5 rounded hover:bg-blue-100 transition-colors shrink-0'
                    title='Klicken zum Einfügen'
                  >
                    {p.ph}
                  </button>
                  <span className='text-gray-500'>{p.desc}</span>
                  <span className='text-gray-400'>→ {p.example}</span>
                </div>
              ))}
            </div>
          </div>
        </div>
      )}

      <div className='flex flex-wrap gap-2 pt-1'>
        <button onClick={save} disabled={saving || !form.principal_url || !form.username}
          className='px-5 py-2 bg-blue-600 text-white rounded-lg text-sm font-medium hover:bg-blue-700 disabled:opacity-50'>
          {saving ? 'Speichern…' : 'Speichern'}
        </button>
        {config && (
          <button onClick={test} disabled={testing}
            className='px-4 py-2 border border-gray-300 text-gray-700 rounded-lg text-sm hover:bg-gray-50 disabled:opacity-50'>
            {testing ? 'Teste…' : 'Verbindung testen'}
          </button>
        )}
        {showResync && config && onResync && (
          <button onClick={resync} disabled={resyncing}
            className='px-4 py-2 border border-blue-300 text-blue-700 rounded-lg text-sm hover:bg-blue-50 disabled:opacity-50'>
            {resyncing ? 'Sync läuft…' : 'Alle Abwesenheiten neu synchronisieren'}
          </button>
        )}
      </div>
    </div>
  )
}

export function CaldavSettingsPage() {
  const [user, setUser] = useState<UserOut | null>(null)
  const [companyCfg, setCompanyCfg] = useState<CaldavConfigOut | null>(null)
  const [userCfg, setUserCfg] = useState<CaldavConfigOut | null>(null)
  const [loading, setLoading] = useState(true)

  const isAdmin = user ? ADMIN_ROLES.includes(user.role) : false

  useEffect(() => {
    async function load() {
      try {
        const me = await api.get<UserOut>('/auth/me')
        setUser(me)
        const [cc, uc] = await Promise.all([
          ADMIN_ROLES.includes(me.role)
            ? api.get<CaldavConfigOut | null>('/caldav/company/config').catch(() => null)
            : Promise.resolve(null),
          api.get<CaldavConfigOut | null>('/caldav/user/config').catch(() => null),
        ])
        setCompanyCfg(cc)
        setUserCfg(uc)
      } catch { /* ignore */ }
      finally { setLoading(false) }
    }
    load()
  }, [])

  const saveCompany = async (data: typeof EMPTY) => {
    const saved = await api.post<CaldavConfigOut>('/caldav/company/config', data)
    setCompanyCfg(saved)
  }
  const testCompany = async () => { await api.post('/caldav/company/test', {}) }
  const resyncCompany = async () => { await api.post('/caldav/company/resync', {}) }

  const saveUser = async (data: typeof EMPTY) => {
    const saved = await api.post<CaldavConfigOut>('/caldav/user/config', data)
    setUserCfg(saved)
  }
  const testUser = async () => { await api.post('/caldav/user/test', {}) }

  if (loading) return <Layout userRole='' userName=''><div className='flex justify-center py-20'><Spinner /></div></Layout>
  if (!user) return null

  return (
    <Layout userRole={user.role} userName={`${user.first_name} ${user.last_name}`}>
      <div className='max-w-2xl space-y-6'>
        <div>
          <h1 className='text-2xl font-bold text-gray-900'>CalDAV-Integration</h1>
          <p className='text-sm text-gray-500 mt-1'>
            Genehmigte Abwesenheiten werden automatisch in Kalender-Apps eingetragen.
            Kompatibel mit Nextcloud, Thunderbird, Apple Kalender, Google Calendar und allen CalDAV-Clients.
          </p>
        </div>

        {/* Hinweis: kein eigener Server nötig */}
        <div className='bg-blue-50 border border-blue-100 rounded-xl p-4 text-sm text-blue-800'>
          <p className='font-semibold mb-1'>Kein eigener CalDAV-Server nötig</p>
          <p>Trage einfach die URL eines bestehenden Kalenders ein – z. B. aus Nextcloud, iCloud oder Google Calendar:</p>
          <ul className='mt-2 space-y-1 text-xs list-disc list-inside text-blue-700'>
            <li><strong>Nextcloud:</strong> Kalender-App → ··· → Link kopieren (WebDAV-URL)</li>
            <li><strong>Apple iCloud:</strong> calendar.icloud.com → Kalender freigeben → privater Link</li>
            <li><strong>Google:</strong> calendar.google.com → Einstellungen → Kalender-Adresse (ICS-Export-URL, Read-only)</li>
            <li><strong>Eigener Radicale/Baikal-Server:</strong> direkte CalDAV-URL verwenden</li>
          </ul>
        </div>

        {isAdmin && (
          <ConfigForm
            title='Firmenkalender (zentral)'
            hint='Alle genehmigten Abwesenheiten aller Mitarbeiter landen in diesem Kalender. Nur Admins können ihn konfigurieren.'
            config={companyCfg}
            onSave={saveCompany}
            onTest={testCompany}
            onResync={resyncCompany}
            showResync
            showNameFormat
          />
        )}

        <ConfigForm
          title='Mein persönlicher Kalender'
          hint='Nur deine eigenen Abwesenheiten. Jeder Mitarbeiter kann seinen eigenen Kalender hinterlegen.'
          config={userCfg}
          onSave={saveUser}
          onTest={testUser}
        />
      </div>
    </Layout>
  )
}
