import { useState } from "preact/hooks";
import { useSpec } from "@/hooks/useSpec";
import { useData, createRecord, updateRecord, deleteRecord as apiDelete } from "@/hooks/useData";
import { TopBar } from "@/layouts/TopBar";
import { Sidebar } from "@/layouts/Sidebar";
import { ToastContainer, showToast } from "@/components/Toast";
import { ConfirmDialog } from "@/components/ConfirmDialog";
import { SplashScreen } from "@/components/Skeleton";
import { ErrorBoundary } from "@/components/ErrorBoundary";
import { ListView } from "@/views/ListView";
import { DetailView } from "@/views/DetailView";
import { FormView } from "@/views/FormView";
import { Dashboard } from "@/views/Dashboard";
import type { DataRow } from "@/types/spec";

type ViewMode = "list" | "detail" | "form" | "edit";

interface PendingConfirm {
  title: string;
  message: string;
  danger?: boolean;
  onConfirm: () => void;
}

export function App() {
  const spec = useSpec();
  const data = useData(spec?.app?.records);

  const [currentPage, setCurrentPage] = useState<string | null>(null);
  const [viewMode, setViewMode] = useState<ViewMode>("list");
  const [selectedRecord, setSelectedRecord] = useState<DataRow | null>(null);
  const [selectedTable, setSelectedTable] = useState<string | null>(null);
  const [confirm, setConfirm] = useState<PendingConfirm | null>(null);

  // Branded splash screen during initial load
  if (!spec) {
    return <SplashScreen />;
  }

  if (spec.error) {
    return (
      <div class="max-w-xl mx-auto mt-20 p-6 rounded-xl" style={{ border: "1px solid rgba(239,68,68,0.3)", background: "rgba(239,68,68,0.05)" }}>
        <h2 class="text-red-400 font-semibold mb-2">Error</h2>
        <pre class="text-sm font-mono whitespace-pre-wrap" style={{ color: "rgba(248,113,113,0.7)" }}>{spec.error}</pre>
      </div>
    );
  }

  const app = spec.app;
  const pages = spec.pages;
  const navMode = app.nav || "tabs";

  // Build tabs
  const seenRecords = new Set<string>();
  const tabs = pages
    .filter((p) => {
      if (p.type === "list" && p.record && !seenRecords.has(p.record)) { seenRecords.add(p.record); return true; }
      return p.type === "custom";
    })
    .map((p) => ({
      name: p.name,
      icon: p.config?.icon || null,
      badge: p.record ? (data[p.record] || []).length || null : null,
    }));

  const active = currentPage || tabs[0]?.name || "";

  // Navigation
  function switchPage(name: string) {
    setCurrentPage(name);
    setViewMode("list");
    setSelectedRecord(null);
    setSelectedTable(null);
  }

  function viewDetail(table: string, id: string) {
    const row = (data[table] || []).find((r) => String(r.id) === String(id));
    if (!row) return;
    setSelectedRecord(row);
    setSelectedTable(table);
    setViewMode("detail");
    // Switch tab if navigating to different table
    const targetPage = pages.find((p) => p.type === "list" && p.record === table);
    if (targetPage && targetPage.name !== active) setCurrentPage(targetPage.name);
  }

  // CRUD
  async function handleCycleField(table: string, id: string, field: string, current: string, choices: string[]) {
    const idx = choices.indexOf(current);
    const next = choices[(idx + 1) % choices.length];
    await updateRecord(table, id, { [field]: next });
    // Optimistic update
    const row = (data[table] || []).find((r) => String(r.id) === String(id));
    if (row) (row as any)[field] = next;
    if (selectedRecord && String(selectedRecord.id) === id) setSelectedRecord({ ...selectedRecord, [field]: next });
  }

  function handleDelete(table: string, id: string) {
    const rec = app.records.find((r) => r.table === table);
    setConfirm({
      title: `Delete ${rec?.name || "record"}?`,
      message: "This action cannot be undone. The record will be permanently removed.",
      danger: true,
      onConfirm: async () => {
        await apiDelete(table, id);
        showToast(`${rec?.name || "Record"} deleted`);
        if (viewMode === "detail") { setViewMode("list"); setSelectedRecord(null); }
        setConfirm(null);
      },
    });
  }

  async function handleSave(table: string, id: string, changes: Record<string, unknown>) {
    await updateRecord(table, id, changes);
    const rec = app.records.find((r) => r.table === table);
    showToast(`${rec?.name || "Record"} updated`);
    // Update local state
    const row = (data[table] || []).find((r) => String(r.id) === String(id));
    if (row) { Object.assign(row, changes); setSelectedRecord({ ...row }); }
  }

  async function handleSubmit(table: string, formData: Record<string, unknown>) {
    await createRecord(table, formData);
    const rec = app.records.find((r) => r.table === table);
    showToast(`${rec?.name || "Record"} added`);
    setViewMode("list");
  }

  // Render active page content
  function renderContent() {
    const activePage = pages.find((p) => p.name === active);
    if (!activePage) return <p style={{ color: "var(--z-muted)" }}>No pages</p>;

    // Custom page (dashboard)
    if (activePage.type === "custom") {
      return <Dashboard page={activePage} data={data} />;
    }

    // Record pages
    const record = activePage.record!;
    const rec = app.records.find((r) => r.table === record);
    const listPage = pages.find((p) => p.type === "list" && p.record === record);
    const detailPage = pages.find((p) => p.type === "detail" && p.record === record);
    const formPage = pages.find((p) => p.type === "form" && p.record === record);
    const rows = data[record] || [];
    const tabName = listPage?.name || record;

    if (viewMode === "detail" && selectedRecord && detailPage) {
      // Keep selectedRecord fresh
      const fresh = rows.find((r) => String(r.id) === String(selectedRecord.id));
      const displayRecord = fresh || selectedRecord;
      return (
        <DetailView
          page={detailPage}
          rec={rec}
          record={displayRecord}
          allRecords={app.records}
          allData={data}
          tabName={tabName}
          onBack={() => { setViewMode("list"); setSelectedRecord(null); }}
          onViewDetail={viewDetail}
          onSave={handleSave}
          onDelete={handleDelete}
        />
      );
    }

    if (viewMode === "form" && formPage && rec) {
      return (
        <FormView
          page={formPage}
          rec={rec}
          allRecords={app.records}
          allData={data}
          tabName={tabName}
          onBack={() => setViewMode("list")}
          onSubmit={handleSubmit}
        />
      );
    }

    if (listPage) {
      return (
        <ListView
          page={listPage}
          rec={rec}
          data={rows}
          allRecords={app.records}
          allData={data}
          onViewDetail={viewDetail}
          onAdd={() => setViewMode("form")}
          onCycleField={handleCycleField}
          onDelete={handleDelete}
        />
      );
    }

    return null;
  }

  const content = (
    <main class="max-w-[var(--z-content-width)] mx-auto px-6 py-6">
      <ErrorBoundary>{renderContent()}</ErrorBoundary>
    </main>
  );

  return (
    <>
      {navMode === "sidebar" ? (
        <div class="flex min-h-screen">
          <Sidebar appName={app.name} appIcon={app.icon} tabs={tabs} current={active} onSelect={switchPage} />
          <div class="flex-1 min-w-0">
            <TopBar appName={app.name} appIcon={app.icon} hideTabs />
            {content}
          </div>
        </div>
      ) : (
        <>
          <TopBar appName={app.name} appIcon={app.icon} tabs={tabs} current={active} onSelect={switchPage} />
          {content}
        </>
      )}
      <ToastContainer />
      {confirm && (
        <ConfirmDialog
          title={confirm.title}
          message={confirm.message}
          danger={confirm.danger}
          confirmLabel="Delete"
          onConfirm={confirm.onConfirm}
          onCancel={() => setConfirm(null)}
        />
      )}
    </>
  );
}
