import { useState, useCallback } from "react";
import { ChevronDown, ChevronRight, Undo2 } from "lucide-react";
import { Button } from "@/components/ui/button";
import { trpc } from "@/lib/trpc";
import type { ChangeSet } from "@codewalk-district/shared";

interface ChangeSetBannerProps {
  changeSet: ChangeSet;
  onDismiss: () => void;
}

const MODE_LABELS: Record<string, string> = {
  plan: "phases",
  detail: "tasks",
  refine: "pages",
};

export function ChangeSetBanner({ changeSet, onDismiss }: ChangeSetBannerProps) {
  const [expanded, setExpanded] = useState(false);
  const [conflicts, setConflicts] = useState<string[] | null>(null);

  const detailQuery = trpc.getChangeSet.useQuery(
    { id: changeSet.id },
    { enabled: expanded },
  );

  const revertMutation = trpc.revertChangeSet.useMutation({
    onSuccess: (result) => {
      if (!result.success && "conflicts" in result) {
        setConflicts(result.conflicts);
      } else {
        setConflicts(null);
      }
    },
  });

  const handleRevert = useCallback(
    (force?: boolean) => {
      revertMutation.mutate({ id: changeSet.id, force });
    },
    [changeSet.id, revertMutation],
  );

  const entries = detailQuery.data?.entries ?? [];
  const entityLabel = MODE_LABELS[changeSet.mode] ?? "entities";
  const isReverted = changeSet.status === "reverted";

  return (
    <div className="rounded-lg border border-border bg-card p-3 space-y-2">
      <div className="flex items-center justify-between gap-2">
        <div className="flex items-center gap-2 min-w-0">
          <button
            className="flex items-center gap-1 text-sm font-medium hover:text-foreground/80"
            onClick={() => setExpanded(!expanded)}
          >
            {expanded ? (
              <ChevronDown className="h-3.5 w-3.5 shrink-0" />
            ) : (
              <ChevronRight className="h-3.5 w-3.5 shrink-0" />
            )}
            {changeSet.summary ??
              `Agent ${isReverted ? "reverted" : "applied"} ${entityLabel}`}
          </button>
          {isReverted && (
            <span className="text-xs text-muted-foreground italic">
              (reverted)
            </span>
          )}
        </div>
        <div className="flex gap-1.5 shrink-0">
          {!isReverted && (
            <Button
              variant="outline"
              size="sm"
              onClick={() => handleRevert()}
              disabled={revertMutation.isPending}
              className="gap-1"
            >
              <Undo2 className="h-3 w-3" />
              {revertMutation.isPending ? "Reverting..." : "Revert"}
            </Button>
          )}
          <Button variant="ghost" size="sm" onClick={onDismiss}>
            Dismiss
          </Button>
        </div>
      </div>

      {conflicts && (
        <div className="rounded border border-status-warning-border bg-status-warning-bg p-2 space-y-2">
          <p className="text-xs font-medium text-status-warning-fg">
            Conflicts detected:
          </p>
          <ul className="text-xs text-status-warning-fg list-disc pl-4 space-y-0.5">
            {conflicts.map((c, i) => (
              <li key={i}>{c}</li>
            ))}
          </ul>
          <Button
            variant="outline"
            size="sm"
            onClick={() => {
              setConflicts(null);
              handleRevert(true);
            }}
            disabled={revertMutation.isPending}
          >
            Force Revert
          </Button>
        </div>
      )}

      {expanded && (
        <div className="pl-5 space-y-1 text-xs text-muted-foreground">
          {detailQuery.isLoading && <p>Loading entries...</p>}
          {entries.map((entry) => (
            <div key={entry.id} className="flex items-center gap-2">
              <span className="font-mono">
                {entry.action === "create" ? "+" : entry.action === "delete" ? "-" : "~"}
              </span>
              <span>
                {entry.entityType}
                {entry.newState && (() => {
                  try {
                    const parsed = JSON.parse(entry.newState);
                    return parsed.name || parsed.title ? `: ${parsed.name || parsed.title}` : "";
                  } catch { return ""; }
                })()}
              </span>
            </div>
          ))}
          {entries.length === 0 && !detailQuery.isLoading && (
            <p>No entries</p>
          )}
        </div>
      )}
    </div>
  );
}
