"use client";

import { useState } from "react";
import { api } from "@/lib/api";
import { MUTATE_API_KEY } from "@/lib/api-endpoints";
import { extractApiError } from "@/lib/error";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogBody,
  DialogFooter,
} from "@/components/ui/dialog";
import { toast } from "sonner";
import { ApiKey, ApiKeyScope, ApiKeyResponse } from "@/lib/types/api-key";
import { ApiKeyCreatedDialog } from "./ApiKeyCreatedDialog";

interface AddApiKeyModalProps {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  onSaved?: () => void;
  existingNames?: string[];
}

const SCOPE_OPTIONS: { value: ApiKeyScope; label: string; description: string }[] = [
  {
    value: "public:read",
    label: "public:read",
    description: "Baca endpoint publik (event groups, peserta, status, dll.)",
  },
  {
    value: "internal:write",
    label: "internal:write",
    description: "Tulis endpoint internal (status kepesertaan, sidang-snapshot, dll.)",
  },
];

export function AddApiKeyModal({ open, onOpenChange, onSaved, existingNames = [] }: AddApiKeyModalProps) {
  const [name, setName] = useState("");
  const [scopes, setScopes] = useState<ApiKeyScope[]>(["public:read"]);
  const [isSubmitting, setIsSubmitting] = useState(false);
  const [createdKey, setCreatedKey] = useState<string | null>(null);
  const [createdName, setCreatedName] = useState("");
  const [nameError, setNameError] = useState<string | null>(null);

  const reset = () => {
    setName("");
    setScopes(["public:read"]);
    setCreatedKey(null);
    setCreatedName("");
    setNameError(null);
  };

  const handleClose = (nextOpen: boolean) => {
    if (!nextOpen) reset();
    onOpenChange(nextOpen);
  };

  const toggleScope = (scope: ApiKeyScope) => {
    setScopes((prev) =>
      prev.includes(scope) ? prev.filter((s) => s !== scope) : [...prev, scope]
    );
  };

  const handleNameChange = (value: string) => {
    setName(value);
    if (value.trim() && existingNames.some((n) => n.toLowerCase() === value.trim().toLowerCase())) {
      setNameError("Nama API key sudah digunakan.");
    } else {
      setNameError(null);
    }
  };

  const handleSubmit = async () => {
    if (!name.trim()) {
      toast.warning("Nama API key harus diisi.");
      return;
    }
    if (scopes.length === 0) {
      toast.warning("Pilih minimal 1 scope.");
      return;
    }
    if (existingNames.some((n) => n.toLowerCase() === name.trim().toLowerCase())) {
      setNameError("Nama API key sudah digunakan.");
      return;
    }

    setIsSubmitting(true);
    try {
      const res = await api.post<ApiKeyResponse>(MUTATE_API_KEY(), {
        name: name.trim(),
        scopes,
      });
      setCreatedKey(res.key);
      setCreatedName(res.data.name);
      toast.success("API key berhasil dibuat.");
      onSaved?.();
    } catch (err: any) {
      const errMsg = extractApiError(err, "Gagal membuat API key.");
      if (errMsg.toLowerCase().includes("sudah ada") || errMsg.toLowerCase().includes("already exists")) {
        setNameError(errMsg);
      } else {
        toast.error(errMsg);
      }
    } finally {
      setIsSubmitting(false);
    }
  };

  return (
    <>
      <Dialog open={open && !createdKey} onOpenChange={handleClose}>
        <DialogContent>
          <DialogHeader>
            <DialogTitle>Tambah API Key</DialogTitle>
            <p className="text-sm text-muted-foreground">
              Buat API key baru untuk klien (mis. muscab-super-apps, hipmi_web, atau
              integrasi eksternal). Key hanya ditampilkan sekali.
            </p>
          </DialogHeader>

          <DialogBody className="space-y-4">
            <div className="space-y-2">
              <label className="text-sm font-medium">Nama</label>
              <Input
                placeholder="Contoh: Muscab Super Apps"
                value={name}
                onChange={(e) => handleNameChange(e.target.value)}
                className={nameError ? "border-red-500 focus-visible:ring-red-500" : ""}
              />
              {nameError ? (
                <p className="text-xs text-red-500">{nameError}</p>
              ) : (
                <p className="text-xs text-muted-foreground">
                  Nama akan ditampilkan di log audit dan halaman manajemen. Tidak bisa
                  duplikat.
                </p>
              )}
            </div>

            <div className="space-y-2">
              <label className="text-sm font-medium">Scope</label>
              <div className="space-y-2">
                {SCOPE_OPTIONS.map((opt) => (
                  <label
                    key={opt.value}
                    className="flex items-start gap-3 p-3 border border-slate-200 rounded-md cursor-pointer hover:bg-slate-50"
                  >
                    <input
                      type="checkbox"
                      className="w-4 h-4 mt-0.5"
                      checked={scopes.includes(opt.value)}
                      onChange={() => toggleScope(opt.value)}
                    />
                    <div>
                      <div className="text-sm font-medium font-mono">{opt.label}</div>
                      <div className="text-xs text-muted-foreground">
                        {opt.description}
                      </div>
                    </div>
                  </label>
                ))}
              </div>
            </div>
          </DialogBody>

          <DialogFooter>
            <Button variant="outline" onClick={() => handleClose(false)} disabled={isSubmitting}>
              Batal
            </Button>
            <Button onClick={handleSubmit} disabled={isSubmitting || !!nameError}>
              {isSubmitting ? "Membuat..." : "Buat API Key"}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      <ApiKeyCreatedDialog
        open={!!createdKey}
        onOpenChange={(next) => {
          if (!next) {
            setCreatedKey(null);
            handleClose(false);
          }
        }}
        title="API Key Berhasil Dibuat"
        description={`Key untuk "${createdName}" telah dibuat. Salin dan simpan sekarang — tidak akan ditampilkan lagi.`}
        plaintextKey={createdKey ?? ""}
      />
    </>
  );
}
