import { useEffect, useState } from "react";
import { ApiError } from "../../api/client";
import type { Machine } from "../../api/types";
import { Button } from "../../components/ui/Button";
import { Modal } from "../../components/ui/Modal";
import { useToast } from "../../components/ui/toast-context";
import { useDeleteMachine } from "./hooks";

interface DeleteMachineDialogProps {
  machine: Machine | null;
  onClose: () => void;
}

/**
 * Destructive machine removal with two options:
 *  - uninstall: also command the agent to uninstall (only meaningful online)
 *  - export: return full history in the delete response before removal
 */
export function DeleteMachineDialog({ machine, onClose }: DeleteMachineDialogProps) {
  const toast = useToast();
  const del = useDeleteMachine();
  const [uninstall, setUninstall] = useState(false);
  const [exportHistory, setExportHistory] = useState(false);

  // Reset options each time a new machine is targeted.
  useEffect(() => {
    if (machine) {
      setUninstall(false);
      setExportHistory(false);
    }
  }, [machine]);

  function handleConfirm() {
    if (!machine) return;
    del.mutate(
      { agentId: machine.agent_id, params: { uninstall, export: exportHistory } },
      {
        onSuccess: (res) => {
          if (exportHistory && res.history) {
            downloadHistory(machine.hostname, res.history);
          }
          toast.success(
            "Machine deleted",
            res.uninstall_sent
              ? "Uninstall command sent to the agent."
              : undefined,
          );
          onClose();
        },
        onError: (err) => {
          toast.error(
            "Could not delete machine",
            err instanceof ApiError
              ? err.message
              : "The server did not respond. The machine was not deleted.",
          );
        },
      },
    );
  }

  return (
    <Modal
      open={machine != null}
      title="Delete machine"
      onClose={del.isPending ? () => {} : onClose}
      dismissable={!del.isPending}
      footer={
        <>
          <Button variant="ghost" onClick={onClose} disabled={del.isPending}>
            Keep machine
          </Button>
          <Button variant="danger" onClick={handleConfirm} loading={del.isPending}>
            Delete machine
          </Button>
        </>
      }
    >
      <p style={{ marginTop: 0 }}>
        Permanently delete{" "}
        <span className="mono">{machine?.hostname}</span> from GuruConnect,
        including its registration and full history. This cannot be undone.
      </p>

      <label className="optline">
        <input
          type="checkbox"
          checked={uninstall}
          onChange={(e) => setUninstall(e.target.checked)}
        />
        <span>
          Also uninstall the agent
          {machine && machine.status !== "online" && (
            <em className="optline__note">
              {" "}
              (offline now; queued until the agent next checks in)
            </em>
          )}
        </span>
      </label>

      <label className="optline">
        <input
          type="checkbox"
          checked={exportHistory}
          onChange={(e) => setExportHistory(e.target.checked)}
        />
        <span>Export full history (download JSON) before removal</span>
      </label>
    </Modal>
  );
}

function downloadHistory(hostname: string, history: unknown) {
  const blob = new Blob([JSON.stringify(history, null, 2)], {
    type: "application/json",
  });
  const url = URL.createObjectURL(blob);
  const a = document.createElement("a");
  a.href = url;
  a.download = `${hostname}-history-${new Date().toISOString().slice(0, 10)}.json`;
  document.body.appendChild(a);
  a.click();
  document.body.removeChild(a);
  URL.revokeObjectURL(url);
}
