"use client";

import { Undo2 } from "lucide-react";
import { useRouter } from "next/navigation";
import * as React from "react";
import { toast } from "sonner";

import { Button } from "@/components/ui/button";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { requestDashboardApi } from "@/lib/dashboard-api-client";

const REVERT_HREF =
  "/dashboard/master-table/structure-master/corporate-actions/revert";

type Props = {
  actionId: number;
  underlyingIsin: string;
  appliedCount: number;
};

/**
 * Restores the Old values captured at preview time.
 *
 * Reverting writes to the same live rows the apply did, so it carries the same
 * typed-ISIN confirmation rather than a plain yes/no.
 */
export function RevertActionButton({ actionId, underlyingIsin, appliedCount }: Props) {
  const router = useRouter();
  const [open, setOpen] = React.useState(false);
  const [confirmIsin, setConfirmIsin] = React.useState("");
  const [isReverting, setIsReverting] = React.useState(false);

  // Reset on close in the handler rather than an effect: the state change is
  // caused by the open/close event, not by synchronising with anything external.
  const setDialogOpen = (next: boolean) => {
    if (!next) setConfirmIsin("");
    setOpen(next);
  };

  const confirmMatches =
    confirmIsin.trim().toUpperCase() === underlyingIsin.trim().toUpperCase();

  const onRevert = async () => {
    setIsReverting(true);
    try {
      const result = await requestDashboardApi<{
        reverted?: number;
        failed?: number;
        errors?: string[];
      }>({
        url: REVERT_HREF,
        method: "POST",
        body: { actionId, underlyingIsin, confirmIsin },
        fallbackError: "Could not revert the corporate action.",
      });

      setDialogOpen(false);
      const failed = result.failed ?? 0;
      if (failed > 0) {
        toast.warning(`Reverted ${result.reverted ?? 0} record(s), ${failed} failed.`);
      } else {
        toast.success(`Reverted ${result.reverted ?? 0} record(s).`);
      }
      router.refresh();
    } catch (error) {
      toast.error(
        error instanceof Error ? error.message : "Could not revert the corporate action.",
      );
    } finally {
      setIsReverting(false);
    }
  };

  return (
    <>
      <Button size="sm" variant="outline" onClick={() => setDialogOpen(true)}>
        <Undo2 className="size-4" />
        Revert
      </Button>

      <Dialog open={open} onOpenChange={setDialogOpen}>
        <DialogContent className="sm:max-w-lg">
          <DialogHeader>
            <DialogTitle>Revert this corporate action</DialogTitle>
            <DialogDescription>
              Restores the Old quantity, purchase price and amount on{" "}
              {appliedCount} applied record(s), and clears their corporate action
              stamp so a corrected split can be applied afterwards.
            </DialogDescription>
          </DialogHeader>

          <div className="space-y-2">
            <Label htmlFor="revert-confirm-isin" className="text-sm">
              Type <span className="font-mono font-semibold">{underlyingIsin}</span> to
              confirm
            </Label>
            <Input
              id="revert-confirm-isin"
              value={confirmIsin}
              onChange={(event) => setConfirmIsin(event.target.value)}
              autoComplete="off"
              placeholder={underlyingIsin}
            />
          </div>

          <DialogFooter className="gap-2">
            <Button variant="outline" onClick={() => setDialogOpen(false)} disabled={isReverting}>
              Cancel
            </Button>
            <Button onClick={onRevert} disabled={!confirmMatches || isReverting}>
              {isReverting ? "Reverting…" : "Revert"}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </>
  );
}
