"use client";

import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { Copy, KeyRound, Plus, Users } from "lucide-react";
import { useState } from "react";
import { Modal } from "@/components/modal";
import { PageHeader } from "@/components/page-header";
import { Badge, Button, Field, Input, Mono, Panel, PageLoader, Select } from "@/components/ui";
import { api } from "@/lib/api";
import type { Role } from "@/lib/types";
import { can, useAuth } from "@/lib/auth";
import { cn, relativeTime } from "@/lib/utils";

const ROLES: Role[] = ["owner", "admin", "builder", "operator", "viewer"];

function Members() {
  const { role } = useAuth();
  const qc = useQueryClient();
  const members = useQuery({ queryKey: ["members"], queryFn: api.listMembers });
  const [email, setEmail] = useState("");
  const [inviteRole, setInviteRole] = useState<Role>("viewer");
  const [open, setOpen] = useState(false);
  const manage = can(role, "members");

  return (
    <Panel className="p-0">
      <div className="flex items-center justify-between px-5 py-4">
        <div className="flex items-center gap-2">
          <Users className="h-4 w-4 text-accent" />
          <span className="font-display font-semibold text-fg">Members</span>
        </div>
        {manage && (
          <Button size="sm" variant="primary" onClick={() => setOpen(true)}>
            <Plus className="h-4 w-4" /> Invite
          </Button>
        )}
      </div>
      <div className="divide-y divide-line border-t border-line">
        {members.isLoading ? (
          <PageLoader />
        ) : (
          (members.data ?? []).map((m) => (
            <div key={m.id} className="flex items-center gap-3 px-5 py-3">
              <span className="flex h-8 w-8 items-center justify-center rounded-full bg-accent/15 font-mono text-xs text-accent">
                {(m.name || m.email)[0]?.toUpperCase()}
              </span>
              <div className="min-w-0">
                <div className="truncate text-sm text-fg">{m.name || m.email}</div>
                <div className="truncate text-xs text-faint">{m.email}</div>
              </div>
              <div className="flex-1" />
              {manage ? (
                <Select
                  value={m.role}
                  onChange={async (e) => {
                    await api.setRole(m.id, e.target.value as Role);
                    await qc.invalidateQueries({ queryKey: ["members"] });
                  }}
                  className="h-8 w-32"
                >
                  {ROLES.map((r) => (
                    <option key={r} value={r}>
                      {r}
                    </option>
                  ))}
                </Select>
              ) : (
                <Badge tone="accent">{m.role}</Badge>
              )}
            </div>
          ))
        )}
      </div>

      <Modal
        open={open}
        onClose={() => setOpen(false)}
        title="Invite a member"
        description="They'll join this workspace with the role you pick."
      >
        <form
          className="space-y-4"
          onSubmit={async (e) => {
            e.preventDefault();
            await api.invite(email, inviteRole);
            await qc.invalidateQueries({ queryKey: ["members"] });
            setEmail("");
            setOpen(false);
          }}
        >
          <Field label="Email">
            <Input
              type="email"
              required
              value={email}
              onChange={(e) => setEmail(e.target.value)}
              placeholder="teammate@company.com"
            />
          </Field>
          <Field label="Role">
            <Select value={inviteRole} onChange={(e) => setInviteRole(e.target.value as Role)}>
              {ROLES.map((r) => (
                <option key={r} value={r}>
                  {r}
                </option>
              ))}
            </Select>
          </Field>
          <div className="flex justify-end">
            <Button variant="primary" type="submit">
              Send invite
            </Button>
          </div>
        </form>
      </Modal>
    </Panel>
  );
}

function ApiKeys() {
  const { role } = useAuth();
  const qc = useQueryClient();
  const keys = useQuery({ queryKey: ["api-keys"], queryFn: api.listApiKeys });
  const [open, setOpen] = useState(false);
  const [name, setName] = useState("");
  const [keyRole, setKeyRole] = useState<Role>("operator");
  const [plaintext, setPlaintext] = useState<string | null>(null);
  const manage = can(role, "members");

  return (
    <Panel className="p-0">
      <div className="flex items-center justify-between px-5 py-4">
        <div className="flex items-center gap-2">
          <KeyRound className="h-4 w-4 text-accent" />
          <span className="font-display font-semibold text-fg">API keys</span>
        </div>
        {manage && (
          <Button size="sm" variant="primary" onClick={() => setOpen(true)}>
            <Plus className="h-4 w-4" /> New key
          </Button>
        )}
      </div>
      <div className="divide-y divide-line border-t border-line">
        {(keys.data ?? []).length === 0 ? (
          <p className="px-5 py-6 text-center text-sm text-muted">No API keys.</p>
        ) : (
          (keys.data ?? []).map((k) => (
            <div key={k.id} className="flex items-center gap-3 px-5 py-3">
              <Mono className="text-accent">{k.prefix}…</Mono>
              <span className="text-sm text-fg">{k.name}</span>
              {k.revoked_at && <Badge tone="danger">revoked</Badge>}
              <div className="flex-1" />
              <span className="hidden text-xs text-faint sm:block">
                {k.last_used_at ? `used ${relativeTime(k.last_used_at)}` : "never used"}
              </span>
              {manage && !k.revoked_at && (
                <button
                  onClick={async () => {
                    await api.revokeApiKey(k.id);
                    await qc.invalidateQueries({ queryKey: ["api-keys"] });
                  }}
                  className="text-xs text-danger hover:underline"
                >
                  revoke
                </button>
              )}
            </div>
          ))
        )}
      </div>

      <Modal
        open={open}
        onClose={() => {
          setOpen(false);
          setPlaintext(null);
        }}
        title="Create API key"
        description="Programmatic, workspace-scoped access."
      >
        {plaintext ? (
          <div className="space-y-3">
            <p className="text-sm text-muted">Copy this key now. It's shown only once.</p>
            <div className="flex items-center gap-2 rounded-lg border border-accent/30 bg-accent/5 px-3 py-2 font-mono text-xs text-accent">
              <span className="flex-1 truncate">{plaintext}</span>
              <button onClick={() => navigator.clipboard.writeText(plaintext)}>
                <Copy className="h-3.5 w-3.5" />
              </button>
            </div>
            <div className="flex justify-end">
              <Button
                variant="primary"
                onClick={() => {
                  setOpen(false);
                  setPlaintext(null);
                }}
              >
                Done
              </Button>
            </div>
          </div>
        ) : (
          <form
            className="space-y-4"
            onSubmit={async (e) => {
              e.preventDefault();
              const res = await api.createApiKey(name, keyRole);
              await qc.invalidateQueries({ queryKey: ["api-keys"] });
              setPlaintext(res.plaintext);
              setName("");
            }}
          >
            <Field label="Name">
              <Input
                required
                value={name}
                onChange={(e) => setName(e.target.value)}
                placeholder="CI pipeline"
              />
            </Field>
            <Field label="Scopes (from role)">
              <Select value={keyRole} onChange={(e) => setKeyRole(e.target.value as Role)}>
                {ROLES.map((r) => (
                  <option key={r} value={r}>
                    {r}
                  </option>
                ))}
              </Select>
            </Field>
            <div className="flex justify-end">
              <Button variant="primary" type="submit">
                Create key
              </Button>
            </div>
          </form>
        )}
      </Modal>
    </Panel>
  );
}

export default function AdminPage() {
  const [tab, setTab] = useState<"members" | "keys">("members");
  return (
    <div>
      <PageHeader
        eyebrow="Govern"
        title="Admin"
        description="Members, roles, and programmatic access keys."
      />
      <div className="mb-6 flex gap-1 rounded-xl border border-line bg-surface/50 p-1 sm:w-72">
        {(["members", "keys"] as const).map((t) => (
          <button
            key={t}
            onClick={() => setTab(t)}
            className={cn(
              "flex-1 rounded-lg px-3 py-1.5 text-sm font-medium capitalize transition-colors",
              tab === t ? "bg-surface-2 text-fg" : "text-muted hover:text-fg"
            )}
          >
            {t === "keys" ? "API keys" : "Members"}
          </button>
        ))}
      </div>
      {tab === "members" ? <Members /> : <ApiKeys />}
    </div>
  );
}
