"use client";

import { useState } from "react";
import { useAppStore, type Module, type DbEngine } from "@/app/lib/store";
import { PageShell, EmptyState } from "./ui/page-shell";
import { Button } from "./ui/button";
import { Badge } from "./ui/badge";
import { Input } from "./ui/input";
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogDescription,
  DialogFooter,
} from "./ui/dialog";
import {
  ContextMenu,
  ContextMenuTrigger,
  ContextMenuContent,
  ContextMenuItem,
} from "./ui/context-menu";
import {
  Plus,
  Database,
  Layers,
  Trash2,
  CheckCircle2,
  Clock,
  XCircle,
  Server,
  Zap,
  HardDrive,
} from "lucide-react";
import { toast } from "sonner";

// ── Database engine definitions ────────────────────────────────────────────

type EngineMeta = {
  label: string;
  icon: React.ElementType;
  color: string;
  bg: string;
  border: string;
};

const ENGINE_META: Record<DbEngine, EngineMeta> = {
  postgres: {
    label: "PostgreSQL",
    icon: Database,
    color: "text-info",
    bg: "bg-info-muted",
    border: "border-info-border",
  },
  supabase: {
    label: "Supabase",
    icon: Zap,
    color: "text-success",
    bg: "bg-success-muted",
    border: "border-success-border",
  },
  scylladb: {
    label: "ScyllaDB",
    icon: Server,
    color: "text-warning",
    bg: "bg-warning-muted",
    border: "border-warning-border",
  },
  mysql: {
    label: "MySQL",
    icon: Database,
    color: "text-warning",
    bg: "bg-warning-muted",
    border: "border-warning-border",
  },
  other: {
    label: "Other",
    icon: HardDrive,
    color: "text-muted-foreground",
    bg: "bg-muted-card",
    border: "border-border",
  },
};

const DB_ENGINES: DbEngine[] = [
  "postgres",
  "supabase",
  "scylladb",
  "mysql",
  "other",
];

const STATUS_BADGES = {
  active: {
    label: "Active",
    icon: CheckCircle2,
    class: "text-success bg-success-muted border-success-border",
  },
  inactive: {
    label: "Inactive",
    icon: XCircle,
    class: "text-muted-foreground bg-muted-card border-border",
  },
  pending: {
    label: "Pending",
    icon: Clock,
    class: "text-warning bg-warning-muted border-warning-border",
  },
} as const;

// ── Helpers ────────────────────────────────────────────────────────────────

function parseUrlHost(raw: string): string | null {
  try {
    const u = new URL(raw);
    const host = u.port ? `${u.hostname}:${u.port}` : u.hostname;
    const db = u.pathname.replace(/^\//, "");
    return db ? `${host}/${db}` : host;
  } catch {
    return null;
  }
}

function isPgUrl(val: string) {
  return val.startsWith("postgresql://") || val.startsWith("postgres://");
}
function isSupabaseUrl(val: string) {
  return /^https:\/\/[^/]+\.supabase\.co(\/|$)/.test(val.trim());
}
function isMysqlUrl(val: string) {
  return val.startsWith("mysql://");
}

// ── Form state ─────────────────────────────────────────────────────────────

type FormState = {
  name: string;
  description: string;
  dbEngine: DbEngine;
  // postgres / mysql / other
  connectionUrl: string;
  // supabase
  supabaseUrl: string;
  supabaseKey: string;
  // scylladb
  scyllaHosts: string;
  scyllaKeyspace: string;
  scyllaUsername: string;
  scyllaPassword: string;
};

const EMPTY_FORM: FormState = {
  name: "",
  description: "",
  dbEngine: "postgres",
  connectionUrl: "",
  supabaseUrl: "",
  supabaseKey: "",
  scyllaHosts: "",
  scyllaKeyspace: "",
  scyllaUsername: "",
  scyllaPassword: "",
};

function formIsValid(form: FormState): boolean {
  if (!form.name.trim()) return false;
  const connectionUrl = form.connectionUrl.trim();
  switch (form.dbEngine) {
    case "postgres":
      return isPgUrl(form.connectionUrl);
    case "mysql":
      return isMysqlUrl(form.connectionUrl);
    case "supabase":
      return isSupabaseUrl(form.supabaseUrl) && form.supabaseKey.trim() !== "";
    case "scylladb":
      return (
        form.scyllaHosts.trim() !== "" && form.scyllaKeyspace.trim() !== ""
      );
    case "other":
      return connectionUrl !== "";
  }
}

// ── Component ──────────────────────────────────────────────────────────────

export default function ModulesPage() {
  const { modules, addModule, removeModule, updateModule } = useAppStore();
  const [createOpen, setCreateOpen] = useState(false);
  const [form, setForm] = useState<FormState>(EMPTY_FORM);
  const [search, setSearch] = useState("");

  const f = (patch: Partial<FormState>) => setForm((s) => ({ ...s, ...patch }));

  const filtered = search.trim()
    ? modules.filter(
        (m) =>
          m.name.toLowerCase().includes(search.toLowerCase()) ||
          (m.description ?? "").toLowerCase().includes(search.toLowerCase()),
      )
    : modules;

  const handleCreate = () => {
    if (!formIsValid(form)) return;
    const base: Module = {
      id: crypto.randomUUID(),
      name: form.name.trim(),
      description: form.description.trim(),
      type: "client",
      dbEngine: form.dbEngine,
      status: "pending",
      createdAt: new Date().toISOString(),
    };
    const extra: Partial<Module> =
      form.dbEngine === "supabase"
        ? {
            supabaseUrl: form.supabaseUrl.trim(),
            supabaseKey: form.supabaseKey.trim(),
          }
        : form.dbEngine === "scylladb"
          ? {
              scyllaHosts: form.scyllaHosts.trim(),
              scyllaKeyspace: form.scyllaKeyspace.trim(),
              ...(form.scyllaUsername.trim()
                ? { scyllaUsername: form.scyllaUsername.trim() }
                : {}),
              ...(form.scyllaPassword.trim()
                ? { scyllaPassword: form.scyllaPassword.trim() }
                : {}),
            }
          : form.dbEngine === "postgres"
            ? { pgUrl: form.connectionUrl.trim() }
            : { connectionUrl: form.connectionUrl.trim() };

    addModule({ ...base, ...extra });
    setForm(EMPTY_FORM);
    setCreateOpen(false);
    toast.success(`${form.name} added`, {
      description: `${ENGINE_META[form.dbEngine].label} client connected`,
    });
  };

  const handleRemove = (id: string, name: string) => {
    removeModule(id);
    toast.success(`${name} removed`);
  };

  const handleActivate = (id: string, name: string) => {
    updateModule(id, { status: "active" });
    toast.success(`${name} activated`);
  };

  // Connection hint shown on cards
  const getCardHint = (mod: Module): string | null => {
    if (mod.dbEngine === "supabase" && mod.supabaseUrl)
      return parseUrlHost(mod.supabaseUrl);
    if (mod.dbEngine === "scylladb" && mod.scyllaHosts)
      return `${mod.scyllaHosts.split(",")[0].trim()} · ${mod.scyllaKeyspace ?? ""}`;
    if (mod.connectionUrl) return parseUrlHost(mod.connectionUrl);
    if (mod.pgUrl) return parseUrlHost(mod.pgUrl);
    return null;
  };

  // URL validation error for url-based engines
  const urlError = (() => {
    const v = form.connectionUrl.trim();
    if (!v) return null;
    if (form.dbEngine === "postgres" && !isPgUrl(v))
      return "Must start with postgresql:// or postgres://";
    if (form.dbEngine === "mysql" && !isMysqlUrl(v))
      return "Must start with mysql://";
    return null;
  })();

  // Supabase project URL validation error
  const supabaseUrlError = (() => {
    const v = form.supabaseUrl.trim();
    if (!v) return null;
    if (!isSupabaseUrl(v)) return "Must be a valid https://*.supabase.co URL";
    return null;
  })();

  return (
    <div className="flex flex-1 flex-col min-h-0 overflow-auto">
      <PageShell>
        {/* Header */}
        <div className="flex items-start justify-between gap-4 mb-8">
          <div className="space-y-1">
            <div className="flex items-center gap-2.5">
              <h1 className="text-xl font-semibold tracking-tight">Modules</h1>
              <Badge
                variant="outline"
                className="text-caption px-1.5 py-0 h-4 border-highlight-border text-highlight bg-highlight-muted"
              >
                Beta
              </Badge>
            </div>
            <p className="text-sm text-muted-foreground max-w-lg">
              Each module is a database client — connect Athena to additional
              PostgreSQL, Supabase, ScyllaDB, or MySQL instances.
            </p>
          </div>
          <Button
            onClick={() => {
              setForm(EMPTY_FORM);
              setCreateOpen(true);
            }}
            className="shrink-0"
          >
            <Plus className="h-4 w-4" /> Add client
          </Button>
        </div>

        {/* Search */}
        {modules.length > 0 && (
          <div className="mb-4">
            <Input
              placeholder="Search clients…"
              value={search}
              onChange={(e) => setSearch(e.target.value)}
              className="max-w-xs h-8 text-sm"
            />
          </div>
        )}

        {/* Empty state */}
        {modules.length === 0 && (
          <EmptyState
            icon={Layers}
            heading="No database clients yet"
            description="Add your first client to connect Athena to a PostgreSQL, Supabase, ScyllaDB, or MySQL database."
            action={
              <Button
                onClick={() => {
                  setForm(EMPTY_FORM);
                  setCreateOpen(true);
                }}
              >
                <Plus className="h-4 w-4" /> Add client
              </Button>
            }
          />
        )}

        {/* Client grid */}
        {filtered.length > 0 && (
          <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4 mb-8">
            {filtered.map((mod) => {
              const engine = mod.dbEngine ?? "other";
              const meta = ENGINE_META[engine];
              const EngineIcon = meta.icon;
              const status = STATUS_BADGES[mod.status];
              const StatusIcon = status.icon;
              const hint = getCardHint(mod);
              return (
                <ContextMenu key={mod.id}>
                  <ContextMenuTrigger asChild>
                    <div className="group flex flex-col gap-3 rounded-lg border border-border bg-card p-4 hover:border-border-subtle hover:shadow-sm transition-all cursor-default">
                      <div className="flex items-start justify-between gap-2">
                        <div
                          className={`flex h-9 w-9 items-center justify-center rounded-lg ${meta.bg}`}
                        >
                          <EngineIcon className={`h-4 w-4 ${meta.color}`} />
                        </div>
                        <span
                          className={`inline-flex items-center gap-1 rounded-full border px-2 py-0.5 text-caption font-medium ${status.class}`}
                        >
                          <StatusIcon className="h-2.5 w-2.5" />
                          {status.label}
                        </span>
                      </div>
                      <div>
                        <h3 className="text-sm font-medium text-foreground">
                          {mod.name}
                        </h3>
                        {mod.description && (
                          <p className="text-xs text-muted-foreground mt-0.5 line-clamp-2">
                            {mod.description}
                          </p>
                        )}
                      </div>
                      {hint && (
                        <div className="flex items-center gap-1.5 rounded-md bg-muted-card px-2 py-1">
                          <Server className="h-3 w-3 text-muted-foreground-faint shrink-0" />
                          <span className="text-caption font-mono text-muted-foreground truncate">
                            {hint}
                          </span>
                        </div>
                      )}
                      <div className="flex items-center justify-between mt-auto pt-1">
                        <Badge
                          variant="outline"
                          className={`text-tiny px-1.5 ${meta.color} ${meta.border} ${meta.bg}`}
                        >
                          {meta.label}
                        </Badge>
                        <span className="text-caption text-muted-foreground-subtle">
                          {new Date(mod.createdAt).toLocaleDateString()}
                        </span>
                      </div>
                    </div>
                  </ContextMenuTrigger>
                  <ContextMenuContent>
                    {mod.status !== "active" && (
                      <ContextMenuItem
                        onClick={() => handleActivate(mod.id, mod.name)}
                      >
                        <CheckCircle2 className="h-3.5 w-3.5" /> Activate
                      </ContextMenuItem>
                    )}
                    <ContextMenuItem
                      onClick={() => handleRemove(mod.id, mod.name)}
                      className="text-destructive focus:text-destructive"
                    >
                      <Trash2 className="h-3.5 w-3.5" /> Remove
                    </ContextMenuItem>
                  </ContextMenuContent>
                </ContextMenu>
              );
            })}
          </div>
        )}

        {/* Quick-start engine buttons */}
        <div className="mt-4">
          <h2 className="text-sm font-semibold mb-3 text-foreground-subtle">
            Connect a database
          </h2>
          <div className="grid grid-cols-2 sm:grid-cols-5 gap-2">
            {DB_ENGINES.map((engine) => {
              const meta = ENGINE_META[engine];
              const Icon = meta.icon;
              return (
                <button
                  key={engine}
                  onClick={() => {
                    f({
                      dbEngine: engine,
                      connectionUrl: "",
                      supabaseUrl: "",
                      supabaseKey: "",
                      scyllaHosts: "",
                      scyllaKeyspace: "",
                      scyllaUsername: "",
                      scyllaPassword: "",
                    });
                    setCreateOpen(true);
                  }}
                  className={`flex flex-col items-center gap-2 rounded-lg border border-dashed p-4 text-left hover:bg-accent-subtle transition-all group ${meta.border}`}
                >
                  <div
                    className={`flex h-8 w-8 items-center justify-center rounded-md ${meta.bg}`}
                  >
                    <Icon className={`h-4 w-4 ${meta.color}`} />
                  </div>
                  <span className={`text-body-sm font-medium ${meta.color}`}>
                    {meta.label}
                  </span>
                </button>
              );
            })}
          </div>
        </div>
      </PageShell>

      {/* Create Dialog */}
      <Dialog open={createOpen} onOpenChange={setCreateOpen}>
        <DialogContent className="max-w-md">
          <DialogHeader>
            <DialogTitle>Add database client</DialogTitle>
            <DialogDescription>
              Connect Athena to a database by selecting the engine and providing
              connection details.
            </DialogDescription>
          </DialogHeader>

          <div className="space-y-4 py-1">
            {/* Engine picker */}
            <div className="space-y-1.5">
              <label className="text-xs font-medium text-foreground">
                Database engine
              </label>
              <div className="grid grid-cols-5 gap-1.5">
                {DB_ENGINES.map((engine) => {
                  const meta = ENGINE_META[engine];
                  const Icon = meta.icon;
                  const selected = form.dbEngine === engine;
                  return (
                    <button
                      key={engine}
                      onClick={() =>
                        f({
                          dbEngine: engine,
                          connectionUrl: "",
                          supabaseUrl: "",
                          supabaseKey: "",
                          scyllaHosts: "",
                          scyllaKeyspace: "",
                          scyllaUsername: "",
                          scyllaPassword: "",
                        })
                      }
                      className={`flex flex-col items-center gap-1.5 rounded-lg border py-2.5 px-1 text-caption font-medium transition-all ${
                        selected
                          ? `${meta.border} ${meta.bg} ${meta.color}`
                          : "border-border text-muted-foreground hover:text-foreground hover:border-border-subtle"
                      }`}
                    >
                      <Icon className="h-4 w-4" />
                      {meta.label === "PostgreSQL" ? "Postgres" : meta.label}
                    </button>
                  );
                })}
              </div>
            </div>

            {/* Name */}
            <div className="space-y-1.5">
              <label className="text-xs font-medium text-foreground">
                Name <span className="text-destructive">*</span>
              </label>
              <Input
                value={form.name}
                onChange={(e) => f({ name: e.target.value })}
                placeholder={`My ${ENGINE_META[form.dbEngine].label} client`}
                className="text-sm"
                autoFocus
              />
            </div>

            {/* Description */}
            <div className="space-y-1.5">
              <label className="text-xs font-medium text-foreground">
                Description{" "}
                <span className="text-muted-foreground font-normal">
                  (optional)
                </span>
              </label>
              <Input
                value={form.description}
                onChange={(e) => f({ description: e.target.value })}
                placeholder="Production database, staging replica…"
                className="text-sm"
              />
            </div>

            {/* Connection fields — per engine */}
            {(form.dbEngine === "postgres" ||
              form.dbEngine === "mysql" ||
              form.dbEngine === "other") && (
              <div className="space-y-1.5">
                <div className="flex items-center justify-between">
                  <label className="text-xs font-medium text-foreground">
                    Connection URL <span className="text-destructive">*</span>
                  </label>
                  {form.connectionUrl && !urlError && (
                    <span className="text-caption text-muted-foreground font-mono">
                      {parseUrlHost(form.connectionUrl)}
                    </span>
                  )}
                </div>
                <Input
                  type="text"
                  value={form.connectionUrl}
                  onChange={(e) => f({ connectionUrl: e.target.value })}
                  placeholder={
                    form.dbEngine === "postgres"
                      ? "postgresql://user:password@host:5432/db"
                      : form.dbEngine === "mysql"
                        ? "mysql://user:password@host:3306/db"
                        : "driver://user:password@host/db"
                  }
                  className={`text-body-sm font-mono h-7 ${urlError ? "border-destructive focus-visible:ring-ring-destructive-subtle" : ""}`}
                  autoComplete="off"
                  spellCheck={false}
                />
                {urlError && (
                  <p className="text-body-sm text-destructive">{urlError}</p>
                )}
              </div>
            )}

            {form.dbEngine === "supabase" && (
              <div className="space-y-3">
                <div className="space-y-1.5">
                  <div className="flex items-center justify-between">
                    <label className="text-xs font-medium text-foreground">
                      Project URL <span className="text-destructive">*</span>
                    </label>
                    {form.supabaseUrl && !supabaseUrlError && (
                      <span className="text-caption text-muted-foreground font-mono">
                        {parseUrlHost(form.supabaseUrl.trim())}
                      </span>
                    )}
                  </div>
                  <Input
                    type="text"
                    value={form.supabaseUrl}
                    onChange={(e) => f({ supabaseUrl: e.target.value })}
                    placeholder="https://xxxxxxxxxxxx.supabase.co"
                    className={`text-body-sm font-mono h-7 ${supabaseUrlError ? "border-destructive focus-visible:ring-ring-destructive-subtle" : ""}`}
                    autoComplete="off"
                    spellCheck={false}
                  />
                  {supabaseUrlError && (
                    <p className="text-body-sm text-destructive">
                      {supabaseUrlError}
                    </p>
                  )}
                </div>
                <div className="space-y-1.5">
                  <label className="text-xs font-medium text-foreground">
                    Anon / service key{" "}
                    <span className="text-destructive">*</span>
                  </label>
                  <Input
                    type="text"
                    value={form.supabaseKey}
                    onChange={(e) => f({ supabaseKey: e.target.value })}
                    placeholder="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9…"
                    className="text-body-sm font-mono h-7"
                    autoComplete="off"
                    spellCheck={false}
                  />
                </div>
              </div>
            )}

            {form.dbEngine === "scylladb" && (
              <div className="space-y-3">
                <div className="grid grid-cols-2 gap-3">
                  <div className="space-y-1.5">
                    <label className="text-xs font-medium text-foreground">
                      Contact points <span className="text-destructive">*</span>
                    </label>
                    <Input
                      type="text"
                      value={form.scyllaHosts}
                      onChange={(e) => f({ scyllaHosts: e.target.value })}
                      placeholder="host1,host2"
                      className="text-body-sm font-mono h-7"
                    />
                  </div>
                  <div className="space-y-1.5">
                    <label className="text-xs font-medium text-foreground">
                      Keyspace <span className="text-destructive">*</span>
                    </label>
                    <Input
                      type="text"
                      value={form.scyllaKeyspace}
                      onChange={(e) => f({ scyllaKeyspace: e.target.value })}
                      placeholder="my_keyspace"
                      className="text-body-sm font-mono h-7"
                    />
                  </div>
                </div>
                <div className="grid grid-cols-2 gap-3">
                  <div className="space-y-1.5">
                    <label className="text-xs font-medium text-foreground text-muted-foreground">
                      Username
                    </label>
                    <Input
                      type="text"
                      value={form.scyllaUsername}
                      onChange={(e) => f({ scyllaUsername: e.target.value })}
                      placeholder="cassandra"
                      className="text-body-sm font-mono h-7"
                    />
                  </div>
                  <div className="space-y-1.5">
                    <label className="text-xs font-medium text-muted-foreground">
                      Password
                    </label>
                    <Input
                      type="text"
                      value={form.scyllaPassword}
                      onChange={(e) => f({ scyllaPassword: e.target.value })}
                      placeholder="••••••••"
                      className="text-body-sm font-mono h-7"
                    />
                  </div>
                </div>
              </div>
            )}
          </div>

          <DialogFooter>
            <Button variant="outline" onClick={() => setCreateOpen(false)}>
              Cancel
            </Button>
            <Button onClick={handleCreate} disabled={!formIsValid(form)}>
              <Plus className="h-3.5 w-3.5" /> Add client
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </div>
  );
}
