"use client";

import { useState, useMemo, useEffect, useCallback } from "react";
import { useAppStore, type AuthFieldMapping } from "@/app/lib/store";
import { useSettings } from "@/app/lib/settings";
import {
  fetchTables,
  fetchColumns,
  type TableMetadata,
  type ColumnMetadata,
  ApiError,
} from "@/app/lib/api";
import { PageShell } from "./ui/page-shell";
import { Button } from "./ui/button";
import { Badge } from "./ui/badge";
import { Input } from "./ui/input";
import {
  Users,
  ShieldCheck,
  Save,
  ChevronDown,
  CheckCircle2,
  AlertCircle,
  Loader2,
  Lock,
  Mail,
  Hash,
  Image,
  Calendar,
  Clock,
  Tag,
} from "lucide-react";
import { toast } from "sonner";

type FieldDef = {
  key: keyof AuthFieldMapping;
  label: string;
  icon: React.ElementType;
  description: string;
  required: boolean;
};

const FIELD_DEFS: FieldDef[] = [
  {
    key: "id",
    label: "User ID",
    icon: Hash,
    description: "Primary key / UUID of the user",
    required: true,
  },
  {
    key: "email",
    label: "Email",
    icon: Mail,
    description: "User's email address",
    required: true,
  },
  {
    key: "displayName",
    label: "Display name",
    icon: Users,
    description: "Human-readable name shown in the UI",
    required: false,
  },
  {
    key: "avatarUrl",
    label: "Avatar URL",
    icon: Image,
    description: "URL of the user's profile picture",
    required: false,
  },
  {
    key: "role",
    label: "Role",
    icon: Tag,
    description: "Permission role (e.g. admin, user, viewer)",
    required: false,
  },
  {
    key: "createdAt",
    label: "Created at",
    icon: Calendar,
    description: "Timestamp when the account was created",
    required: false,
  },
  {
    key: "lastSignIn",
    label: "Last sign in",
    icon: Clock,
    description: "Timestamp of the most recent login",
    required: false,
  },
];

type Props = {
  clientName: string | null;
};

export default function AuthConfigPage({ clientName }: Props) {
  const { baseUrl, apiKey } = useSettings();
  const ctx = useMemo(() => ({ baseUrl, apiKey }), [baseUrl, apiKey]);
  const { authConfig, setAuthConfig } = useAppStore();

  const [tables, setTables] = useState<TableMetadata[]>([]);
  const [columns, setColumns] = useState<ColumnMetadata[]>([]);
  const [tablesLoading, setTablesLoading] = useState(false);
  const [columnsLoading, setColumnsLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);

  // Local form state
  const [usersTable, setUsersTable] = useState(authConfig.usersTable);
  const [usersSchema, setUsersSchema] = useState(authConfig.usersSchema);
  const [authProvider, setAuthProvider] = useState(authConfig.authProvider);
  const [fieldMapping, setFieldMapping] = useState(authConfig.fieldMapping);

  const loadTables = useCallback(async () => {
    if (!clientName) return;
    setTablesLoading(true);
    setError(null);
    try {
      const rows = await fetchTables(ctx, clientName);
      setTables(rows);
      // Auto-detect users table
      const candidates = ["users", "auth.users", "user", "accounts", "members"];
      const found = rows.find((t) =>
        candidates.some(
          (c) =>
            t.table_name.toLowerCase() === c ||
            `${t.table_schema}.${t.table_name}`.toLowerCase() === c,
        ),
      );
      if (found && !authConfig.usersTable) {
        setUsersTable(found.table_name);
        setUsersSchema(found.table_schema ?? "public");
      }
    } catch (err) {
      setError(err instanceof ApiError ? err.message : "Failed to load tables");
    } finally {
      setTablesLoading(false);
    }
  }, [clientName, ctx, authConfig.usersTable]);

  useEffect(() => {
    loadTables();
  }, [loadTables]);

  const loadColumns = useCallback(async () => {
    if (!usersTable || !clientName) {
      setColumns([]);
      return;
    }
    setColumnsLoading(true);
    try {
      const cols = await fetchColumns(
        ctx,
        usersTable,
        clientName,
        undefined,
        0,
        true,
        usersSchema || undefined,
      );
      setColumns(cols);
    } catch {
      setColumns([]);
    } finally {
      setColumnsLoading(false);
    }
  }, [usersTable, clientName, ctx]);

  useEffect(() => {
    loadColumns();
  }, [loadColumns]);

  const columnOptions = columns.map((c) => c.column_name);

  const handleSave = () => {
    setAuthConfig({ usersTable, usersSchema, authProvider, fieldMapping });
    toast.success("Auth configuration saved", {
      description: `Users table set to ${usersSchema}.${usersTable}`,
    });
  };

  const hasChanges =
    usersTable !== authConfig.usersTable ||
    usersSchema !== authConfig.usersSchema ||
    authProvider !== authConfig.authProvider ||
    JSON.stringify(fieldMapping) !== JSON.stringify(authConfig.fieldMapping);

  // Completion score
  const filledRequired = FIELD_DEFS.filter(
    (f) =>
      f.required &&
      fieldMapping[f.key] &&
      columnOptions.includes(fieldMapping[f.key]),
  ).length;
  const totalRequired = FIELD_DEFS.filter((f) => f.required).length;
  const isConfigured = filledRequired === totalRequired && !!usersTable;

  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">
              <ShieldCheck className="h-5 w-5 text-primary" />
              <h1 className="text-xl font-semibold tracking-tight">
                Auth configuration
              </h1>
              {isConfigured ? (
                <Badge
                  variant="outline"
                  className="text-caption border-success-border text-success bg-success-subtle"
                >
                  <CheckCircle2 className="h-2.5 w-2.5 mr-1" /> Configured
                </Badge>
              ) : (
                <Badge
                  variant="outline"
                  className="text-caption border-warning-border text-warning bg-warning-subtle"
                >
                  Setup required
                </Badge>
              )}
            </div>
            <p className="text-sm text-muted-foreground max-w-lg">
              Tell Athena which database table holds your users and how to map
              its columns to standard auth fields. This drives the
              Authentication view and user lookups across the gateway.
            </p>
          </div>
          {hasChanges && (
            <Button onClick={handleSave} size="sm">
              <Save className="h-3.5 w-3.5" /> Save
            </Button>
          )}
        </div>

        {error && (
          <div className="flex items-center gap-2 rounded-lg border border-destructive-border bg-destructive-subtle px-4 py-3 text-sm text-destructive mb-6">
            <AlertCircle className="h-4 w-4 shrink-0" /> {error}
          </div>
        )}

        {/* Step 1: Auth provider */}
        <section className="rounded-lg border border-border bg-card overflow-hidden mb-5">
          <div className="border-b border-border px-6 py-4">
            <h2 className="text-sm font-semibold flex items-center gap-2">
              <Lock className="h-3.5 w-3.5 text-muted-foreground" /> Auth
              provider
            </h2>
            <p className="text-xs text-muted-foreground mt-0.5">
              Which auth system populates your users table?
            </p>
          </div>
          <div className="px-6 py-5">
            <div className="grid grid-cols-3 gap-3">
              {(["supabase", "better-auth", "custom"] as const).map((p) => {
                const labels = {
                  supabase: "Supabase Auth",
                  "better-auth": "Better Auth",
                  custom: "Custom / Other",
                };
                return (
                  <button
                    key={p}
                    onClick={() => setAuthProvider(p)}
                    className={`flex items-center justify-center gap-2 rounded-lg border p-3 text-sm font-medium transition-all ${
                      authProvider === p
                        ? "border-primary bg-primary-subtle text-primary"
                        : "border-border text-muted-foreground hover:border-border-subtle hover:text-foreground hover:bg-accent-subtle"
                    }`}
                  >
                    {labels[p]}
                  </button>
                );
              })}
            </div>
            {authProvider === "supabase" && (
              <p className="text-xs text-muted-foreground mt-3 bg-muted/40 rounded-md px-3 py-2">
                Supabase Auth users live in the{" "}
                <code className="font-mono bg-background px-1 rounded">
                  auth.users
                </code>{" "}
                schema. Set Users table to{" "}
                <code className="font-mono bg-background px-1 rounded">
                  users
                </code>{" "}
                and schema to{" "}
                <code className="font-mono bg-background px-1 rounded">
                  auth
                </code>
                .
              </p>
            )}
          </div>
        </section>

        {/* Step 2: Users table */}
        <section className="rounded-lg border border-border bg-card overflow-hidden mb-5">
          <div className="border-b border-border px-6 py-4">
            <h2 className="text-sm font-semibold flex items-center gap-2">
              <Users className="h-3.5 w-3.5 text-muted-foreground" /> Users
              table
            </h2>
            <p className="text-xs text-muted-foreground mt-0.5">
              Select the table that contains user records.
            </p>
          </div>
          <div className="px-6 py-5 grid grid-cols-[auto_1fr] gap-4 items-end">
            <div className="space-y-1.5">
              <label className="text-xs text-muted-foreground font-medium">
                Schema
              </label>
              <Input
                value={usersSchema}
                onChange={(e) => setUsersSchema(e.target.value)}
                placeholder="public"
                className="w-28 h-8 text-sm font-mono"
              />
            </div>
            <div className="space-y-1.5">
              <label className="text-xs text-muted-foreground font-medium">
                Table
              </label>
              {tablesLoading ? (
                <div className="flex items-center gap-2 h-8 text-xs text-muted-foreground">
                  <Loader2 className="h-3.5 w-3.5 animate-spin" /> Loading
                  tables…
                </div>
              ) : (
                <div className="relative">
                  <select
                    value={usersTable}
                    onChange={(e) => {
                      const t = tables.find(
                        (x) => x.table_name === e.target.value,
                      );
                      setUsersTable(e.target.value);
                      if (t) setUsersSchema(t.table_schema ?? "public");
                    }}
                    className="h-8 w-full max-w-xs rounded-md border border-border bg-background px-3 pr-8 text-sm text-foreground appearance-none cursor-pointer"
                  >
                    <option value="">Select a table…</option>
                    {tables.map((t) => (
                      <option
                        key={`${t.table_schema}.${t.table_name}`}
                        value={t.table_name}
                      >
                        {t.table_schema !== "public"
                          ? `${t.table_schema}.`
                          : ""}
                        {t.table_name}
                      </option>
                    ))}
                  </select>
                  <ChevronDown className="pointer-events-none absolute right-2.5 top-1/2 -translate-y-1/2 h-3.5 w-3.5 text-muted-foreground" />
                </div>
              )}
            </div>
          </div>
        </section>

        {/* Step 3: Field mapping */}
        <section className="rounded-lg border border-border bg-card overflow-hidden mb-6">
          <div className="border-b border-border px-6 py-4">
            <div className="flex items-center justify-between">
              <div>
                <h2 className="text-sm font-semibold">Field mapping</h2>
                <p className="text-xs text-muted-foreground mt-0.5">
                  Map table columns to standard auth fields. Required fields
                  must be mapped.
                </p>
              </div>
              {usersTable && (
                <div className="flex items-center gap-1.5 text-xs text-muted-foreground">
                  {columnsLoading ? (
                    <Loader2 className="h-3 w-3 animate-spin" />
                  ) : (
                    <>
                      <span className="font-mono text-foreground">
                        {columnOptions.length}
                      </span>{" "}
                      columns detected
                    </>
                  )}
                </div>
              )}
            </div>
          </div>
          <div className="divide-y divide-border">
            {FIELD_DEFS.map(
              ({ key, label, icon: Icon, description, required }) => {
                const mapped = fieldMapping[key];
                const valid =
                  !required || (mapped && columnOptions.includes(mapped));
                return (
                  <div
                    key={key}
                    className="grid grid-cols-[2fr_3fr] gap-4 items-center px-6 py-3.5"
                  >
                    <div className="flex items-start gap-3">
                      <div className="mt-0.5 flex h-7 w-7 shrink-0 items-center justify-center rounded-md bg-muted-card">
                        <Icon className="h-3.5 w-3.5 text-muted-foreground" />
                      </div>
                      <div>
                        <div className="flex items-center gap-1.5">
                          <p className="text-sm font-medium">{label}</p>
                          {required && (
                            <span className="text-destructive text-xs">*</span>
                          )}
                        </div>
                        <p className="text-xs text-muted-foreground">
                          {description}
                        </p>
                      </div>
                    </div>
                    <div className="flex items-center gap-2">
                      {columnsLoading ? (
                        <div className="h-8 w-full max-w-[200px] rounded-md border border-border bg-muted/30 animate-pulse" />
                      ) : (
                        <div className="relative flex-1 max-w-[200px]">
                          <select
                            value={mapped || ""}
                            onChange={(e) =>
                              setFieldMapping((prev: AuthFieldMapping) => ({
                                ...prev,
                                [key]: e.target.value,
                              }))
                            }
                            className={`h-8 w-full rounded-md border bg-background px-3 pr-8 text-sm appearance-none cursor-pointer font-mono ${
                              valid
                                ? "border-border text-foreground"
                                : "border-warning/50 text-warning"
                            }`}
                          >
                            <option value="">— not mapped —</option>
                            {columnOptions.map((col) => (
                              <option key={col} value={col}>
                                {col}
                              </option>
                            ))}
                          </select>
                          <ChevronDown className="pointer-events-none absolute right-2.5 top-1/2 -translate-y-1/2 h-3.5 w-3.5 text-muted-foreground" />
                        </div>
                      )}
                      {valid && mapped && (
                        <CheckCircle2 className="h-4 w-4 text-success shrink-0" />
                      )}
                    </div>
                  </div>
                );
              },
            )}
          </div>
        </section>

        {/* Progress summary */}
        <div className="rounded-lg border border-border bg-card px-6 py-4 flex items-center gap-4">
          <div className="flex-1">
            <div className="flex items-center justify-between mb-1.5">
              <p className="text-xs font-medium text-foreground">
                Configuration progress
              </p>
              <span className="text-xs text-muted-foreground">
                {filledRequired}/{totalRequired} required fields mapped
              </span>
            </div>
            <div className="h-1.5 w-full rounded-full bg-muted overflow-hidden">
              <div
                className="h-full rounded-full bg-primary transition-all duration-300"
                style={{ width: `${(filledRequired / totalRequired) * 100}%` }}
              />
            </div>
          </div>
          {hasChanges && (
            <Button onClick={handleSave} size="sm" className="shrink-0">
              <Save className="h-3.5 w-3.5" /> Save
            </Button>
          )}
        </div>
      </PageShell>
    </div>
  );
}
