"use client";

import { useState, useCallback, useEffect, useMemo } from "react";
import {
  StemeDBClient,
  type ListSourcesResponse,
  type SourceRecordDto,
  ApiError,
} from "@/lib/api";
import type { PanelState } from "@/lib/types";
import { SOURCE_FETCH_LIMIT } from "@/lib/constants";
import { RotateCcw, Eye, Ban } from "lucide-react";
import { Button } from "@/components/ui/button";
import { ErrorState } from "@/components/shared/error-state";
import { ConfirmationDialog } from "@/components/shared/confirmation-dialog";

function BlockedSourceRow({
  source,
  onRestore,
  onViewImpact,
}: {
  source: SourceRecordDto;
  onRestore: (source: SourceRecordDto) => void;
  onViewImpact: (source: SourceRecordDto) => void;
}) {
  const blockedDate = new Date(source.updated_at).toLocaleDateString();

  return (
    <div className="rounded-lg border border-border p-4 hover:bg-accent/5 transition-colors">
      <div className="flex items-start justify-between gap-4">
        <div className="flex-1 min-w-0">
          <div className="flex items-center gap-2">
            <span className="inline-flex items-center rounded-full border px-2 py-0.5 text-xs font-medium bg-red-500/10 text-red-500 border-red-500/20">
              blocked
            </span>
            <span className="font-medium text-foreground truncate">
              {source.label}
            </span>
          </div>
          <div className="mt-2 flex items-center gap-4 text-sm text-muted-foreground">
            <span className="font-mono text-xs" title={source.hash}>
              {source.hash.slice(0, 12)}...
            </span>
            <span>Blocked: {blockedDate}</span>
          </div>
        </div>

        <div className="flex items-center gap-2 shrink-0">
          <Button
            variant="outline"
            size="sm"
            onClick={() => onViewImpact(source)}
          >
            <Eye className="h-4 w-4 mr-1" />
            View Impact
          </Button>
          <Button
            variant="outline"
            size="sm"
            onClick={() => onRestore(source)}
          >
            <RotateCcw className="h-4 w-4 mr-1" />
            Restore
          </Button>
        </div>
      </div>
    </div>
  );
}

function BlockedSourcesEmptyState() {
  return (
    <div className="text-center py-12">
      <Ban className="h-12 w-12 mx-auto text-muted-foreground/50 mb-4" />
      <h3 className="text-lg font-medium text-foreground mb-2">
        No Blocked Sources
      </h3>
      <p className="text-sm text-muted-foreground max-w-sm mx-auto">
        Sources that you block from the Sources page will appear here.
        Blocked sources are excluded from all query results.
      </p>
    </div>
  );
}

export function BlockedSourcesPanel() {
  const [state, setState] = useState<PanelState<ListSourcesResponse>>({
    status: "idle",
  });
  const [restoreSource, setRestoreSource] = useState<SourceRecordDto | null>(null);
  const [isProcessing, setIsProcessing] = useState(false);

  const fetchData = useCallback(async () => {
    setState({ status: "loading" });
    try {
      const client = new StemeDBClient();
      const data = await client.listSources(SOURCE_FETCH_LIMIT);
      setState({ status: "success", data });
    } catch (err) {
      if (err instanceof ApiError && err.status === 404) {
        setState({
          status: "success",
          data: { sources: [], count: 0 },
        });
        return;
      }
      const message =
        err instanceof ApiError
          ? err.userMessage
          : err instanceof Error
            ? err.message
            : "Unknown error";
      setState({ status: "error", error: message });
    }
  }, []);

  useEffect(() => {
    fetchData();
  }, [fetchData]);

  const blockedSources = useMemo(() => {
    if (state.status !== "success") return [];
    return state.data.sources.filter((s) => s.status === "quarantined");
  }, [state]);

  const handleRestore = useCallback((source: SourceRecordDto) => {
    setRestoreSource(source);
  }, []);

  const handleViewImpact = useCallback(async (source: SourceRecordDto) => {
    // Open in new tab or show inline - for now just log
    const client = new StemeDBClient();
    try {
      const impact = await client.getSourceImpact(source.hash);
      // Could show a sheet here, but for simplicity just alert
      alert(`${impact.assertion_count} assertions affected by this source`);
    } catch (err) {
      console.error("Failed to load impact:", err);
    }
  }, []);

  const handleRestoreConfirm = useCallback(async () => {
    if (!restoreSource) return;

    setIsProcessing(true);
    try {
      const client = new StemeDBClient();
      await client.restoreSource(restoreSource.hash);
      setRestoreSource(null);
      await fetchData();
    } catch (err) {
      console.error("Failed to restore source:", err);
    } finally {
      setIsProcessing(false);
    }
  }, [restoreSource, fetchData]);

  if (state.status === "idle" || state.status === "loading") {
    return (
      <div className="space-y-3">
        {[1, 2, 3].map((i) => (
          <div
            key={i}
            className="h-20 rounded-lg border border-border bg-muted/30 animate-pulse"
          />
        ))}
      </div>
    );
  }

  if (state.status === "error") {
    return (
      <ErrorState
        title="Failed to Load Blocked Sources"
        error={state.error}
        onRetry={fetchData}
      />
    );
  }

  return (
    <>
      {blockedSources.length === 0 ? (
        <BlockedSourcesEmptyState />
      ) : (
        <div className="space-y-3">
          {blockedSources.map((source) => (
            <BlockedSourceRow
              key={source.hash}
              source={source}
              onRestore={handleRestore}
              onViewImpact={handleViewImpact}
            />
          ))}
        </div>
      )}

      <ConfirmationDialog
        isOpen={restoreSource !== null}
        title="Restore Source"
        description={`Are you sure you want to restore "${restoreSource?.label}"? Its assertions will be included in query results again.`}
        confirmLabel="Restore"
        confirmVariant="default"
        isLoading={isProcessing}
        onConfirm={handleRestoreConfirm}
        onCancel={() => setRestoreSource(null)}
      />
    </>
  );
}
