'use client'

import { CheckboxInput, useDocumentInfo } from '@payloadcms/ui'
import { useCallback, useEffect, useState } from 'react'

type Occurrence = {
  id: string
  date: string
  cancelled: boolean
}

const LIMIT = 10

const formatDate = (iso: string): string =>
  new Date(iso).toLocaleString('de-DE', {
    weekday: 'short',
    day: '2-digit',
    month: '2-digit',
    year: 'numeric',
    hour: '2-digit',
    minute: '2-digit',
  })

export const NextOccurrencesTable = () => {
  const { id } = useDocumentInfo()
  const [occurrences, setOccurrences] = useState<Occurrence[]>([])
  const [loading, setLoading] = useState(false)
  const [pendingIds, setPendingIds] = useState<Set<string>>(new Set())
  const [errorIds, setErrorIds] = useState<Set<string>>(new Set())
  const [fetchError, setFetchError] = useState<string | null>(null)

  useEffect(() => {
    if (!id) return
    let cancelled = false
    setLoading(true)
    setFetchError(null)

    const params = new URLSearchParams({
      'where[event][equals]': String(id),
      'where[date][greater_than_equal]': new Date().toISOString(),
      sort: 'date',
      limit: String(LIMIT),
      depth: '0',
    })

    fetch(`/api/eventOccurrence?${params.toString()}`, { credentials: 'include' })
      .then(async (res) => {
        if (!res.ok) throw new Error(`HTTP ${res.status}`)
        return res.json()
      })
      .then((json: { docs: Occurrence[] }) => {
        if (cancelled) return
        setOccurrences(json.docs)
      })
      .catch((err: Error) => {
        if (cancelled) return
        setFetchError(err.message)
      })
      .finally(() => {
        if (!cancelled) setLoading(false)
      })

    return () => {
      cancelled = true
    }
  }, [id])

  const toggle = useCallback(async (occ: Occurrence) => {
    const next = !occ.cancelled
    setOccurrences((prev) =>
      prev.map((o) => (o.id === occ.id ? { ...o, cancelled: next } : o)),
    )
    setPendingIds((prev) => new Set(prev).add(occ.id))
    setErrorIds((prev) => {
      const s = new Set(prev)
      s.delete(occ.id)
      return s
    })

    try {
      const res = await fetch(`/api/eventOccurrence/${occ.id}`, {
        method: 'PATCH',
        credentials: 'include',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ cancelled: next }),
      })
      if (!res.ok) throw new Error(`HTTP ${res.status}`)
    } catch {
      setOccurrences((prev) =>
        prev.map((o) => (o.id === occ.id ? { ...o, cancelled: occ.cancelled } : o)),
      )
      setErrorIds((prev) => new Set(prev).add(occ.id))
    } finally {
      setPendingIds((prev) => {
        const s = new Set(prev)
        s.delete(occ.id)
        return s
      })
    }
  }, [])

  if (!id) {
    return (
      <div className="field-description">
        Veranstaltung erst speichern, um Termine zu verwalten.
      </div>
    )
  }

  if (loading) {
    return <div className="field-description">Wird geladen…</div>
  }

  if (fetchError) {
    return (
      <div className="field-description" style={{ color: 'var(--theme-error-500)' }}>
        Fehler beim Laden: {fetchError}
      </div>
    )
  }

  if (occurrences.length === 0) {
    return (
      <div className="field-description">
        Keine zukünftigen Termine vorhanden.
      </div>
    )
  }

  return (
    <div className="table">
      <table>
        <thead>
          <tr>
            <th>Datum</th>
            <th>Abgesagt</th>
          </tr>
        </thead>
        <tbody>
          {occurrences.map((occ) => (
            <tr key={occ.id}>
              <td>{formatDate(occ.date)}</td>
              <td>
                <CheckboxInput
                  checked={occ.cancelled}
                  onToggle={() => toggle(occ)}
                  readOnly={pendingIds.has(occ.id)}
                />
                {errorIds.has(occ.id) && (
                  <div
                    className="field-description"
                    style={{ color: 'var(--theme-error-500)' }}
                  >
                    Speichern fehlgeschlagen.
                  </div>
                )}
              </td>
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  )
}

export default NextOccurrencesTable
