"use client";

import * as React from "react";
import { Calendar, Loader2 } from "lucide-react";
import { useQueryClient } from "@tanstack/react-query";
import { useAppDispatch, useAppSelector } from "@/store/hooks";
import {
  closeDiscoveryMeetingBookedDialog,
  selectDiscoveryMeetingBookedDialog,
} from "@/store/slices/discovery-meeting-booked-dialog-slice";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Textarea } from "@/components/ui/textarea";
import { ReactSelect } from "@/components/ui/react-select";
import { DateTimePicker } from "@/components/ui/date-time-picker";
import { useMoveDealMutation } from "@/api/rtk/deals-api";
import { useMoveLeadMutation } from "@/features/leads/hooks/use-move-lead-mutation";
import { toast } from "sonner";
import {
  markLocalDealBoardMove,
  clearLocalDealBoardMoveEcho,
} from "@/lib/deal-board-socket-coalesce";
import { invalidateLeadsBoardColumnsTouchingStages } from "@/features/leads/api/invalidate-leads-board-columns";
import { leadsKeys } from "@/features/leads/api/query-keys";
import {
  applyOptimisticLeadBoardMoveWithCounts,
  revertOptimisticLeadBoardMoveWithCounts,
} from "@/features/leads/api/optimistic-board-column-move";
import { baseApi } from "@/api/rtk/base-api";
import {
  buildLeadMeetingNotes,
  LEAD_MEETING_MEDIUM_OPTIONS,
  toLeadMeetingDateIso,
  type LeadMeetingMedium,
} from "@/lib/lead-meeting-medium";

function FieldLabel({ children }: { children: React.ReactNode }) {
  return (
    <label className="mb-1.5 block select-none font-['Lexend_Deca'] text-[10px] font-medium uppercase tracking-[0.09em] text-gray-400">
      {children}
    </label>
  );
}

export function DiscoveryMeetingBookedDialog() {
  const dispatch = useAppDispatch();
  const queryClient = useQueryClient();
  const dlg = useAppSelector(selectDiscoveryMeetingBookedDialog);
  const [moveDealMutation, { isLoading: isMovingDeal }] = useMoveDealMutation();
  const { mutateAsync: moveLeadTs, isPending: isMovingLeadTs } =
    useMoveLeadMutation();

  const [meetingDate, setMeetingDate] = React.useState<string | undefined>();
  const [medium, setMedium] = React.useState<LeadMeetingMedium | "">("");
  const [otherMediumDetail, setOtherMediumDetail] = React.useState("");
  const [notes, setNotes] = React.useState("");

  React.useEffect(() => {
    if (!dlg.open) {
      setMeetingDate(undefined);
      setMedium("");
      setOtherMediumDetail("");
      setNotes("");
    }
  }, [dlg.open]);

  const handleClose = () => {
    dispatch(closeDiscoveryMeetingBookedDialog());
  };

  const handleConfirm = async () => {
    if (!dlg.dealId || !dlg.pipelineId || !dlg.targetStageId || !dlg.moveContext) {
      return;
    }
    const meetingDateIso = toLeadMeetingDateIso(meetingDate);
    if (!meetingDateIso) {
      toast.error("Meeting date and time are required");
      return;
    }
    if (!medium) {
      toast.error("Meeting medium is required");
      return;
    }
    if (medium === "OTHER" && !otherMediumDetail.trim()) {
      toast.error("Please specify the meeting medium");
      return;
    }

    const meetingNotes = buildLeadMeetingNotes({
      medium,
      otherMediumDetail,
      notes,
    });

    const leadMeeting = {
      meetingDate: meetingDateIso,
      medium,
      ...(meetingNotes ? { notes: meetingNotes } : {}),
    };

    const prob = dlg.targetProb ?? 0;

    const fromStage = dlg.sourceStageId ?? "";
    let optimisticSnapshot: ReturnType<
      typeof applyOptimisticLeadBoardMoveWithCounts
    > = null;

    try {
      if (dlg.moveContext.kind === "paged") {
        optimisticSnapshot = applyOptimisticLeadBoardMoveWithCounts(
          queryClient,
          {
            dealId: dlg.dealId,
            fromStage,
            toStage: dlg.targetStageId,
            listParams: dlg.moveContext.listParams,
          },
        );
        await moveLeadTs({
          id: dlg.dealId,
          stageId: dlg.targetStageId,
          prob,
          leadMeeting,
        });
      } else if (dlg.moveContext.kind === "infinite") {
        await moveDealMutation({
          id: dlg.dealId,
          stageId: dlg.targetStageId,
          prob,
          leadMeeting,
          ...dlg.moveContext.listArgs,
        }).unwrap();
      } else {
        await moveDealMutation({
          id: dlg.dealId,
          stageId: dlg.targetStageId,
          prob,
          leadMeeting,
          pipelineId: dlg.pipelineId ?? undefined,
        }).unwrap();
      }

      const from = dlg.sourceStageId ?? undefined;
      markLocalDealBoardMove(dlg.dealId, from, dlg.targetStageId);
      if (dlg.moveContext.kind === "paged") {
        void queryClient.invalidateQueries({
          queryKey: leadsKeys.boardCounts(dlg.moveContext.listParams),
        });
      } else {
        invalidateLeadsBoardColumnsTouchingStages(queryClient, [
          from,
          dlg.targetStageId,
        ].filter(Boolean) as string[]);
      }

      dispatch(
        baseApi.util.invalidateTags([
          { type: "Deals", id: dlg.dealId },
          { type: "Deals", id: "LIST" },
          { type: "Deals", id: "QA_STATS" },
        ]),
      );

      toast.success("Discovery meeting booked");
      handleClose();
    } catch (err: unknown) {
      clearLocalDealBoardMoveEcho();
      if (
        optimisticSnapshot &&
        dlg.moveContext?.kind === "paged"
      ) {
        revertOptimisticLeadBoardMoveWithCounts(
          queryClient,
          optimisticSnapshot,
          dlg.moveContext.listParams,
        );
      }
      const msg =
        err && typeof err === "object" && "data" in err
          ? (() => {
              const d = (err as { data?: { message?: unknown } }).data?.message;
              return typeof d === "string"
                ? d
                : Array.isArray(d) && typeof d[0] === "string"
                  ? d[0]
                  : "";
            })()
          : err instanceof Error
            ? err.message
            : "";
      toast.error(msg.trim() || "Failed to move lead to Discovery Meeting Booked");
    }
  };

  const busy = isMovingDeal || isMovingLeadTs;
  const titleName = dlg.customerName?.trim() || "this lead";

  return (
    <Dialog
      open={dlg.open}
      onOpenChange={(open) => {
        if (!open) handleClose();
      }}
    >
      <DialogContent className="sm:max-w-md">
        <DialogHeader>
          <DialogTitle className="flex items-center gap-2">
            <Calendar className="size-4 text-accent" />
            Discovery meeting details
          </DialogTitle>
          <DialogDescription>
            Enter the scheduled meeting for <strong>{titleName}</strong> before
            moving to Discovery Meeting Booked.
          </DialogDescription>
        </DialogHeader>

        <div className="space-y-4 py-1">
          <div>
            <FieldLabel>Meeting date & time *</FieldLabel>
            <DateTimePicker
              value={meetingDate}
              onChange={setMeetingDate}
              placeholder="Select meeting date and time"
            />
          </div>
          <div>
            <FieldLabel>Meeting medium *</FieldLabel>
            <ReactSelect
              value={medium || undefined}
              onValueChange={(v) => {
                const next = v as LeadMeetingMedium;
                setMedium(next);
                if (next !== "OTHER") setOtherMediumDetail("");
              }}
              options={LEAD_MEETING_MEDIUM_OPTIONS}
              placeholder="Select medium"
            />
          </div>
          {medium === "OTHER" ? (
            <div>
              <FieldLabel>Specify medium *</FieldLabel>
              <Input
                value={otherMediumDetail}
                onChange={(e) => setOtherMediumDetail(e.target.value)}
                placeholder="e.g. Webex, WhatsApp call, Skype"
                className="text-sm"
              />
            </div>
          ) : null}
          <div>
            <FieldLabel>Notes (optional)</FieldLabel>
            <Textarea
              value={notes}
              onChange={(e) => setNotes(e.target.value)}
              placeholder="Dial-in link, location, or other context"
              rows={3}
              className="resize-none text-sm"
            />
          </div>
        </div>

        <DialogFooter className="gap-2 sm:gap-0">
          <Button type="button" variant="outline" onClick={handleClose} disabled={busy}>
            Cancel
          </Button>
          <Button type="button" variant="accent" onClick={handleConfirm} disabled={busy}>
            {busy ? (
              <>
                <Loader2 className="mr-2 size-4 animate-spin" />
                Saving…
              </>
            ) : (
              "Book meeting & move"
            )}
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}
