"use client";

import { useCallback, useEffect, useMemo, useState } from "react";
import {
  desktopAppInfo,
  desktopAthenaHealth,
  desktopPing,
  type DesktopAppInfo,
  type DesktopAthenaHealth,
} from "@/app/lib/desktop";
import { useSettings } from "@/app/lib/settings";
import { Badge } from "./ui/badge";
import { Button } from "./ui/button";
import { Input } from "./ui/input";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "./ui/tabs";
import {
  BookOpen,
  Code2,
  Lock,
  RefreshCcw,
  Save,
  Settings2,
} from "lucide-react";
import { toast } from "sonner";

const SCHEMAS = ["public", "graphql_public", "vault", "extensions"];

type SelectState = Record<string, boolean>;

function SchemaPills({
  state,
  onToggle,
}: {
  state: SelectState;
  onToggle: (name: string) => void;
}) {
  return (
    <div className="flex flex-wrap gap-2">
      {SCHEMAS.map((schema) => {
        const active = !!state[schema];
        return (
          <button
            key={schema}
            type="button"
            onClick={() => onToggle(schema)}
            className={`rounded border px-2.5 py-1 text-body-sm font-mono uppercase tracking-wide transition-colors ${
              active
                ? "border-primary/50 bg-primary/10 text-primary"
                : "border-border bg-background text-muted-foreground hover:bg-accent/40"
            }`}
          >
            {schema}
          </button>
        );
      })}
    </div>
  );
}

export default function DataApiPage() {
  const { baseUrl } = useSettings();
  const [enabled, setEnabled] = useState(true);
  const [maxRows, setMaxRows] = useState("10000");
  const [poolSize, setPoolSize] = useState("Configured automatically");
  const [desktopState, setDesktopState] = useState<
    "checking" | "connected" | "unavailable"
  >("checking");
  const [desktopInfo, setDesktopInfo] = useState<DesktopAppInfo | null>(null);
  const [healthInfo, setHealthInfo] = useState<DesktopAthenaHealth | null>(
    null,
  );

  const [exposedSchemas, setExposedSchemas] = useState<SelectState>({
    public: true,
    graphql_public: true,
    vault: true,
    extensions: false,
  });

  const [searchPathSchemas, setSearchPathSchemas] = useState<SelectState>({
    public: true,
    extensions: true,
    vault: true,
    graphql_public: false,
  });

  const apiUrl = useMemo(() => {
    try {
      const parsed = new URL(baseUrl);
      return `${parsed.origin}/rest/v1`;
    } catch {
      return `${baseUrl.replace(/\/$/, "")}/rest/v1`;
    }
  }, [baseUrl]);

  const toggleExposed = (name: string) => {
    setExposedSchemas((prev) => ({ ...prev, [name]: !prev[name] }));
  };

  const toggleSearchPath = (name: string) => {
    setSearchPathSchemas((prev) => ({ ...prev, [name]: !prev[name] }));
  };

  const refreshDesktopStatus = useCallback(async (): Promise<boolean> => {
    setDesktopState("checking");

    const ping = await desktopPing();
    if (ping !== "pong") {
      setDesktopState("unavailable");
      setDesktopInfo(null);
      setHealthInfo(null);
      return false;
    }

    const [info, health] = await Promise.all([
      desktopAppInfo(),
      desktopAthenaHealth(baseUrl),
    ]);

    setDesktopInfo(info);
    setHealthInfo(health);
    setDesktopState("connected");
    return true;
  }, [baseUrl]);

  useEffect(() => {
    void refreshDesktopStatus();
  }, [refreshDesktopStatus]);

  const handleSave = async () => {
    toast.success("Data API settings saved");

    const isDesktopConnected = await refreshDesktopStatus();
    if (isDesktopConnected) {
      toast("Desktop bridge refreshed");
    }
  };

  return (
    <div className="flex flex-1 min-h-0 overflow-auto">
      <div className="mx-auto w-full max-w-[1120px] px-6 py-8">
        <div className="flex items-start gap-3 pb-6">
          <div className="flex h-12 w-12 items-center justify-center rounded-lg bg-primary/10">
            <Code2 className="h-6 w-6 text-primary" />
          </div>
          <div>
            <h1 className="text-3xl font-semibold tracking-tight">Data API</h1>
            <p className="mt-1 text-sm text-muted-foreground">
              Auto-generate an API directly from your database schema.
            </p>
          </div>
        </div>

        <Tabs defaultValue="settings" className="space-y-0">
          <TabsList className="mb-5 h-10">
            <TabsTrigger value="overview">Overview</TabsTrigger>
            <TabsTrigger value="settings">Settings</TabsTrigger>
            <TabsTrigger value="docs">Docs</TabsTrigger>
          </TabsList>

          <TabsContent value="overview" className="mt-0 space-y-5">
            <section className="rounded-lg border border-border bg-card p-5">
              <div className="grid gap-5 md:grid-cols-3">
                <div>
                  <p className="text-xs uppercase tracking-wider text-muted-foreground">
                    Built by
                  </p>
                  <p className="mt-2 text-sm font-medium">XYLEX Group</p>
                </div>
                <div>
                  <p className="text-xs uppercase tracking-wider text-muted-foreground">
                    Docs
                  </p>
                  <p className="mt-2 text-sm font-medium">
                    Athena Data API docs
                  </p>
                </div>
                <div>
                  <p className="text-xs uppercase tracking-wider text-muted-foreground">
                    Website
                  </p>
                  <p className="mt-2 text-sm font-medium">athena-db.com</p>
                </div>
              </div>
              <p className="mt-6 text-sm text-muted-foreground">
                The Data API exposes RESTful endpoints for your project and can
                be scoped to specific schemas.
              </p>
            </section>

            <section className="rounded-lg border border-border bg-card p-5">
              <div className="flex items-start justify-between gap-3">
                <div>
                  <p className="text-xl font-semibold">Desktop Bridge</p>
                  <p className="mt-1 text-sm text-muted-foreground">
                    Tauri runtime and local Athena API connection status.
                  </p>
                </div>
                <Button
                  variant="outline"
                  size="sm"
                  onClick={() => void refreshDesktopStatus()}
                >
                  <RefreshCcw className="h-3.5 w-3.5" /> Refresh
                </Button>
              </div>
              <div className="mt-4 grid gap-3 md:grid-cols-3">
                <div className="rounded-lg border border-border bg-background p-3">
                  <p className="text-xs uppercase tracking-wide text-muted-foreground">
                    Runtime
                  </p>
                  <div className="mt-1 flex items-center gap-2">
                    <Badge
                      variant={
                        desktopState === "connected" ? "default" : "secondary"
                      }
                    >
                      {desktopState === "checking"
                        ? "Checking"
                        : desktopState === "connected"
                          ? "Connected"
                          : "Browser mode"}
                    </Badge>
                  </div>
                </div>
                <div className="rounded-lg border border-border bg-background p-3">
                  <p className="text-xs uppercase tracking-wide text-muted-foreground">
                    Desktop App
                  </p>
                  <p className="mt-1 text-sm font-medium">
                    {desktopInfo
                      ? `${desktopInfo.name} ${desktopInfo.version}`
                      : "Not detected"}
                  </p>
                </div>
                <div className="rounded-lg border border-border bg-background p-3">
                  <p className="text-xs uppercase tracking-wide text-muted-foreground">
                    Athena Health
                  </p>
                  <p className="mt-1 text-sm font-medium">
                    {healthInfo
                      ? `${healthInfo.ok ? "Healthy" : "Unhealthy"} (${healthInfo.statusCode})`
                      : "Unavailable"}
                  </p>
                </div>
              </div>
            </section>

            <section className="rounded-lg border border-border bg-card p-5">
              <p className="text-xl font-semibold">API URL</p>
              <p className="mt-1 text-sm text-muted-foreground">
                RESTful endpoint for querying and managing your database.
              </p>
              <div className="mt-4 flex flex-wrap items-center gap-2">
                <Input
                  value={apiUrl}
                  readOnly
                  className="max-w-[560px] font-mono text-xs"
                />
                <Button
                  variant="outline"
                  size="sm"
                  onClick={() => navigator.clipboard.writeText(apiUrl)}
                >
                  Copy
                </Button>
              </div>
              <div className="mt-6 rounded-lg border border-border bg-background p-4">
                <div className="flex items-center justify-between gap-3">
                  <div>
                    <p className="text-sm font-medium">Enable Data API</p>
                    <p className="text-xs text-muted-foreground mt-0.5">
                      When enabled, Athena endpoints become available for
                      configured schemas.
                    </p>
                  </div>
                  <button
                    type="button"
                    onClick={() => setEnabled((prev) => !prev)}
                    className={`h-7 w-12 rounded-full p-1 transition-colors ${enabled ? "bg-success" : "bg-muted"}`}
                    aria-label="Toggle Data API"
                  >
                    <span
                      className={`block h-5 w-5 rounded-full bg-white transition-transform ${enabled ? "translate-x-5" : "translate-x-0"}`}
                    />
                  </button>
                </div>
              </div>
            </section>
          </TabsContent>

          <TabsContent value="settings" className="mt-0">
            <section className="rounded-lg border border-border bg-card overflow-hidden">
              <div className="grid divide-y divide-border">
                <div className="grid gap-4 px-5 py-4 md:grid-cols-[280px_1fr]">
                  <div>
                    <p className="text-sm font-semibold">Exposed schemas</p>
                    <p className="text-xs text-muted-foreground mt-1">
                      Tables and views in these schemas become API endpoints.
                    </p>
                  </div>
                  <SchemaPills
                    state={exposedSchemas}
                    onToggle={toggleExposed}
                  />
                </div>

                <div className="grid gap-4 px-5 py-4 md:grid-cols-[280px_1fr]">
                  <div>
                    <p className="text-sm font-semibold">Extra search path</p>
                    <p className="text-xs text-muted-foreground mt-1">
                      Additional schemas available in each request search_path.
                    </p>
                  </div>
                  <SchemaPills
                    state={searchPathSchemas}
                    onToggle={toggleSearchPath}
                  />
                </div>

                <div className="grid gap-4 px-5 py-4 md:grid-cols-[280px_1fr]">
                  <div>
                    <p className="text-sm font-semibold">Max rows</p>
                    <p className="text-xs text-muted-foreground mt-1">
                      Limits payload size for accidental or malicious requests.
                    </p>
                  </div>
                  <div className="max-w-[380px]">
                    <Input
                      value={maxRows}
                      onChange={(e) => setMaxRows(e.target.value)}
                      className="font-mono"
                    />
                  </div>
                </div>

                <div className="grid gap-4 px-5 py-4 md:grid-cols-[280px_1fr]">
                  <div>
                    <p className="text-sm font-semibold">Pool size</p>
                    <p className="text-xs text-muted-foreground mt-1">
                      Maximum open connections in Deadpool API server pool.
                    </p>
                  </div>
                  <div className="max-w-[380px]">
                    <Input
                      value={poolSize}
                      onChange={(e) => setPoolSize(e.target.value)}
                      className="font-mono"
                    />
                  </div>
                </div>
              </div>

              <div className="flex items-center justify-end gap-2 border-t border-border px-5 py-4">
                <Button variant="outline" size="sm">
                  Cancel
                </Button>
                <Button size="sm" onClick={handleSave}>
                  <Save className="h-3.5 w-3.5" /> Save
                </Button>
              </div>
            </section>

            <section className="mt-5 rounded-lg border border-border bg-card p-5">
              <div className="flex items-start justify-between gap-3">
                <div>
                  <p className="text-sm font-semibold">Harden Data API</p>
                  <p className="mt-1 text-xs text-muted-foreground">
                    Expose a custom schema instead of your default public
                    schema.
                  </p>
                </div>
                <Button variant="outline" size="sm">
                  <Lock className="h-3.5 w-3.5" /> Harden Data API
                </Button>
              </div>
            </section>
          </TabsContent>

          <TabsContent value="docs" className="mt-0">
            <section className="rounded-lg border border-border bg-card p-6">
              <div className="flex items-center gap-2">
                <Badge variant="secondary">Quick docs</Badge>
                <BookOpen className="h-4 w-4 text-muted-foreground" />
              </div>
              <ul className="mt-4 space-y-2 text-sm text-muted-foreground">
                <li>
                  Use `apikey` and `Authorization: Bearer &lt;token&gt;` headers
                  for authenticated requests.
                </li>
                <li>
                  Schema filtering can be applied using the `Accept-Profile` and
                  `Content-Profile` headers.
                </li>
                <li>
                  Enable RLS before using browser-exposed keys in production.
                </li>
              </ul>
              <Button variant="outline" className="mt-5" size="sm">
                <Settings2 className="h-3.5 w-3.5" /> Open full docs
              </Button>
            </section>
          </TabsContent>
        </Tabs>
      </div>
    </div>
  );
}
