"use client";

import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { Check, Gavel, X } from "lucide-react";
import Link from "next/link";
import { useState } from "react";
import { PageHeader } from "@/components/page-header";
import { StatusPill } from "@/components/status";
import { Badge, Button, EmptyState, Mono, Panel, PageLoader } from "@/components/ui";
import { api } from "@/lib/api";
import type { Approval } from "@/lib/types";
import { can, useAuth } from "@/lib/auth";
import { cn, relativeTime } from "@/lib/utils";

const TABS = ["pending", "approved", "rejected", "expired"] as const;

function ApprovalCard({ approval }: { approval: Approval }) {
  const qc = useQueryClient();
  const { role } = useAuth();
  const [reason, setReason] = useState("");
  const decide = useMutation({
    mutationFn: (approve: boolean) =>
      approve ? api.approve(approval.id, reason) : api.reject(approval.id, reason),
    onSuccess: () => {
      void qc.invalidateQueries({ queryKey: ["approvals"] });
    },
  });
  const pending = approval.status === "pending";

  return (
    <Panel className={cn(pending && "border-warning/25")}>
      <div className="flex items-start justify-between gap-4">
        <div className="flex items-start gap-3">
          <div className="flex h-10 w-10 items-center justify-center rounded-xl border border-warning/30 bg-warning/10 text-warning">
            <Gavel className="h-5 w-5" />
          </div>
          <div>
            <div className="flex items-center gap-2">
              <span className="font-mono text-sm text-fg">{approval.requested_tool}</span>
              {approval.status !== "pending" && <StatusPill status={approval.status} />}
            </div>
            <p className="mt-0.5 text-sm text-muted">{approval.summary}</p>
          </div>
        </div>
        <Link href={`/runs/${approval.run_id}`} className="shrink-0 text-xs text-muted hover:text-fg">
          run <Mono>{approval.run_id.slice(0, 8)}</Mono>
        </Link>
      </div>

      {Object.keys(approval.requested_args ?? {}).length > 0 && (
        <pre className="mt-4 max-h-40 overflow-auto rounded-lg border border-line bg-ink/60 p-3 font-mono text-[12px] text-muted">
          {JSON.stringify(approval.requested_args, null, 2)}
        </pre>
      )}

      <div className="mt-4 flex flex-wrap items-center gap-2 text-xs text-faint">
        <Badge>requested {relativeTime(approval.created_at)}</Badge>
        {approval.expires_at && <Badge>expires {relativeTime(approval.expires_at)}</Badge>}
      </div>

      {pending && can(role, "approve") && (
        <div className="mt-4 flex flex-col gap-2 border-t border-line pt-4 sm:flex-row sm:items-center">
          <input
            value={reason}
            onChange={(e) => setReason(e.target.value)}
            placeholder="Reason (optional)"
            className="h-9 flex-1 rounded-lg border border-line bg-ink/60 px-3 text-sm text-fg placeholder:text-faint focus:border-accent/60 focus-visible:focus-ring"
          />
          <div className="flex gap-2">
            <Button variant="danger" onClick={() => decide.mutate(false)} loading={decide.isPending}>
              <X className="h-4 w-4" /> Reject
            </Button>
            <Button variant="primary" onClick={() => decide.mutate(true)} loading={decide.isPending}>
              <Check className="h-4 w-4" /> Approve
            </Button>
          </div>
        </div>
      )}
      {pending && !can(role, "approve") && (
        <p className="mt-4 border-t border-line pt-4 text-xs text-faint">
          Your role can view but not decide approvals.
        </p>
      )}
    </Panel>
  );
}

export default function ApprovalsPage() {
  const [tab, setTab] = useState<(typeof TABS)[number]>("pending");
  const approvals = useQuery({
    queryKey: ["approvals", tab],
    queryFn: () => api.listApprovals(tab),
    refetchInterval: tab === "pending" ? 4000 : false,
  });

  return (
    <div>
      <PageHeader
        eyebrow="Operate"
        title="Approvals"
        description="Sensitive actions wait here for a human decision before they execute."
      />

      <div className="mb-6 flex gap-1 rounded-xl border border-line bg-surface/50 p-1">
        {TABS.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}
          </button>
        ))}
      </div>

      {approvals.isLoading ? (
        <PageLoader />
      ) : (approvals.data ?? []).length === 0 ? (
        <EmptyState
          icon={<Gavel className="h-8 w-8" />}
          title={`No ${tab} approvals`}
          description={tab === "pending" ? "You're all caught up." : undefined}
        />
      ) : (
        <div className="space-y-4">
          {(approvals.data ?? []).map((a) => (
            <ApprovalCard key={a.id} approval={a} />
          ))}
        </div>
      )}
    </div>
  );
}
