"use client";

import { useCallback, useEffect, useMemo, useState } from "react";
import { AppShell } from "@/components/AppShell";
import {
  Badge,
  Panel,
} from "@/components/ui/Primitives";
import {
  ProposalDiffCard,
  ReviewDecisionBar,
  ReviewNoteField,
  ReviewQueueList,
  ReviewTimeline,
  ReviewWorkflowNav,
} from "@/components/reviews/ReviewWorkflow";
import { approveReviewItem, batchReviewItems, listAgentTimeline, listApprovalQueue, rejectReviewItem } from "@/lib/review-client";
import { toast } from "@/lib/toast";
import type { AgentTimelineItem, ApprovalQueueItem } from "@/lib/types";

export default function ReviewsPage() {
  const [approvalQueue, setApprovalQueue] = useState<ApprovalQueueItem[]>([]);
  const [timeline, setTimeline] = useState<AgentTimelineItem[]>([]);
  const [selectedApprovalId, setSelectedApprovalId] = useState<string | null>(null);
  const [selectedBatchIds, setSelectedBatchIds] = useState<Set<string>>(new Set());
  const [reviewNote, setReviewNote] = useState("");
  const [isSubmitting, setIsSubmitting] = useState(false);
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {
    void (async () => {
      try {
        const [nextQueue, nextTimeline] = await Promise.all([
          listApprovalQueue(),
          listAgentTimeline(),
        ]);
        setApprovalQueue(nextQueue);
        setSelectedApprovalId((current) =>
          current && nextQueue.some((item) => item.id === current) ? current : nextQueue[0]?.id ?? null,
        );
        setTimeline(nextTimeline);
      } catch (err) {
        setError(err instanceof Error ? err.message : "Unable to load review queue");
      }
    })();
  }, []);

  const featuredProposal = useMemo(
    () => approvalQueue.find((item) => item.id === selectedApprovalId) ?? approvalQueue[0] ?? null,
    [approvalQueue, selectedApprovalId],
  );

  const batchMode = selectedBatchIds.size > 0;

  const toggleBatchItem = useCallback((id: string) => {
    setSelectedBatchIds((current) => {
      const next = new Set(current);
      if (next.has(id)) {
        next.delete(id);
      } else {
        next.add(id);
      }
      return next;
    });
  }, []);

  const selectAllForBatch = useCallback(() => {
    setSelectedBatchIds(new Set(approvalQueue.map((item) => item.id)));
  }, [approvalQueue]);

  const clearBatch = useCallback(() => {
    setSelectedBatchIds(new Set());
  }, []);

  const operatorWorkflows = [
    {
      id: "workflow-approvals",
      name: "Approval triage",
      owner: "Operator",
      queueCount: approvalQueue.length,
      sla: "< 4h",
      status: approvalQueue.length > 3 ? "at_risk" : "healthy",
    },
    {
      id: "workflow-agent-activity",
      name: "Agent activity review",
      owner: "Knowledge Ops",
      queueCount: timeline.length,
      sla: "< 1d",
      status: timeline.length > 6 ? "at_risk" : "healthy",
    },
  ] as const;

  async function handleDecision(decision: "approved" | "rejected") {
    if (!featuredProposal) {
      return;
    }

    setIsSubmitting(true);
    const note = reviewNote.trim() || undefined;

    try {
      const updated =
        decision === "approved"
          ? await approveReviewItem(featuredProposal, note)
          : await rejectReviewItem(featuredProposal, note);

      setApprovalQueue((current) => {
        const nextQueue = current.filter((item) => item.id !== featuredProposal.id);
        setSelectedApprovalId((selected) =>
          selected === featuredProposal.id ? nextQueue[0]?.id ?? null : selected,
        );
        return nextQueue;
      });
      setTimeline((current) => [
        {
          id: updated.id,
          actor: updated.owner,
          action: `human ${decision} proposal`,
          timestamp: new Date().toISOString(),
          status: updated.status,
          summary: updated.after ?? updated.title,
        },
        ...current,
      ]);
      setReviewNote("");
      toast.success(`Proposal ${decision}`);
    } catch (err) {
      const msg = err instanceof Error ? err.message : "Unable to update review state";
      setError(msg);
      toast.error(msg);
    } finally {
      setIsSubmitting(false);
    }
  }

  async function handleBatchDecision(decision: "approved" | "rejected") {
    const batchItems = approvalQueue.filter((item) => selectedBatchIds.has(item.id));
    if (batchItems.length === 0) return;

    setIsSubmitting(true);
    const note = reviewNote.trim() || undefined;

    try {
      await batchReviewItems(batchItems, decision, note);

      setApprovalQueue((current) => {
        const nextQueue = current.filter((item) => !selectedBatchIds.has(item.id));
        setSelectedApprovalId(nextQueue[0]?.id ?? null);
        return nextQueue;
      });
      setTimeline((current) => [
        {
          id: `batch-${Date.now()}`,
          actor: "reviewer",
          action: `batch ${decision} ${batchItems.length} proposals`,
          timestamp: new Date().toISOString(),
          status: decision,
          summary: note ?? `${batchItems.length} items ${decision}`,
        },
        ...current,
      ]);
      setSelectedBatchIds(new Set());
      setReviewNote("");
      toast.success(`Batch ${decision}: ${batchItems.length} items`);
    } catch (err) {
      const msg = err instanceof Error ? err.message : "Batch review failed";
      setError(msg);
      toast.error(msg);
    } finally {
      setIsSubmitting(false);
    }
  }

  return (
    <AppShell
      title="Agent review"
      description="Approval queue, proposal comparison, and audit-oriented review surfaces for agent-mediated edits."
      actions={<Badge>Operator workflow shell</Badge>}
    >
      <section style={{ display: "grid", gridTemplateColumns: "minmax(260px, 320px) minmax(0, 1fr)", gap: "var(--nl-space-4)" }}>
        <ReviewWorkflowNav workflows={operatorWorkflows} />

        <Panel>
          <ReviewDecisionBar
            batchMode={batchMode}
            selectedCount={selectedBatchIds.size}
            isSubmitting={isSubmitting}
            onSelectAll={selectAllForBatch}
            onClear={clearBatch}
            onBatchDecision={(decision) => void handleBatchDecision(decision)}
          />
          {error ? <div style={{ color: "var(--nl-text-secondary)" }}>{error}</div> : null}

          <ReviewQueueList
            items={approvalQueue}
            batchMode={batchMode}
            selectedBatchIds={selectedBatchIds}
            selectedApprovalId={featuredProposal?.id ?? null}
            onSelectItem={(id) => batchMode ? toggleBatchItem(id) : setSelectedApprovalId(id)}
          />
        </Panel>
      </section>

      <ReviewNoteField value={reviewNote} onChange={setReviewNote} />

      {featuredProposal && !batchMode ? (
        <ProposalDiffCard
          proposal={featuredProposal}
          onApprove={() => void handleDecision("approved")}
          onReject={() => void handleDecision("rejected")}
          isSubmitting={isSubmitting}
        />
      ) : null}

      <ReviewTimeline items={timeline} />
    </AppShell>
  );
}
