'use client'

import { useState, useEffect, useCallback, ReactNode } from 'react'
import { useTheme } from '@/lib/ThemeContext'

/**
 * Shared scaffolding for all 15 constraint editors.
 *
 * Each editor follows the same shape: list-load on mount, optional form to
 * create a new entry, a table to render existing entries, delete with a
 * confirm. Extracted here so individual editors only carry their schema-
 * specific bits (form fields, table columns).
 */

export interface ConstraintApi<TItem, TForm> {
  list(): Promise<TItem[]>
  create(form: TForm): Promise<TItem>
  remove(id: string): Promise<void>
}

export interface CrudState<TItem, TForm> {
  items: TItem[]
  loading: boolean
  error: string | null
  showForm: boolean
  submitting: boolean
  form: TForm
  setForm: (f: TForm | ((prev: TForm) => TForm)) => void
  toggleForm: () => void
  reload: () => Promise<void>
  submit: (e?: React.FormEvent) => Promise<void>
  remove: (id: string, confirmMsg?: string) => Promise<void>
  setError: (msg: string | null) => void
}

export function useConstraintCrud<TItem extends { id: string }, TForm>(
  api: ConstraintApi<TItem, TForm>,
  initialForm: TForm,
  opts: { onBeforeSubmit?: (form: TForm) => string | null } = {},
): CrudState<TItem, TForm> {
  const [items, setItems] = useState<TItem[]>([])
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState<string | null>(null)
  const [showForm, setShowForm] = useState(false)
  const [submitting, setSubmitting] = useState(false)
  const [form, setForm] = useState<TForm>(initialForm)

  const reload = useCallback(async () => {
    setLoading(true)
    setError(null)
    try {
      const data = await api.list()
      setItems(data || [])
    } catch (e) {
      setError(e instanceof Error ? e.message : 'Laden fehlgeschlagen')
    } finally {
      setLoading(false)
    }
  }, [api])

  useEffect(() => { reload() }, [reload])

  const submit = useCallback(async (e?: React.FormEvent) => {
    if (e) e.preventDefault()
    if (opts.onBeforeSubmit) {
      const err = opts.onBeforeSubmit(form)
      if (err) {
        setError(err)
        return
      }
    }
    setSubmitting(true)
    setError(null)
    try {
      await api.create(form)
      setForm(initialForm)
      setShowForm(false)
      await reload()
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Anlegen fehlgeschlagen')
    } finally {
      setSubmitting(false)
    }
  }, [api, form, initialForm, opts, reload])

  const remove = useCallback(async (id: string, confirmMsg = 'Regel wirklich loeschen?') => {
    if (!confirm(confirmMsg)) return
    try {
      await api.remove(id)
      await reload()
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Loeschen fehlgeschlagen')
    }
  }, [api, reload])

  return {
    items, loading, error, showForm, submitting, form, setForm,
    toggleForm: () => setShowForm(s => !s),
    reload, submit, remove, setError,
  }
}

interface ShellProps {
  testId: string
  title: string
  description: string
  newLabel: string
  newDisabled?: boolean
  prereqWarning?: string | null
  emptyText: string
  loadingText?: string
  tableHeaders: string[]
  showFormButtonLabel?: string
  cancelLabel?: string
  state: {
    loading: boolean
    error: string | null
    showForm: boolean
    submitting: boolean
    items: { id: string }[]
    toggleForm: () => void
    submit: (e?: React.FormEvent) => void | Promise<void>
  }
  formBody: ReactNode
  renderRow: (item: unknown, idx: number) => ReactNode
}

export function ConstraintShell({
  testId, title, description, newLabel, newDisabled = false,
  prereqWarning, emptyText, loadingText = 'Laedt…', tableHeaders,
  cancelLabel = 'Abbrechen',
  state, formBody, renderRow,
}: ShellProps) {
  const { isDark } = useTheme()
  const cardClass = isDark ? 'bg-white/10 border-white/20 text-white' : 'bg-white/80 border-black/10 text-slate-900'

  return (
    <div className="space-y-4" data-testid={testId}>
      <div className="flex items-center justify-between">
        <div>
          <h3 className={`text-lg font-semibold ${isDark ? 'text-white' : 'text-slate-900'}`}>{title}</h3>
          <p className={`text-sm ${isDark ? 'text-white/60' : 'text-slate-500'}`}>{description}</p>
        </div>
        <button
          onClick={state.toggleForm}
          disabled={newDisabled}
          className={`px-4 py-2 rounded-xl font-medium transition-colors disabled:opacity-50 ${isDark ? 'bg-indigo-500 hover:bg-indigo-600 text-white' : 'bg-indigo-600 hover:bg-indigo-700 text-white'}`}
        >
          {state.showForm ? cancelLabel : newLabel}
        </button>
      </div>

      {prereqWarning && !state.loading && (
        <div className={`p-3 rounded-xl text-sm ${isDark ? 'bg-amber-500/10 border border-amber-500/30 text-amber-200' : 'bg-amber-50 border border-amber-200 text-amber-900'}`}>
          {prereqWarning}
        </div>
      )}

      {state.error && <div className="p-3 rounded-xl bg-red-500/20 border border-red-500/40 text-red-300">{state.error}</div>}

      {state.showForm && (
        <form onSubmit={state.submit} className={`p-4 rounded-2xl border backdrop-blur-xl ${cardClass}`}>
          {formBody}
        </form>
      )}

      {state.loading ? (
        <div className={`text-center py-8 opacity-60 ${isDark ? 'text-white' : 'text-slate-700'}`}>{loadingText}</div>
      ) : state.items.length === 0 ? (
        <div className={`text-center py-8 opacity-60 ${isDark ? 'text-white' : 'text-slate-700'}`}>{emptyText}</div>
      ) : (
        <div className={`rounded-2xl border backdrop-blur-xl overflow-hidden ${cardClass}`}>
          <table className="w-full">
            <thead className={isDark ? 'bg-white/5' : 'bg-slate-100'}>
              <tr>
                {tableHeaders.map((h, i) => <th key={i} className="text-left px-4 py-3 text-sm font-medium opacity-70">{h}</th>)}
                <th className="px-4 py-3"></th>
              </tr>
            </thead>
            <tbody>
              {state.items.map((item, idx) => renderRow(item, idx))}
            </tbody>
          </table>
        </div>
      )}
    </div>
  )
}

// ---------- Shared style helpers ----------

export function useShellStyles() {
  const { isDark } = useTheme()
  return {
    isDark,
    cardClass: isDark ? 'bg-white/10 border-white/20 text-white' : 'bg-white/80 border-black/10 text-slate-900',
    inputClass: isDark ? 'bg-white/10 border-white/20 text-white' : 'bg-white border-slate-300 text-slate-900',
    rowClass: isDark ? 'border-t border-white/10' : 'border-t border-slate-200',
    deleteBtn: 'text-red-400 hover:text-red-300 text-sm',
    submitBtn: 'w-full px-4 py-2 rounded-lg bg-emerald-500 hover:bg-emerald-600 text-white font-medium disabled:opacity-50',
  }
}

// ---------- Day-of-week constants reused across editors ----------

export const DAYS = [
  { v: 1, label: 'Montag', short: 'Mo' },
  { v: 2, label: 'Dienstag', short: 'Di' },
  { v: 3, label: 'Mittwoch', short: 'Mi' },
  { v: 4, label: 'Donnerstag', short: 'Do' },
  { v: 5, label: 'Freitag', short: 'Fr' },
  { v: 6, label: 'Samstag', short: 'Sa' },
  { v: 7, label: 'Sonntag', short: 'So' },
]

export function dayLabel(v: number): string {
  return DAYS.find(d => d.v === v)?.label || String(v)
}
