"use client";

import { useEffect, useMemo, useState } from "react";
import {
  ColumnMetadata,
  TableMetadata,
  fetchColumns,
  fetchTables,
  fetchClients,
} from "@/app/lib/api";
import TableExplorerSidebar from "./components/TableExplorerSidebar";
import DataGridPanel from "./components/DataGridPanel";
import SchemaActionsPanel from "./components/SchemaActionsPanel";

const DEFAULT_TABLE_TEXT = "Select a table to load data and schema preview.";

const envPreferredClient = process.env.NEXT_PUBLIC_ATHENA_CLIENT;

export default function Home() {
  const [clients, setClients] = useState<string[]>([]);
  const [selectedClient, setSelectedClient] = useState<string | null>(null);
  const [clientsLoading, setClientsLoading] = useState(false);
  const [clientsError, setClientsError] = useState<string | null>(null);
  const [tables, setTables] = useState<TableMetadata[]>([]);
  const [selectedTable, setSelectedTable] = useState<TableMetadata | null>(
    null,
  );
  const [columns, setColumns] = useState<ColumnMetadata[]>([]);
  const [tablesLoading, setTablesLoading] = useState(false);
  const [tablesError, setTablesError] = useState<string | null>(null);
  const [dataRefreshKey, setDataRefreshKey] = useState(0);
  const [schemaVersion, setSchemaVersion] = useState(0);

  const handleReloadTables = (clientName: string) => {
    setTablesLoading(true);
    fetchTables(clientName)
      .then((entries) => {
        setTables(entries);
        setSelectedTable(entries[0] ?? null);
        setTablesError(entries.length === 0 ? "No tables available" : null);
      })
      .catch((error) => {
        setTables([]);
        setSelectedTable(null);
        setTablesError(
          error instanceof Error ? error.message : "Failed to load tables",
        );
      })
      .finally(() => {
        setTablesLoading(false);
      });
  };

  useEffect(() => {
    let canceled = false;
    const timer = setTimeout(() => {
      if (canceled) return;
      setClientsLoading(true);
      fetchClients()
        .then((entries) => {
          if (canceled) return;
          setClients(entries);
          const initial =
            envPreferredClient && entries.includes(envPreferredClient)
              ? envPreferredClient
              : entries[0] ?? null;
          setSelectedClient(initial);
          setClientsError(
            entries.length === 0 ? "No Postgres clients configured" : null,
          );
        })
        .catch((error) => {
          if (canceled) return;
          setClientsError(
            error instanceof Error ? error.message : "Failed to load clients",
          );
        })
        .finally(() => {
          if (!canceled) {
            setClientsLoading(false);
          }
        });
    }, 0);
    return () => {
      canceled = true;
      clearTimeout(timer);
    };
  }, []);

  useEffect(() => {
    const timer = setTimeout(() => {
      if (!selectedClient) {
        setTables([]);
        setSelectedTable(null);
        setColumns([]);
        return;
      }
      handleReloadTables(selectedClient);
    }, 0);
    return () => clearTimeout(timer);
  }, [selectedClient]);

  useEffect(() => {
    let canceled = false;
    const timer = setTimeout(() => {
      if (!selectedTable || !selectedClient) {
        setColumns([]);
        return;
      }
      fetchColumns(selectedTable.table_name, selectedClient)
        .then((result) => {
          if (!canceled) {
            setColumns(result);
          }
        })
        .catch(() => {
          if (!canceled) {
            setColumns([]);
          }
        });
    }, 0);
    return () => {
      canceled = true;
      clearTimeout(timer);
    };
  }, [selectedTable, schemaVersion, selectedClient]);

  const displayMessage = useMemo(() => {
    if (clientsError) {
      return clientsError;
    }
    if (!selectedClient) {
      return "Choose a Postgres client to continue.";
    }
    if (!selectedTable) {
      return `Connected to ${selectedClient}. ${DEFAULT_TABLE_TEXT}`;
    }
    return `Selected schema: ${selectedTable.table_schema ?? "public"} (${selectedClient})`;
  }, [selectedTable, clientsError, selectedClient]);

  const triggerDataRefresh = () => {
    setDataRefreshKey((prev) => prev + 1);
  };

  const triggerSchemaRefresh = () => {
    setSchemaVersion((prev) => prev + 1);
  };

  const handleMutation = () => {
    triggerDataRefresh();
    triggerSchemaRefresh();
  };

  const handleSchemaChange = () => {
    triggerSchemaRefresh();
    triggerDataRefresh();
  };

  return (
    <div className="min-h-screen bg-zinc-950 text-white">
      <div className="mx-auto flex max-w-7xl flex-col gap-6 px-6 py-8 lg:gap-8">
        <header className="space-y-3">
          <p className="text-xs uppercase tracking-[0.4em] text-zinc-500">
            Athena Explorer
          </p>
          <div className="flex flex-wrap items-center gap-3">
            <h1 className="text-4xl font-semibold leading-tight text-white sm:text-5xl">
              Database grid + schema toolkit
            </h1>
            <div className="flex items-center gap-2 text-xs text-zinc-400">
              <label htmlFor="client-select" className="text-[11px] uppercase tracking-wider text-zinc-500">
                Client
              </label>
              {clientsLoading ? (
                <span>Loading clients…</span>
              ) : clientsError ? (
                <span className="text-amber-300">{clientsError}</span>
              ) : (
                <select
                  id="client-select"
                  value={selectedClient ?? ""}
                  onChange={(event) => {
                    if (event.target.value) {
                      setSelectedClient(event.target.value);
                    }
                  }}
                  className="rounded-xl border border-white/10 bg-black/40 px-3 py-1 text-[11px] text-white outline-none focus:border-cyan-400"
                >
                  <option value="" disabled>
                    Select client
                  </option>
                  {clients.map((client) => (
                    <option key={client} value={client}>
                      {client}
                    </option>
                  ))}
                </select>
              )}
              <button
                onClick={() => selectedClient && handleReloadTables(selectedClient)}
                className="rounded-full border border-white/10 px-3 py-1 text-[11px] uppercase tracking-wider text-white transition hover:border-white/40"
                disabled={!selectedClient}
              >
                Refresh
              </button>
            </div>
          </div>
          <p className="text-sm text-zinc-400">{displayMessage}</p>
        </header>
        <div className="grid gap-6 lg:grid-cols-[240px_minmax(0,1fr)_320px]">
          <TableExplorerSidebar
            tables={tables}
            selectedTable={selectedTable}
            loading={tablesLoading}
            error={tablesError}
            onSelect={(table) => {
              setSelectedTable(table);
            }}
          />
          <DataGridPanel
            table={selectedTable}
            columns={columns}
            clientName={selectedClient}
            refreshKey={dataRefreshKey}
            onMutation={handleMutation}
          />
          <SchemaActionsPanel
            table={selectedTable}
            columns={columns}
            clientName={selectedClient}
            onSchemaChange={handleSchemaChange}
          />
        </div>
      </div>
    </div>
  );
}
