"use client";

import { useState, useEffect, useCallback } from "react";
import {
  Card,
  Button,
  Badge,
  Input,
  Toggle,
  Select,
  CardSkeleton,
  ConfirmModal,
  Modal,
} from "@/shared/components";
import { useCopyToClipboard } from "@/shared/hooks/useCopyToClipboard";
import { format } from "date-fns";

export default function KeysPage() {
  const [currentUser, setCurrentUser] = useState(null);
  const [keys, setKeys] = useState([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState("");
  const [confirmState, setConfirmState] = useState(null);
  const [createOpen, setCreateOpen] = useState(false);
  const [newName, setNewName] = useState("");
  const [newComment, setNewComment] = useState("");
  const [selectedUserId, setSelectedUserId] = useState("");
  const [newKeyPreview, setNewKeyPreview] = useState(null);
  const [creating, setCreating] = useState(false);
  const [users, setUsers] = useState([]);
  const [globalSettings, setGlobalSettings] = useState(null);
  const { copied, copy } = useCopyToClipboard(2000);

  const isAdmin = currentUser?.role === "admin";

  // Fetch current user
  useEffect(() => {
    fetch("/api/auth/me")
      .then((r) => r.json())
      .then((data) => setCurrentUser(data.user))
      .catch(() => {});
  }, []);

  // Fetch users list (admin only)
  useEffect(() => {
    if (!isAdmin) return;
    fetch("/api/users")
      .then((r) => r.json())
      .then((data) => setUsers(data.users || []))
      .catch(() => {});
  }, [isAdmin]);

  useEffect(() => {
    fetch("/api/settings")
      .then((r) => r.json())
      .then((data) => setGlobalSettings(data))
      .catch(() => {});
  }, []);

  const fetchKeys = useCallback(async () => {
    try {
      setError("");
      const url = selectedUserId
        ? `/api/keys?userId=${encodeURIComponent(selectedUserId)}`
        : "/api/keys";
      const res = await fetch(url);
      if (!res.ok) {
        const data = await res.json();
        throw new Error(data.error || "Failed to fetch keys");
      }
      const data = await res.json();
      setKeys(data.keys || []);
    } catch (err) {
      setError(err.message || "An error occurred");
    } finally {
      setLoading(false);
    }
  }, [selectedUserId]);

  useEffect(() => {
    if (currentUser) {
      setLoading(true);
      fetchKeys();
    }
  }, [fetchKeys, currentUser]);

  const handleCreate = async () => {
    if (!newName.trim()) return;
    setCreating(true);
    try {
      const body = { name: newName.trim() };
      if (newComment.trim()) body.comment = newComment.trim();
      if (selectedUserId) body.userId = selectedUserId;
      const res = await fetch("/api/keys", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(body),
      });
      if (!res.ok) {
        const data = await res.json();
        throw new Error(data.error || "Failed to create key");
      }
      const data = await res.json();
      setNewKeyPreview(data);
      setNewName("");
      setNewComment("");
      await fetchKeys();
    } catch (err) {
      setError(err.message);
    } finally {
      setCreating(false);
    }
  };

  const handleToggle = async (key) => {
    try {
      const res = await fetch(`/api/keys/${key.id}`, {
        method: "PUT",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ isActive: !key.isActive }),
      });
      if (!res.ok) throw new Error("Failed to update key");
      await fetchKeys();
    } catch (err) {
      setError(err.message);
    }
  };

  const handleDelete = (key) => {
    setConfirmState({
      title: "Delete API Key",
      message: `Delete key "${key.name}"? Requests using this key will stop working.`,
      variant: "danger",
      onConfirm: async () => {
        setConfirmState(null);
        try {
          const res = await fetch(`/api/keys/${key.id}`, { method: "DELETE" });
          if (!res.ok) {
            const data = await res.json();
            throw new Error(data.error || "Failed to delete key");
          }
          await fetchKeys();
        } catch (err) {
          setError(err.message);
        }
      },
    });
  };

  const handlePatchKey = async (keyId, updates) => {
    try {
      const res = await fetch(`/api/keys/${keyId}`, {
        method: "PATCH",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(updates),
      });
      if (!res.ok) throw new Error("Failed to update key settings");
      await fetchKeys();
    } catch (err) {
      setError(err.message);
    }
  };

  const closeCreate = () => {
    setCreateOpen(false);
    setNewKeyPreview(null);
    setNewName("");
    setNewComment("");
  };

  const userById = {};
  if (users) {
    for (const u of users) userById[u.id] = u;
  }

  if (loading) {
    return (
      <div className="flex min-w-0 flex-col gap-6 px-1 sm:px-0">
        <CardSkeleton />
        <CardSkeleton />
      </div>
    );
  }

  if (error && keys.length === 0) {
    return (
      <div className="flex min-w-0 flex-col gap-6 px-1 sm:px-0">
        <div className="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
          <div className="min-w-0">
            <h1 className="text-2xl font-semibold">API Keys</h1>
            <p className="text-sm text-text-muted mt-1">
              Create and manage API keys for your endpoints
            </p>
          </div>
        </div>
        <Card>
          <div className="text-center py-12">
            <p className="text-red-500 mb-4">{error}</p>
            <Button variant="outline" onClick={fetchKeys}>
              Retry
            </Button>
          </div>
        </Card>
      </div>
    );
  }

  return (
    <div className="flex min-w-0 flex-col gap-6 px-1 sm:px-0">
      {/* Header */}
      <div className="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
        <div className="min-w-0">
          <h1 className="text-2xl font-semibold">API Keys</h1>
          <p className="text-sm text-text-muted mt-1">
            Manage your API keys for endpoint access
          </p>
        </div>
        <div className="flex items-center gap-3">
          {isAdmin && (
            <Select
              value={selectedUserId}
              onChange={(e) => setSelectedUserId(e.target.value)}
              options={[
                { value: "", label: "My Keys" },
                ...users.map((u) => ({
                  value: u.id,
                  label: u.username,
                })),
              ]}
              placeholder="My Keys"
              className="min-w-[180px]"
            />
          )}
          <Button
            icon="add"
            onClick={() => {
              setNewKeyPreview(null);
              setCreateOpen(true);
            }}
          >
            Create Key
          </Button>
        </div>
      </div>

      {/* Error banner (non-blocking) */}
      {error && keys.length > 0 && (
        <Card padding="sm" className="border-red-500/30 bg-red-500/5">
          <p className="text-sm text-red-500">{error}</p>
        </Card>
      )}

      {/* Keys List */}
      {keys.length === 0 ? (
        <Card>
          <div className="text-center py-12">
            <div className="inline-flex items-center justify-center w-16 h-16 rounded-full bg-primary/10 text-primary mb-4">
              <span className="material-symbols-outlined text-[32px]">vpn_key</span>
            </div>
            <p className="text-text-main font-medium mb-1">No API keys yet</p>
            <p className="text-sm text-text-muted mb-4">
              Create an API key to start making requests through the endpoint
            </p>
            <Button
              variant="outline"
              icon="add"
              onClick={() => {
                setNewKeyPreview(null);
                setCreateOpen(true);
              }}
            >
              Create Your First Key
            </Button>
          </div>
        </Card>
      ) : (
        <div className="flex flex-col gap-4" data-testid="keys-table">
          {keys.map((key) => (
            <Card key={key.id} padding="sm" className="group">
              <div className="flex min-w-0 flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
                <div className="flex min-w-0 flex-1 items-start gap-3 sm:items-center">
                  <div className="size-8 rounded-lg bg-primary/10 flex items-center justify-center shrink-0">
                    <span className="material-symbols-outlined text-primary text-[18px]">
                      vpn_key
                    </span>
                  </div>
                  <div className="min-w-0 flex-1">
                    <div className="flex items-center gap-2 flex-wrap">
                      <span className="font-medium text-sm text-text-main truncate">
                        {key.name}
                      </span>
                      <Badge
                        variant={key.isActive ? "success" : "error"}
                        size="sm"
                        dot
                      >
                        {key.isActive ? "Active" : "Disabled"}
                      </Badge>
                    </div>
                    {isAdmin && key.userId && userById[key.userId] && (
                      <p className="text-xs text-text-muted mt-0.5">
                        Owner: <span className="font-medium">{userById[key.userId].username}</span>
                      </p>
                    )}
                    <p className="text-xs text-text-muted mt-0.5">
                      Created {format(new Date(key.createdAt), "MMM d, yyyy")}
                    </p>
                    {key.comment && (
                      <p className="text-xs text-text-muted italic mt-0.5">
                        {key.comment}
                      </p>
                    )}
                    <p className="text-xs text-text-muted font-mono mt-0.5 truncate max-w-[280px]">
                      {key.key}
                    </p>
                  </div>
                </div>

                {/* RTK/Caveman Settings */}
                <div className="flex items-center gap-3 shrink-0 flex-wrap">
                  <Select
                    value={key.rtkEnabled === null ? "" : key.rtkEnabled ? "on" : "off"}
                    onChange={(e) => {
                      const val = e.target.value === "" ? null : e.target.value === "on";
                      handlePatchKey(key.id, { rtkEnabled: val });
                    }}
                    placeholder={globalSettings ? `Use Global (${globalSettings.rtkEnabled !== false ? "On" : "Off"})` : "Use Global"}
                    options={[
                      { value: "", label: `Use Global${globalSettings ? ` (${globalSettings.rtkEnabled !== false ? "On" : "Off"})` : ""}` },
                      { value: "on", label: "Enabled" },
                      { value: "off", label: "Disabled" },
                    ]}
                    className="min-w-[140px]"
                    selectClassName="!py-1.5 !text-xs"
                    title="RTK: Reduce input tokens for git/grep/ls/tree/logs"
                  />
                  <Select
                    value={key.cavemanEnabled === null ? "" : key.cavemanEnabled ? "on" : "off"}
                    onChange={(e) => {
                      const val = e.target.value === "" ? null : e.target.value === "on";
                      handlePatchKey(key.id, { cavemanEnabled: val });
                    }}
                    placeholder={globalSettings ? `Use Global (${globalSettings.cavemanEnabled ? "On" : "Off"})` : "Use Global"}
                    options={[
                      { value: "", label: `Use Global${globalSettings ? ` (${globalSettings.cavemanEnabled ? "On" : "Off"})` : ""}` },
                      { value: "on", label: "Enabled" },
                      { value: "off", label: "Disabled" },
                    ]}
                    className="min-w-[140px]"
                    selectClassName="!py-1.5 !text-xs"
                    title="Caveman: Compress LLM output tokens"
                  />
                  {(key.cavemanEnabled === true || (key.cavemanEnabled === null && globalSettings?.cavemanEnabled)) && (
                    <Select
                      value={key.cavemanLevel ?? ""}
                      onChange={(e) => {
                        handlePatchKey(key.id, { cavemanLevel: e.target.value || null });
                      }}
                      placeholder={globalSettings?.cavemanLevel ? `Use Global (${globalSettings.cavemanLevel})` : "Use Global (full)"}
                      options={[
                        { value: "", label: `Use Global${globalSettings?.cavemanLevel ? ` (${globalSettings.cavemanLevel})` : " (full)"}` },
                        { value: "lite", label: "Lite" },
                        { value: "full", label: "Full" },
                        { value: "ultra", label: "Ultra" },
                      ]}
                      className="min-w-[120px]"
                      selectClassName="!py-1.5 !text-xs"
                      title="Caveman compression level"
                    />
                  )}
                </div>

                {/* Actions */}
                <div className="flex items-center gap-2 shrink-0">
                  <Toggle
                    checked={key.isActive}
                    onChange={() => handleToggle(key)}
                    size="sm"
                  />
                  {isAdmin && key.comment !== undefined && (
                    <Button
                      size="sm"
                      variant="ghost"
                      icon="edit_note"
                      title="Edit comment"
                      onClick={() => {
                        setNewName(key.name);
                        setNewComment(key.comment || "");
                        setSelectedUserId(key.userId || "");
                        setNewKeyPreview(key);
                        setCreateOpen(true);
                      }}
                    />
                  )}
                  <Button
                    size="sm"
                    variant="ghost"
                    icon="content_copy"
                    title="Copy key"
                    onClick={() => copy(key.key)}
                  >
                    {copied ? "Copied" : "Copy"}
                  </Button>
                  <Button
                    size="sm"
                    variant="danger"
                    icon="delete"
                    onClick={() => handleDelete(key)}
                    data-testid={`delete-key-btn-${key.id}`}
                  >
                    Delete
                  </Button>
                </div>
              </div>
            </Card>
          ))}
        </div>
      )}

      {/* Create Key Modal */}
      <Modal
        isOpen={createOpen}
        onClose={closeCreate}
        title={newKeyPreview && !newKeyPreview.key ? "Edit API Key" : newKeyPreview ? "Key Created" : "Create API Key"}
        size="sm"
        footer={
          newKeyPreview && newKeyPreview.key ? (
            <Button variant="primary" onClick={closeCreate}>
              Done
            </Button>
          ) : (
            <>
              <Button variant="ghost" onClick={closeCreate} disabled={creating}>
                Cancel
              </Button>
              <Button
                variant="primary"
                onClick={handleCreate}
                loading={creating}
                disabled={!newName.trim()}
              >
                Create
              </Button>
            </>
          )
        }
      >
        {newKeyPreview && newKeyPreview.key ? (
          <div className="flex flex-col gap-4">
            <p className="text-sm text-text-muted">
              Your API key has been created. Copy it now — you won&apos;t be able
              to see it again.
            </p>
            <Card.Section>
              <code className="text-sm font-mono break-all text-text-main">
                {newKeyPreview.key}
              </code>
            </Card.Section>
            <Button
              variant="outline"
              icon="content_copy"
              fullWidth
              onClick={() => copy(newKeyPreview.key)}
            >
              {copied ? "Copied" : "Copy Key"}
            </Button>
          </div>
        ) : (
          <div className="flex flex-col gap-4">
            <Input
              label="Key Name"
              placeholder="e.g. Claude Code, Cursor"
              value={newName}
              onChange={(e) => setNewName(e.target.value)}
              required
              hint="A label to help you identify this key"
              autoFocus
            />
            {isAdmin && users.length > 0 && (
              <Select
                label="Assign to User"
                value={selectedUserId}
                onChange={(e) => setSelectedUserId(e.target.value)}
                options={[
                  { value: "", label: "Select a user (optional)" },
                  ...users.map((u) => ({
                    value: u.id,
                    label: u.username,
                  })),
                ]}
                placeholder="Select a user (optional)"
                hint="Leave empty to create for yourself"
              />
            )}
            <Input
              label="Comment (optional)"
              placeholder="e.g. Production server, Testing"
              value={newComment}
              onChange={(e) => setNewComment(e.target.value)}
              hint="Notes to help you remember this key's purpose"
            />
          </div>
        )}
      </Modal>

      {/* Confirm Delete Modal */}
      <ConfirmModal
        isOpen={!!confirmState}
        onClose={() => setConfirmState(null)}
        onConfirm={confirmState?.onConfirm}
        title={confirmState?.title || "Confirm"}
        message={confirmState?.message}
        variant={confirmState?.variant || "danger"}
      />
    </div>
  );
}
