"use client";

import { useMemo, useState } from "react";
import { api, ConfigCatalogItem } from "@/lib/api";
import { useApi } from "@/hooks/useApi";
import { useLocale } from "@/i18n/LocaleProvider";
import {
  Button,
  Card,
  Dialog,
  ErrorState,
  Field,
  IconChip,
  SkeletonTable,
  StatusBadge,
  PageHeader,
  Sheet,
} from "@/components/ui";

export default function Page() {
  const { t } = useLocale();
  const catalog = useApi<ConfigCatalogItem[]>(api.configCatalog, []);
  const [editing, setEditing] = useState<ConfigCatalogItem | null>(null);
  const [confirmDelete, setConfirmDelete] = useState<ConfigCatalogItem | null>(null);

  // Group the fixed catalog by provider so related credentials sit together.
  const groups = useMemo(() => {
    const by = new Map<string, ConfigCatalogItem[]>();
    for (const item of catalog.data ?? []) {
      const list = by.get(item.provider) ?? [];
      list.push(item);
      by.set(item.provider, list);
    }
    return Array.from(by.entries());
  }, [catalog.data]);

  return (
    <div>
      <PageHeader titleKey="nav.apiKeys" />

      <Card className="mb-4 flex items-start gap-3">
        <IconChip tone="warning">{"\u{1F510}"}</IconChip>
        <p className="text-sm text-muted">{t("keys.notice")}</p>
      </Card>

      {catalog.loading ? (
        <SkeletonTable rows={6} />
      ) : catalog.error ? (
        <ErrorState onRetry={catalog.reload} />
      ) : (
        <div className="space-y-6">
          {groups.map(([provider, items]) => (
            <div key={provider}>
              <h2 className="mb-2 text-sm font-semibold">{provider}</h2>
              <div className="card divide-y divide-line">
                {items.map((item) => (
                  <KeyRow
                    key={item.key}
                    item={item}
                    onSet={() => setEditing(item)}
                    onDelete={() => setConfirmDelete(item)}
                  />
                ))}
              </div>
            </div>
          ))}
        </div>
      )}

      {editing && (
        <KeyForm
          item={editing}
          onClose={() => setEditing(null)}
          onSaved={() => {
            setEditing(null);
            catalog.reload();
          }}
        />
      )}

      <Dialog
        open={confirmDelete !== null}
        onClose={() => setConfirmDelete(null)}
        icon={"\u{1F5D1}"}
        tone="danger"
        title={t("keys.deleteTitle")}
        description={t("keys.deleteBody")}
        actions={
          <>
            <Button
              variant="danger"
              className="flex-1"
              onClick={async () => {
                if (confirmDelete) await api.deleteConfig(confirmDelete.key);
                setConfirmDelete(null);
                catalog.reload();
              }}
            >
              {t("keys.deleteYes")}
            </Button>
            <Button onClick={() => setConfirmDelete(null)}>{t("common.cancel")}</Button>
          </>
        }
      />
    </div>
  );
}

/* --------------------------------------------------------------------- row */

function KeyRow({
  item,
  onSet,
  onDelete,
}: {
  item: ConfigCatalogItem;
  onSet: () => void;
  onDelete: () => void;
}) {
  const { t } = useLocale();
  const [revealed, setRevealed] = useState<string | null>(null);
  const [busy, setBusy] = useState(false);

  const reveal = async () => {
    setBusy(true);
    try {
      const { value } = await api.revealConfig(item.key);
      setRevealed(value);
    } finally {
      setBusy(false);
    }
  };

  return (
    <div className="flex flex-wrap items-center gap-4 p-4">
      <IconChip tone={item.configured ? (item.secret ? "warning" : "info") : "neutral"}>
        {item.secret ? "\u{1F510}" : "⚙"}
      </IconChip>

      <div className="min-w-[180px] flex-1">
        <div className="font-mono text-sm font-medium">{item.key}</div>
        <div className="text-xs text-muted">{item.description}</div>
        {revealed !== null && (
          <div className="mt-1 break-all font-mono text-xs text-brand">{revealed}</div>
        )}
      </div>

      {item.configured ? (
        <StatusBadge tone={item.secret ? "warning" : "info"}>
          {t("keys.configured")}
        </StatusBadge>
      ) : (
        <StatusBadge tone="neutral">{t("keys.notSet")}</StatusBadge>
      )}

      <div className="flex gap-2">
        {item.configured && item.secret ? (
          revealed === null ? (
            <Button disabled={busy} onClick={reveal}>
              {busy ? t("common.loading") : t("keys.reveal")}
            </Button>
          ) : (
            <Button onClick={() => setRevealed(null)}>{t("keys.hide")}</Button>
          )
        ) : null}

        {/* Secondary, not primary: a vault of many rows would otherwise be a wall of yellow. */}
        <Button variant="secondary" onClick={onSet}>
          {item.configured ? t("keys.replace") : t("keys.set")}
        </Button>

        {item.configured && (
          <Button variant="danger" onClick={onDelete}>
            {t("keys.delete")}
          </Button>
        )}
      </div>
    </div>
  );
}

/* -------------------------------------------------------------------- form */

function KeyForm({
  item,
  onClose,
  onSaved,
}: {
  item: ConfigCatalogItem;
  onClose: () => void;
  onSaved: () => void;
}) {
  const { t } = useLocale();
  const [value, setValue] = useState("");
  const [busy, setBusy] = useState(false);
  const [error, setError] = useState<string | null>(null);

  const submit = async (e: React.FormEvent) => {
    e.preventDefault();
    setBusy(true);
    setError(null);
    try {
      // The key and its secrecy are fixed by the catalog; only the value is set here.
      await api.putConfig({ key: item.key, value, secret: item.secret });
      onSaved();
    } catch (err) {
      setError(err instanceof Error ? err.message : t("common.error"));
    } finally {
      setBusy(false);
    }
  };

  return (
    <Sheet open onClose={onClose} title={item.configured ? t("keys.replaceTitle") : t("keys.setTitle")}>
      <form onSubmit={submit} className="space-y-4">
        <div className="card p-4">
          <div className="font-mono text-sm font-medium">{item.key}</div>
          <div className="text-xs text-muted">
            {item.provider} {"·"} {item.description}
          </div>
        </div>

        <Field
          label={item.configured ? t("keys.newValue") : t("keys.valueLabel")}
          required
          type={item.secret ? "password" : "text"}
          value={value}
          onChange={(e) => setValue(e.target.value)}
          placeholder={item.secret ? "••••••••••••" : ""}
          className="font-mono"
        />
        {item.configured && item.secret && (
          <p className="text-xs text-muted">{t("keys.valueReplaceHint")}</p>
        )}

        {error && (
          <div className="tint tone-danger rounded-card border p-3 text-sm">{error}</div>
        )}

        <div className="flex gap-3">
          <Button variant="primary" type="submit" disabled={busy || !value} className="flex-1">
            {busy ? t("common.loading") : t("keys.save")}
          </Button>
          <Button type="button" onClick={onClose}>
            {t("common.cancel")}
          </Button>
        </div>
      </form>
    </Sheet>
  );
}
