import { useCallback, useEffect, useState } from 'react'
import { useSearchParams } from 'react-router-dom'

const BASE = '/api/v1'

// Öffentliche Endpunkte: KEIN Bearer-Token, daher nicht der api-Client (der
// hängt Authorization an und triggert Token-Refresh). Schlankes fetch.
async function publicPost<T>(path: string, body: unknown): Promise<T> {
  const res = await fetch(`${BASE}${path}`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(body),
  })
  if (!res.ok) {
    const err = await res.json().catch(() => ({ detail: res.statusText }))
    const e = new Error(typeof err.detail === 'string' ? err.detail : res.statusText)
    ;(e as Error & { status?: number }).status = res.status
    throw e
  }
  return res.json()
}

interface TimeEntry { id: string; start_time: string; end_time: string | null }
interface StampStatus { open: boolean; on_break: boolean; today: TimeEntry[] }
interface AuthResponse extends StampStatus { session_token: string; user_name: string; expires_in_seconds: number }
interface ActionResponse extends StampStatus { warnings: string[] }

function fmtTime(iso: string | null): string {
  if (!iso) return '–'
  return iso.slice(0, 5)
}

export function PublicStampPage() {
  const [params] = useSearchParams()
  const token = params.get('t') ?? ''

  const [companyName, setCompanyName] = useState<string | null>(null)
  const [enabled, setEnabled] = useState(true)
  const [loadingCompany, setLoadingCompany] = useState(true)

  const [personnelNumber, setPersonnelNumber] = useState('')
  const [pin, setPin] = useState('')

  const [sessionToken, setSessionToken] = useState<string | null>(null)
  const [userName, setUserName] = useState('')
  const [status, setStatus] = useState<StampStatus | null>(null)

  const [busy, setBusy] = useState(false)
  const [error, setError] = useState<string | null>(null)
  const [warnings, setWarnings] = useState<string[]>([])
  const [info, setInfo] = useState<string | null>(null)

  useEffect(() => {
    if (!token) { setLoadingCompany(false); return }
    fetch(`${BASE}/time/public/company?t=${encodeURIComponent(token)}`)
      .then(r => r.ok ? r.json() : Promise.reject(new Error('ungültig')))
      .then((c: { company_name: string; enabled: boolean }) => {
        setCompanyName(c.company_name)
        setEnabled(c.enabled)
      })
      .catch(() => setCompanyName(null))
      .finally(() => setLoadingCompany(false))
  }, [token])

  const resetToLogin = useCallback((msg: string) => {
    setSessionToken(null)
    setStatus(null)
    setPin('')
    setInfo(msg)
  }, [])

  async function authenticate(e: React.FormEvent) {
    e.preventDefault()
    setBusy(true); setError(null); setWarnings([]); setInfo(null)
    try {
      const res = await publicPost<AuthResponse>('/time/public/auth', {
        token, personnel_number: personnelNumber, pin,
      })
      setSessionToken(res.session_token)
      setUserName(res.user_name)
      setStatus({ open: res.open, on_break: res.on_break, today: res.today })
    } catch (err: unknown) {
      setError(err instanceof Error ? err.message : 'Anmeldung fehlgeschlagen')
    } finally {
      setBusy(false)
    }
  }

  async function doAction(action: 'in' | 'out' | 'break_start' | 'break_end') {
    if (!sessionToken) return
    setBusy(true); setError(null); setWarnings([])
    try {
      const res = await publicPost<ActionResponse>('/time/public/action', {
        session_token: sessionToken, action,
      })
      setStatus({ open: res.open, on_break: res.on_break, today: res.today })
      if (res.warnings.length) setWarnings(res.warnings)
    } catch (err: unknown) {
      const status = (err as Error & { status?: number }).status
      if (status === 401) {
        resetToLogin('Sitzung abgelaufen. Bitte erneut anmelden.')
      } else {
        setError(err instanceof Error ? err.message : 'Aktion fehlgeschlagen')
      }
    } finally {
      setBusy(false)
    }
  }

  // ── Render-Zustände ─────────────────────────────────────────────────────────

  if (loadingCompany) {
    return (
      <Shell>
        <div className='flex flex-col items-center gap-3 py-10'>
          <div className='animate-spin rounded-full h-9 w-9 border-4 border-blue-500 border-t-transparent' />
          <p className='text-sm text-gray-400'>Wird geladen…</p>
        </div>
      </Shell>
    )
  }

  if (!token || companyName === null) {
    return (
      <Shell>
        <div className='bg-red-50 border border-red-200 rounded-xl px-4 py-5 text-center'>
          <p className='text-3xl mb-2'>🚫</p>
          <p className='font-semibold text-red-700'>QR-Code ungültig</p>
          <p className='text-sm text-red-600 mt-1'>Dieser QR-Code ist nicht (mehr) gültig. Bitte an die Verwaltung wenden.</p>
        </div>
      </Shell>
    )
  }

  if (!enabled) {
    return (
      <Shell company={companyName}>
        <div className='bg-amber-50 border border-amber-200 rounded-xl px-4 py-5 text-center'>
          <p className='text-3xl mb-2'>🔒</p>
          <p className='font-semibold text-amber-800'>QR-Stempeln deaktiviert</p>
          <p className='text-sm text-amber-700 mt-1'>Das mobile Stempeln per QR ist für dieses Unternehmen derzeit nicht aktiviert.</p>
        </div>
      </Shell>
    )
  }

  // Angemeldet → Stempel-Ansicht
  if (sessionToken && status) {
    const isOpen = status.open
    const onBreak = status.on_break
    return (
      <Shell company={companyName}>
        <div className='space-y-4'>
          <p className='text-center text-sm text-gray-500'>Angemeldet als</p>
          <p className='text-center text-xl font-bold text-gray-900 -mt-3'>{userName}</p>

          {warnings.length > 0 && (
            <div className='bg-yellow-50 border border-yellow-200 rounded-xl px-4 py-3'>
              <ul className='text-sm text-yellow-700 list-disc list-inside space-y-0.5'>
                {warnings.map((w, i) => <li key={i}>{w}</li>)}
              </ul>
            </div>
          )}
          {error && <div className='bg-red-50 border border-red-200 rounded-xl px-4 py-3 text-sm text-red-700'>{error}</div>}

          <div className={`inline-flex w-full justify-center items-center gap-2 px-3 py-2 rounded-full text-sm font-semibold ${
            onBreak ? 'bg-yellow-100 text-yellow-700' : isOpen ? 'bg-green-100 text-green-700' : 'bg-gray-100 text-gray-500'
          }`}>
            <span className={`w-2 h-2 rounded-full ${onBreak ? 'bg-yellow-400' : isOpen ? 'bg-green-500' : 'bg-gray-400'}`} />
            {onBreak ? 'In Pause' : isOpen ? 'Eingestempelt' : 'Nicht eingestempelt'}
          </div>

          {!isOpen ? (
            <button onClick={() => doAction('in')} disabled={busy}
              className='w-full min-h-[80px] rounded-3xl bg-green-500 active:bg-green-700 text-white text-2xl font-bold shadow-md disabled:opacity-50'>
              {busy ? '…' : 'EINSTEMPELN'}
            </button>
          ) : onBreak ? (
            <button onClick={() => doAction('break_end')} disabled={busy}
              className='w-full min-h-[80px] rounded-3xl bg-yellow-400 active:bg-yellow-600 text-white text-2xl font-bold shadow-md disabled:opacity-50'>
              {busy ? '…' : 'PAUSE BEENDEN'}
            </button>
          ) : (
            <>
              <button onClick={() => doAction('out')} disabled={busy}
                className='w-full min-h-[80px] rounded-3xl bg-red-500 active:bg-red-700 text-white text-2xl font-bold shadow-md disabled:opacity-50'>
                {busy ? '…' : 'AUSSTEMPELN'}
              </button>
              <button onClick={() => doAction('break_start')} disabled={busy}
                className='w-full min-h-[48px] rounded-xl border border-yellow-300 text-yellow-600 font-semibold active:bg-yellow-50 disabled:opacity-50'>
                ☕ Pause starten
              </button>
            </>
          )}

          {status.today.length > 0 && (
            <div className='bg-white rounded-xl border border-gray-200 px-4 py-3'>
              <p className='text-xs font-semibold text-gray-400 uppercase tracking-widest mb-2'>Heute</p>
              <ul className='text-sm text-gray-700 space-y-1'>
                {status.today.map(e => (
                  <li key={e.id} className='flex justify-between'>
                    <span>{fmtTime(e.start_time)} – {fmtTime(e.end_time)}</span>
                  </li>
                ))}
              </ul>
            </div>
          )}

          <button onClick={() => resetToLogin('')}
            className='w-full text-sm text-gray-400 underline pt-2'>
            Fertig / Abmelden
          </button>
        </div>
      </Shell>
    )
  }

  // PIN-Anmeldung
  return (
    <Shell company={companyName}>
      <form onSubmit={authenticate} className='space-y-4'>
        {info && <div className='bg-blue-50 border border-blue-200 rounded-xl px-4 py-3 text-sm text-blue-700'>{info}</div>}
        {error && <div className='bg-red-50 border border-red-200 rounded-xl px-4 py-3 text-sm text-red-700'>{error}</div>}

        <div>
          <label className='block text-sm font-medium text-gray-700 mb-1'>Personalnummer</label>
          <input
            inputMode='numeric' autoComplete='off' value={personnelNumber}
            onChange={e => setPersonnelNumber(e.target.value.replace(/\D/g, ''))}
            className='w-full text-center text-2xl tracking-widest font-mono border border-gray-300 rounded-xl px-3 py-3 focus:outline-none focus:ring-2 focus:ring-blue-500'
            required
          />
        </div>
        <div>
          <label className='block text-sm font-medium text-gray-700 mb-1'>PIN</label>
          <input
            type='password' inputMode='numeric' autoComplete='off' value={pin}
            onChange={e => setPin(e.target.value.replace(/\D/g, '').slice(0, 6))}
            className='w-full text-center text-2xl tracking-widest font-mono border border-gray-300 rounded-xl px-3 py-3 focus:outline-none focus:ring-2 focus:ring-blue-500'
            required
          />
          <p className='mt-1 text-xs text-gray-400'>PIN im Mitarbeiter-Portal unter „Mein Profil“ setzen/ändern.</p>
        </div>
        <button type='submit' disabled={busy || !personnelNumber || pin.length < 4}
          className='w-full min-h-[56px] rounded-2xl bg-blue-600 active:bg-blue-800 text-white text-lg font-bold shadow-md disabled:opacity-50'>
          {busy ? 'Anmelden…' : 'Anmelden'}
        </button>
      </form>
    </Shell>
  )
}

function Shell({ company, children }: { company?: string; children: React.ReactNode }) {
  return (
    <div className='min-h-screen bg-gray-50 flex flex-col items-center px-4 py-8'>
      <div className='w-full max-w-sm'>
        <div className='text-center mb-6'>
          <p className='text-xs font-semibold text-blue-600 uppercase tracking-widest'>Zeiterfassung</p>
          <h1 className='text-2xl font-bold text-gray-900 mt-1'>{company ?? 'Stempeln'}</h1>
        </div>
        {children}
      </div>
    </div>
  )
}
