'use client'

import { useState, useEffect, useCallback } from 'react'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Plus, Trash2, Check, Loader2 } from 'lucide-react'
import type { CockpitModule, ModuleColumn } from '@/lib/modules'

interface ModuleItemRow {
  id: string
  data: Record<string, any>
  createdAt: string
}

interface TableModuleProps {
  projectId: string
  module: CockpitModule
  canEdit: boolean
  /** Live-Sync: andere Clients über Änderung informieren */
  notifyChanged: () => void
}

function formatTime(dateStr: string) {
  return new Date(dateStr).toLocaleTimeString('de-CH', { hour: '2-digit', minute: '2-digit' })
}

/**
 * Generisches Tabellen-Modul des Modul-Baukastens.
 * Rendert beliebige Spalten (text / check / time) gemäss Modul-Konfiguration.
 * Daten liegen als JSON-Zeilen in module_items (generische API).
 */
export function TableModule({ projectId, module, canEdit, notifyChanged }: TableModuleProps) {
  const [items, setItems] = useState<ModuleItemRow[]>([])
  const [isLoading, setIsLoading] = useState(true)
  const [draft, setDraft] = useState<Record<string, string>>({})

  const columns: ModuleColumn[] = module.columns || []
  const textColumns = columns.filter(c => c.type === 'text')

  const load = useCallback(async () => {
    try {
      const res = await fetch(`/api/projects/${projectId}/modules/${module.id}/items`)
      if (res.ok) {
        const data = await res.json()
        setItems(data.items || [])
      }
    } catch (err) {
      console.error(`Failed to load module ${module.id}:`, err)
    } finally {
      setIsLoading(false)
    }
  }, [projectId, module.id])

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

  // Live-Refresh, wenn andere Clients Journal-Änderungen melden
  useEffect(() => {
    const onRefresh = () => load()
    window.addEventListener('journal-refresh', onRefresh)
    return () => window.removeEventListener('journal-refresh', onRefresh)
  }, [load])

  const addRow = useCallback(async () => {
    const hasContent = textColumns.some(c => (draft[c.key] || '').trim())
    if (!hasContent) return
    const data: Record<string, any> = {}
    for (const c of textColumns) {
      const v = (draft[c.key] || '').trim()
      if (v) data[c.key] = v
    }
    try {
      const res = await fetch(`/api/projects/${projectId}/modules/${module.id}/items`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ data }),
      })
      if (res.ok) {
        const item = await res.json()
        setItems(prev => [...prev, item])
        setDraft({})
        notifyChanged()
      }
    } catch (err) {
      console.error('Failed to add module item:', err)
    }
  }, [projectId, module.id, draft, textColumns, notifyChanged])

  const toggleCheck = useCallback(async (item: ModuleItemRow, key: string) => {
    if (!canEdit) return
    const next = !item.data[key]
    try {
      const res = await fetch(`/api/projects/${projectId}/modules/${module.id}/items/${item.id}`, {
        method: 'PUT',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ data: { [key]: next, [`${key}At`]: next ? new Date().toISOString() : null } }),
      })
      if (res.ok) {
        const updated = await res.json()
        setItems(prev => prev.map(i => i.id === updated.id ? updated : i))
        notifyChanged()
      }
    } catch (err) {
      console.error('Failed to toggle module item:', err)
    }
  }, [projectId, module.id, canEdit, notifyChanged])

  const deleteRow = useCallback(async (itemId: string) => {
    try {
      await fetch(`/api/projects/${projectId}/modules/${module.id}/items/${itemId}`, { method: 'DELETE' })
      setItems(prev => prev.filter(i => i.id !== itemId))
      notifyChanged()
    } catch (err) {
      console.error('Failed to delete module item:', err)
    }
  }, [projectId, module.id, notifyChanged])

  // Grid-Template aus Spalten ableiten (+ Lösch-Spalte)
  const gridCols = columns.map(c =>
    c.type === 'check' ? '32px' : c.type === 'time' ? '52px' : 'minmax(0,1fr)'
  ).join(' ') + (canEdit ? ' 24px' : '')

  return (
    <div>
      {/* Spalten-Kopf */}
      <div className="grid text-[10px] font-semibold text-muted-foreground border-b border-border/50" style={{ gridTemplateColumns: gridCols }}>
        {columns.map(c => (
          <div key={c.key} className={`px-1.5 py-1 truncate ${c.type !== 'text' ? 'text-center' : ''}`}>{c.label}</div>
        ))}
        {canEdit && <div />}
      </div>

      {isLoading ? (
        <div className="flex items-center justify-center py-4 text-muted-foreground text-xs">
          <Loader2 className="w-3.5 h-3.5 animate-spin mr-1.5" /> Laden…
        </div>
      ) : items.length === 0 ? (
        <div className="text-center text-muted-foreground py-3 text-xs">Keine Einträge</div>
      ) : (
        <div className="divide-y divide-border/50">
          {items.map((item, idx) => (
            <div key={item.id} className={`grid items-center text-xs print:text-[9px] group ${idx % 2 === 0 ? '' : 'bg-stone-50 dark:bg-muted/20'}`} style={{ gridTemplateColumns: gridCols }}>
              {columns.map(c => {
                if (c.type === 'check') {
                  const checked = !!item.data[c.key]
                  const at = item.data[`${c.key}At`]
                  return (
                    <div key={c.key} className="flex items-center justify-center py-1.5">
                      <button
                        onClick={() => toggleCheck(item, c.key)}
                        disabled={!canEdit}
                        title={at ? `${c.label}: ${formatTime(at)}` : c.label}
                        className={`w-5 h-5 rounded border-2 flex items-center justify-center transition-colors ${
                          checked ? 'bg-green-500 border-green-500 text-white' : 'border-muted-foreground/30 hover:border-green-400'
                        }`}
                      >
                        {checked && <Check className="w-3 h-3" />}
                      </button>
                    </div>
                  )
                }
                if (c.type === 'time') {
                  // Zeit-Spalte: automatisch = Erstellzeit (oder explizit gesetzter Wert)
                  const t = item.data[c.key] || item.createdAt
                  return (
                    <div key={c.key} className="px-1.5 py-1.5 font-mono tabular-nums text-muted-foreground text-center text-[11px]">
                      {t ? formatTime(t) : '–'}
                    </div>
                  )
                }
                return (
                  <div key={c.key} className="px-1.5 py-1.5 break-words min-w-0">
                    {item.data[c.key] || <span className="text-muted-foreground">–</span>}
                  </div>
                )
              })}
              {canEdit && (
                <button
                  onClick={() => deleteRow(item.id)}
                  className="opacity-0 group-hover:opacity-100 text-muted-foreground hover:text-destructive flex items-center justify-center print:hidden"
                >
                  <Trash2 className="w-3 h-3" />
                </button>
              )}
            </div>
          ))}
        </div>
      )}

      {/* Neue Zeile */}
      {canEdit && (
        <div className="flex gap-1 px-1.5 py-1.5 border-t border-border/50 print:hidden">
          {textColumns.map((c, i) => (
            <Input
              key={c.key}
              placeholder={c.label + '…'}
              value={draft[c.key] || ''}
              onChange={(e) => setDraft(prev => ({ ...prev, [c.key]: e.target.value }))}
              onKeyDown={(e) => e.key === 'Enter' && addRow()}
              className={`h-6 text-[11px] ${i === 0 ? 'flex-1 min-w-0' : 'w-20 shrink-0'}`}
            />
          ))}
          <Button size="sm" variant="ghost" onClick={addRow} disabled={!textColumns.some(c => (draft[c.key] || '').trim())} className="h-6 px-1.5 shrink-0">
            <Plus className="w-3 h-3" />
          </Button>
        </div>
      )}
    </div>
  )
}
