"use client";

import { useEffect, useState } from "react";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { Loader2 } from "lucide-react";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { apiPost } from "@/lib/api/client";

const SESSIONS_QUERY_KEY = ["mission-control", "sessions"] as const;

type PanelAction = "pause" | "resume" | "graceful-kill" | "force-kill";
type KillConfirmationState = "graceful" | "force" | null;

interface PanelActionResult {
  nextStatus: string;
}

export interface PanelControlsProps {
  sessionId: string;
  // eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents
  status: "active" | "paused" | "killed" | string;
  onStatusChange?: (newStatus: string) => void;
}

function getErrorMessage(error: unknown): string {
  if (error instanceof Error && error.message.trim().length > 0) {
    return error.message;
  }

  return "Failed to update agent session.";
}

export function PanelControls({
  sessionId,
  status,
  onStatusChange,
}: PanelControlsProps): React.JSX.Element {
  const queryClient = useQueryClient();
  const [errorMessage, setErrorMessage] = useState<string | null>(null);
  const [confirmingKill, setConfirmingKill] = useState<KillConfirmationState>(null);

  useEffect(() => {
    setErrorMessage(null);
    setConfirmingKill(null);
  }, [sessionId]);

  const controlMutation = useMutation({
    mutationFn: async (action: PanelAction): Promise<PanelActionResult> => {
      switch (action) {
        case "pause":
          await apiPost<{ message: string }>(
            `/api/mission-control/sessions/${encodeURIComponent(sessionId)}/pause`
          );
          return { nextStatus: "paused" };
        case "resume":
          await apiPost<{ message: string }>(
            `/api/mission-control/sessions/${encodeURIComponent(sessionId)}/resume`
          );
          return { nextStatus: "active" };
        case "graceful-kill":
          await apiPost<{ message: string }>(
            `/api/mission-control/sessions/${encodeURIComponent(sessionId)}/kill`,
            { force: false }
          );
          return { nextStatus: "killed" };
        case "force-kill":
          await apiPost<{ message: string }>(
            `/api/mission-control/sessions/${encodeURIComponent(sessionId)}/kill`,
            { force: true }
          );
          return { nextStatus: "killed" };
      }
    },
    onSuccess: ({ nextStatus }): void => {
      setErrorMessage(null);
      setConfirmingKill(null);
      onStatusChange?.(nextStatus);
      void queryClient.invalidateQueries({ queryKey: SESSIONS_QUERY_KEY });
    },
    onError: (error: unknown): void => {
      setConfirmingKill(null);
      setErrorMessage(getErrorMessage(error));
    },
  });

  const normalizedStatus = status.toLowerCase();
  const isKilled = normalizedStatus === "killed";
  const isBusy = controlMutation.isPending;
  const pendingAction = isBusy ? controlMutation.variables : undefined;

  const submitAction = (action: PanelAction): void => {
    setErrorMessage(null);
    controlMutation.mutate(action);
  };

  const pauseDisabled = isBusy || normalizedStatus === "paused" || isKilled;
  const resumeDisabled = isBusy || normalizedStatus === "active" || isKilled;
  const gracefulKillDisabled = isBusy || isKilled;
  const forceKillDisabled = isBusy || isKilled;

  return (
    <div className="flex flex-col items-end gap-2">
      <div className="flex flex-wrap items-center justify-end gap-1.5">
        <Button
          type="button"
          size="sm"
          variant="secondary"
          onClick={() => {
            submitAction("pause");
          }}
          disabled={pauseDisabled}
          aria-label="Pause session"
        >
          {pendingAction === "pause" ? (
            <Loader2 className="h-3.5 w-3.5 animate-spin" aria-hidden="true" />
          ) : (
            <span aria-hidden="true">⏸</span>
          )}
          <span>Pause</span>
        </Button>

        <Button
          type="button"
          size="sm"
          variant="secondary"
          onClick={() => {
            submitAction("resume");
          }}
          disabled={resumeDisabled}
          aria-label="Resume session"
        >
          {pendingAction === "resume" ? (
            <Loader2 className="h-3.5 w-3.5 animate-spin" aria-hidden="true" />
          ) : (
            <span aria-hidden="true">▶</span>
          )}
          <span>Resume</span>
        </Button>

        <div className="relative">
          <Button
            type="button"
            size="sm"
            variant="secondary"
            onClick={() => {
              setErrorMessage(null);
              setConfirmingKill((current) => (current === "graceful" ? null : "graceful"));
            }}
            disabled={gracefulKillDisabled}
            aria-label="Gracefully kill session"
          >
            {pendingAction === "graceful-kill" ? (
              <Loader2 className="h-3.5 w-3.5 animate-spin" aria-hidden="true" />
            ) : (
              <span aria-hidden="true">⏹</span>
            )}
            <span>Graceful Kill</span>
          </Button>
          {confirmingKill === "graceful" ? (
            <div className="absolute right-0 top-[calc(100%+0.375rem)] z-20 w-72 rounded-md border border-border bg-card p-2 shadow-lg">
              <p className="text-xs text-muted-foreground">
                Gracefully stop this agent after it finishes the current step?
              </p>
              <div className="mt-2 flex justify-end gap-1.5">
                <Button
                  type="button"
                  size="sm"
                  variant="ghost"
                  onClick={() => {
                    setConfirmingKill(null);
                  }}
                  disabled={isBusy}
                >
                  Cancel
                </Button>
                <Button
                  type="button"
                  size="sm"
                  variant="secondary"
                  onClick={() => {
                    submitAction("graceful-kill");
                  }}
                  disabled={isBusy}
                >
                  {pendingAction === "graceful-kill" ? (
                    <Loader2 className="h-3.5 w-3.5 animate-spin" aria-hidden="true" />
                  ) : null}
                  <span>Confirm</span>
                </Button>
              </div>
            </div>
          ) : null}
        </div>

        <div className="relative">
          <Button
            type="button"
            size="sm"
            variant="danger"
            onClick={() => {
              setErrorMessage(null);
              setConfirmingKill((current) => (current === "force" ? null : "force"));
            }}
            disabled={forceKillDisabled}
            aria-label="Force kill session"
          >
            {pendingAction === "force-kill" ? (
              <Loader2 className="h-3.5 w-3.5 animate-spin" aria-hidden="true" />
            ) : (
              <span aria-hidden="true">💀</span>
            )}
            <span>Force Kill</span>
          </Button>
          {confirmingKill === "force" ? (
            <div className="absolute right-0 top-[calc(100%+0.375rem)] z-20 w-72 rounded-md border border-border bg-card p-2 shadow-lg">
              <p className="text-xs text-muted-foreground">
                This will hard-kill the agent immediately.
              </p>
              <div className="mt-2 flex justify-end gap-1.5">
                <Button
                  type="button"
                  size="sm"
                  variant="ghost"
                  onClick={() => {
                    setConfirmingKill(null);
                  }}
                  disabled={isBusy}
                >
                  Cancel
                </Button>
                <Button
                  type="button"
                  size="sm"
                  variant="danger"
                  onClick={() => {
                    submitAction("force-kill");
                  }}
                  disabled={isBusy}
                >
                  {pendingAction === "force-kill" ? (
                    <Loader2 className="h-3.5 w-3.5 animate-spin" aria-hidden="true" />
                  ) : null}
                  <span>Confirm</span>
                </Button>
              </div>
            </div>
          ) : null}
        </div>
      </div>

      {errorMessage ? (
        <Badge variant="status-error" className="max-w-[32rem] whitespace-normal text-xs">
          {errorMessage}
        </Badge>
      ) : null}
    </div>
  );
}
