"use client";

import { useMemo, useState, useEffect, useCallback } from "react";
import { useSettings } from "@/app/lib/settings";
import {
  TableMetadata,
  fetchTableStats,
  fetchExtensions,
  fetchPublications,
  fetchIndexes,
  fetchDbConfig,
  type TableStats,
  type DbExtension,
  type DbPublication,
  type DbIndex,
  ApiError,
} from "@/app/lib/api";
import { cn } from "@/app/lib/utils";
import { ScrollArea } from "./ui/scroll-area";
import { Badge } from "./ui/badge";
import { Input } from "./ui/input";
import { Button } from "./ui/button";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "./ui/tabs";
import {
  Database,
  Table2,
  Search,
  ChevronRight,
  Columns3,
  HardDrive,
  Layers,
  Loader2,
  Plug,
  BookOpen,
  RefreshCw,
  Settings2,
  Plus,
} from "lucide-react";
import { toast } from "sonner";

type Props = {
  clients: string[];
  selectedClient: string | null;
  tables: TableMetadata[];
  onSelectTable: (table: TableMetadata) => void;
  currentSchema: string;
  onCreateTable?: () => void;
};

export default function DatabaseOverview({
  selectedClient,
  tables,
  onSelectTable,
  currentSchema,
  onCreateTable,
}: Props) {
  const { baseUrl, apiKey } = useSettings();
  const ctx = useMemo(() => ({ baseUrl, apiKey }), [baseUrl, apiKey]);
  const [search, setSearch] = useState("");
  const [stats, setStats] = useState<TableStats | null>(null);
  const [extensions, setExtensions] = useState<DbExtension[]>([]);
  const [publications, setPublications] = useState<DbPublication[]>([]);
  const [indexes, setIndexes] = useState<DbIndex[]>([]);
  const [dbConfig, setDbConfig] = useState<
    { name: string; setting: string; category: string }[]
  >([]);
  const [loadingTab, setLoadingTab] = useState<string | null>(null);

  useEffect(() => {
    if (!selectedClient) return;
    fetchTableStats(ctx, selectedClient).then(setStats);
  }, [ctx, selectedClient]);

  const loadExtensions = useCallback(async () => {
    if (!selectedClient) return;
    setLoadingTab("extensions");
    const result = await fetchExtensions(ctx, selectedClient);
    setExtensions(result);
    setLoadingTab(null);
  }, [ctx, selectedClient]);

  const loadPublications = useCallback(async () => {
    if (!selectedClient) return;
    setLoadingTab("publications");
    const result = await fetchPublications(ctx, selectedClient);
    setPublications(result);
    setLoadingTab(null);
  }, [ctx, selectedClient]);

  const loadIndexes = useCallback(async () => {
    if (!selectedClient) return;
    setLoadingTab("indexes");
    const result = await fetchIndexes(
      ctx,
      selectedClient,
      undefined,
      currentSchema,
    );
    setIndexes(result);
    setLoadingTab(null);
  }, [ctx, selectedClient, currentSchema]);

  const loadConfig = useCallback(async () => {
    if (!selectedClient) return;
    setLoadingTab("config");
    const result = await fetchDbConfig(ctx, selectedClient);
    setDbConfig(result);
    setLoadingTab(null);
  }, [ctx, selectedClient]);

  const filteredTables = useMemo(() => {
    if (!search.trim()) return tables;
    const q = search.toLowerCase();
    return tables.filter(
      (t) =>
        t.table_name.toLowerCase().includes(q) ||
        (t.table_schema ?? "public").toLowerCase().includes(q),
    );
  }, [tables, search]);

  const grouped = useMemo(() => {
    const m = new Map<string, TableMetadata[]>();
    for (const t of filteredTables) {
      const s = t.table_schema ?? "public";
      if (!m.has(s)) m.set(s, []);
      m.get(s)!.push(t);
    }
    return Array.from(m.entries()).sort(([a], [b]) => a.localeCompare(b));
  }, [filteredTables]);

  if (!selectedClient) {
    return (
      <div className="flex flex-1 flex-col items-center justify-center text-muted-foreground">
        <Database className="h-16 w-16 opacity-20 mb-4" />
        <p className="text-sm">
          Select a client from the sidebar to browse tables
        </p>
      </div>
    );
  }

  return (
    <div className="flex flex-1 flex-col min-h-0">
      <div className="border-b border-border px-6 py-4">
        <div className="flex items-center gap-3">
          <div className="flex h-10 w-10 items-center justify-center rounded bg-primary-muted">
            <Database className="h-5 w-5 text-primary" />
          </div>
          <div>
            <h2 className="text-sm font-semibold text-foreground">Database</h2>
            <p className="text-xs text-muted-foreground mt-0.5">
              {selectedClient}
            </p>
          </div>
        </div>

        {stats && (
          <div className="grid grid-cols-4 gap-3 mt-4">
            <div className="rounded border border-border bg-card p-3">
              <div className="flex items-center gap-1.5 text-muted-foreground mb-1">
                <Table2 className="h-3.5 w-3.5" />
                <span className="text-caption uppercase tracking-wider">
                  Tables
                </span>
              </div>
              <span className="text-lg font-semibold text-foreground">
                {stats.total_tables}
              </span>
            </div>
            <div className="rounded border border-border bg-card p-3">
              <div className="flex items-center gap-1.5 text-muted-foreground mb-1">
                <Columns3 className="h-3.5 w-3.5" />
                <span className="text-caption uppercase tracking-wider">
                  Columns
                </span>
              </div>
              <span className="text-lg font-semibold text-foreground">
                {stats.total_columns}
              </span>
            </div>
            <div className="rounded border border-border bg-card p-3">
              <div className="flex items-center gap-1.5 text-muted-foreground mb-1">
                <HardDrive className="h-3.5 w-3.5" />
                <span className="text-caption uppercase tracking-wider">
                  Size
                </span>
              </div>
              <span className="text-lg font-semibold text-foreground">
                {stats.total_size}
              </span>
            </div>
            <div className="rounded border border-border bg-card p-3">
              <div className="flex items-center gap-1.5 text-muted-foreground mb-1">
                <Layers className="h-3.5 w-3.5" />
                <span className="text-caption uppercase tracking-wider">
                  Schemas
                </span>
              </div>
              <span className="text-lg font-semibold text-foreground">
                {stats.schemas.length}
              </span>
            </div>
          </div>
        )}
      </div>

      <Tabs defaultValue="tables" className="flex flex-col flex-1 min-h-0">
        <div className="border-b border-border px-6">
          <TabsList className="h-9">
            <TabsTrigger value="tables">Tables</TabsTrigger>
            <TabsTrigger value="extensions" onClick={loadExtensions}>
              Extensions
            </TabsTrigger>
            <TabsTrigger value="publications" onClick={loadPublications}>
              Publications
            </TabsTrigger>
            <TabsTrigger value="indexes" onClick={loadIndexes}>
              Indexes
            </TabsTrigger>
            <TabsTrigger value="config" onClick={loadConfig}>
              Configuration
            </TabsTrigger>
          </TabsList>
        </div>

        <TabsContent value="tables" className="flex-1 min-h-0 m-0">
          <div className="px-6 py-3 border-b border-border flex items-center gap-3">
            <div className="relative flex-1 max-w-sm">
              <Search className="absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" />
              <Input
                placeholder="Search tables..."
                value={search}
                onChange={(e) => setSearch(e.target.value)}
                className="pl-9 h-8"
              />
            </div>
            {onCreateTable && (
              <Button size="sm" onClick={onCreateTable}>
                <Plus className="h-3 w-3" /> Create table
              </Button>
            )}
          </div>

          <ScrollArea className="flex-1">
            <div className="p-6 space-y-6">
              {grouped.length === 0 ? (
                <div className="flex flex-col items-center justify-center py-16 text-center">
                  <Table2 className="h-12 w-12 text-muted-foreground-dim mb-3" />
                  <p className="text-sm text-muted-foreground">
                    {search ? "No tables match your search" : "No tables found"}
                  </p>
                </div>
              ) : (
                grouped.map(([schema, schemaTables]) => (
                  <section key={schema}>
                    <div className="flex items-center gap-2 mb-3">
                      <span className="text-xs font-medium uppercase tracking-wider text-muted-foreground">
                        {schema}
                      </span>
                      <Badge variant="secondary" className="text-caption">
                        {schemaTables.length}
                      </Badge>
                    </div>
                    <div className="grid gap-1">
                      {schemaTables.map((t) => (
                        <button
                          key={`${t.table_schema ?? "public"}.${t.table_name}`}
                          onClick={() => onSelectTable(t)}
                          className="flex w-full items-center gap-3 rounded border border-transparent px-4 py-2.5 text-left transition-all duration-150 hover:bg-accent-panel hover:text-foreground text-muted-foreground hover:border-border-muted"
                        >
                          <Table2 className="h-4 w-4 shrink-0 opacity-60" />
                          <span className="flex-1 truncate font-mono text-sm">
                            {t.table_name}
                          </span>
                          <ChevronRight className="h-4 w-4 shrink-0 opacity-40" />
                        </button>
                      ))}
                    </div>
                  </section>
                ))
              )}
            </div>
          </ScrollArea>
        </TabsContent>

        <TabsContent value="extensions" className="flex-1 min-h-0 m-0">
          {loadingTab === "extensions" ? (
            <div className="flex flex-1 items-center justify-center py-12">
              <Loader2 className="h-6 w-6 animate-spin text-primary" />
            </div>
          ) : extensions.length === 0 ? (
            <div className="flex flex-1 flex-col items-center justify-center py-12 text-muted-foreground">
              <Plug className="h-10 w-10 opacity-20 mb-3" />
              <p className="text-sm">No extensions loaded</p>
            </div>
          ) : (
            <ScrollArea className="flex-1">
              <div className="p-4 space-y-1">
                {extensions.map((ext) => (
                  <div
                    key={ext.name}
                    className="flex items-center gap-3 rounded border border-border-muted bg-card px-4 py-3 hover:bg-accent-muted transition-colors"
                  >
                    <Plug className="h-4 w-4 text-muted-foreground-subtle shrink-0" />
                    <div className="flex-1 min-w-0">
                      <div className="flex items-center gap-2">
                        <span className="text-xs font-medium text-foreground">
                          {ext.name}
                        </span>
                        <Badge variant="secondary" className="text-tiny">
                          v{ext.version}
                        </Badge>
                        <span className="text-caption text-muted-foreground">
                          {ext.schema}
                        </span>
                      </div>
                      {ext.description && (
                        <p className="text-caption text-muted-foreground mt-0.5 truncate">
                          {ext.description}
                        </p>
                      )}
                    </div>
                  </div>
                ))}
              </div>
            </ScrollArea>
          )}
        </TabsContent>

        <TabsContent value="publications" className="flex-1 min-h-0 m-0">
          {loadingTab === "publications" ? (
            <div className="flex flex-1 items-center justify-center py-12">
              <Loader2 className="h-6 w-6 animate-spin text-primary" />
            </div>
          ) : publications.length === 0 ? (
            <div className="flex flex-1 flex-col items-center justify-center py-12 text-muted-foreground">
              <BookOpen className="h-10 w-10 opacity-20 mb-3" />
              <p className="text-sm">No publications</p>
              <p className="text-xs text-muted-foreground-subtle mt-1">
                Logical replication publications will appear here
              </p>
            </div>
          ) : (
            <ScrollArea className="flex-1">
              <div className="p-4 space-y-1">
                {publications.map((pub) => (
                  <div
                    key={pub.name}
                    className="rounded border border-border-muted bg-card px-4 py-3 hover:bg-accent-muted transition-colors"
                  >
                    <div className="flex items-center gap-2 mb-1">
                      <span className="text-xs font-medium text-foreground">
                        {pub.name}
                      </span>
                      <Badge variant="secondary" className="text-tiny">
                        owner: {pub.owner}
                      </Badge>
                      {pub.all_tables && (
                        <Badge variant="default" className="text-tiny">
                          all tables
                        </Badge>
                      )}
                    </div>
                    {!pub.all_tables && pub.tables.length > 0 && (
                      <p className="text-caption text-muted-foreground font-mono truncate">
                        {pub.tables.join(", ")}
                      </p>
                    )}
                  </div>
                ))}
              </div>
            </ScrollArea>
          )}
        </TabsContent>

        <TabsContent value="indexes" className="flex-1 min-h-0 m-0">
          {loadingTab === "indexes" ? (
            <div className="flex flex-1 items-center justify-center py-12">
              <Loader2 className="h-6 w-6 animate-spin text-primary" />
            </div>
          ) : indexes.length === 0 ? (
            <div className="flex flex-1 flex-col items-center justify-center py-12 text-muted-foreground">
              <Layers className="h-10 w-10 opacity-20 mb-3" />
              <p className="text-sm">No indexes found</p>
            </div>
          ) : (
            <ScrollArea className="flex-1">
              <div className="p-4 space-y-1">
                {indexes.map((idx, i) => (
                  <div
                    key={`${idx.index_name}-${i}`}
                    className="rounded border border-border-muted bg-card px-4 py-3 hover:bg-accent-muted transition-colors"
                  >
                    <div className="flex items-center gap-2 mb-1">
                      <span className="text-xs font-medium text-foreground font-mono">
                        {idx.index_name}
                      </span>
                      {idx.is_unique && (
                        <Badge variant="default" className="text-tiny">
                          unique
                        </Badge>
                      )}
                      <span className="text-caption text-muted-foreground">
                        on {idx.table_name}
                      </span>
                    </div>
                    <p className="text-caption text-muted-foreground font-mono truncate">
                      {idx.index_definition}
                    </p>
                  </div>
                ))}
              </div>
            </ScrollArea>
          )}
        </TabsContent>

        <TabsContent
          value="config"
          className="flex-1 min-h-0 m-0 overflow-hidden"
        >
          {loadingTab === "config" ? (
            <div className="flex flex-1 items-center justify-center py-12">
              <Loader2 className="h-6 w-6 animate-spin text-primary" />
            </div>
          ) : dbConfig.length === 0 ? (
            <div className="flex flex-1 flex-col items-center justify-center py-12 text-muted-foreground">
              <Settings2 className="h-10 w-10 opacity-20 mb-3" />
              <p className="text-sm">No configuration loaded</p>
            </div>
          ) : (
            <div className="h-full overflow-auto">
              <table className="w-full text-xs">
                <thead className="sticky top-0 z-[5]">
                  <tr className="border-b border-border bg-grid-header">
                    <th className="px-4 py-2 text-left text-caption font-medium text-muted-foreground">
                      Name
                    </th>
                    <th className="px-4 py-2 text-left text-caption font-medium text-muted-foreground">
                      Setting
                    </th>
                    <th className="px-4 py-2 text-left text-caption font-medium text-muted-foreground">
                      Category
                    </th>
                  </tr>
                </thead>
                <tbody className="divide-y divide-border/50">
                  {dbConfig.map((c, i) => (
                    <tr
                      key={`${c.name}-${i}`}
                      className="hover:bg-accent-muted transition-colors"
                    >
                      <td className="px-4 py-2 font-mono text-body-sm text-foreground whitespace-nowrap">
                        {c.name}
                      </td>
                      <td className="px-4 py-2 font-mono text-body-sm text-muted-foreground max-w-[300px] truncate">
                        {c.setting}
                      </td>
                      <td className="px-4 py-2 text-caption text-muted-foreground">
                        {c.category}
                      </td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
          )}
        </TabsContent>
      </Tabs>
    </div>
  );
}
