"use client";

import { useState, useCallback, useEffect, useMemo } from "react";
import { StemeDBClient, type QuarantineResponse, type QuarantinedAssertion, ApiError } from "@/lib/api";
import type { PanelState } from "@/lib/types";
import { QUARANTINE_FETCH_LIMIT } from "@/lib/constants";
import { ConfirmationDialog } from "@/components/shared/confirmation-dialog";
import { ErrorState } from "@/components/shared/error-state";
import { QuarantineMetrics } from "./quarantine-metrics";
import { QuarantineList } from "./quarantine-list";
import { QuarantineLoadingSkeleton } from "./quarantine-loading-skeleton";
import { QuarantineEmptyState } from "./quarantine-empty-state";

type ConfirmAction = {
  type: "restore" | "delete";
  hash: string;
} | null;

// Transform backend response to component format
function toQuarantinedAssertion(
  event: QuarantineResponse["quarantined"][0]
): QuarantinedAssertion {
  return {
    hash: event.hash,
    subject: "Unknown", // Backend doesn't provide this in list view
    predicate: "Unknown",
    value: event.reason_description,
    reason: event.reason_description,
    quarantined_at: event.timestamp,
    quarantined_by: event.agent_id ?? "system",
    can_restore: !event.reviewed,
  };
}

export function QuarantinePanel() {
  const [state, setState] = useState<PanelState<QuarantineResponse>>({ status: "idle" });
  const [confirmAction, setConfirmAction] = useState<ConfirmAction>(null);
  const [isProcessing, setIsProcessing] = useState(false);

  // Transform backend response to component-compatible format
  const assertions = useMemo(() => {
    if (state.status !== "success") return [];
    return state.data.quarantined.map(toQuarantinedAssertion);
  }, [state]);

  const fetchData = useCallback(async () => {
    setState({ status: "loading" });
    try {
      const client = new StemeDBClient();
      const data = await client.quarantine(QUARANTINE_FETCH_LIMIT, 0);
      setState({ status: "success", data });
    } catch (err) {
      // 404 means no quarantined items - treat as empty success, not error
      if (err instanceof ApiError && err.status === 404) {
        setState({
          status: "success",
          data: { quarantined: [], count: 0, pending_count: 0 },
        });
        return;
      }
      const message =
        err instanceof ApiError
          ? err.userMessage
          : err instanceof Error
            ? err.message
            : "Unknown error";
      setState({ status: "error", error: message });
    }
  }, []);

  // Load data on mount
  useEffect(() => {
    fetchData();
  }, [fetchData]);

  const handleRestore = useCallback((hash: string) => {
    setConfirmAction({ type: "restore", hash });
    return Promise.resolve();
  }, []);

  const handleDelete = useCallback((hash: string) => {
    setConfirmAction({ type: "delete", hash });
    return Promise.resolve();
  }, []);

  const executeConfirmedAction = useCallback(async () => {
    if (!confirmAction) return;

    setIsProcessing(true);
    try {
      const client = new StemeDBClient();
      if (confirmAction.type === "restore") {
        await client.restoreFromQuarantine(confirmAction.hash);
      } else {
        await client.deleteFromQuarantine(confirmAction.hash);
      }
      setConfirmAction(null);
      // Refresh the list
      await fetchData();
    } catch (err) {
      const message = err instanceof Error ? err.message : "Unknown error";
      // Keep the dialog open with the error
      setState({ status: "error", error: message });
    } finally {
      setIsProcessing(false);
    }
  }, [confirmAction, fetchData]);

  const handleRetry = useCallback(() => {
    fetchData();
  }, [fetchData]);

  return (
    <div className="space-y-6">
      {/* Header */}
      <div className="rounded-lg border border-border bg-card p-6">
        <h2 className="text-lg font-medium text-card-foreground mb-2">
          Flagged Assertions
        </h2>
        <p className="text-sm text-muted-foreground">
          Review, restore, or permanently delete assertions that failed
          validation or were flagged by the Content Defense Layer.
        </p>
      </div>

      {/* Content */}
      <div className="rounded-lg border border-border bg-card p-6">
        {state.status === "idle" && <QuarantineLoadingSkeleton />}
        {state.status === "loading" && <QuarantineLoadingSkeleton />}

        {state.status === "error" && (
          <ErrorState
            title="Failed to Load Quarantine"
            error={state.error}
            onRetry={handleRetry}
          />
        )}

        {state.status === "success" && (
          <div className="space-y-6">
            {assertions.length === 0 ? (
              <QuarantineEmptyState hasFilter={false} />
            ) : (
              <>
                <QuarantineMetrics
                  totalCount={state.data.count}
                  assertions={assertions}
                />
                <QuarantineList
                  assertions={assertions}
                  onRestore={handleRestore}
                  onDelete={handleDelete}
                />
              </>
            )}
          </div>
        )}
      </div>

      {/* Confirmation Dialog */}
      <ConfirmationDialog
        isOpen={confirmAction !== null}
        title={
          confirmAction?.type === "restore"
            ? "Restore Assertion"
            : "Delete Assertion"
        }
        description={
          confirmAction?.type === "restore"
            ? "Are you sure you want to restore this assertion? It will be moved back to the active assertion store."
            : "Are you sure you want to permanently delete this assertion? This action cannot be undone."
        }
        confirmLabel={confirmAction?.type === "restore" ? "Restore" : "Delete"}
        confirmVariant={
          confirmAction?.type === "restore" ? "default" : "destructive"
        }
        isLoading={isProcessing}
        onConfirm={executeConfirmedAction}
        onCancel={() => setConfirmAction(null)}
      />
    </div>
  );
}
