"use client";

import { useEffect, useState } from "react";
import toast from "react-hot-toast";

import { getProfile } from "@/app/lib/auth";
import {
  precheckConsultation,
  startConsultation,
  cacheSubmittedConsulteeDetails,
  joinConsultationQueue,
  getConsultationQueueStatus,
  cacheQueueConsulteeDetails,
  extractQueueEntry,
} from "@/app/lib/consultation";
import { useLocaleRouter } from "@/app/lib/useLocaleRouter";

interface AstrologerSummary {
  id: number;
  name: string;
  charge: number;
  callRate?: number;
}

interface Props {
  show: boolean;
  onClose: () => void;
  astrologer: AstrologerSummary;
  medium: "CHAT" | "AUDIO";
  // Called instead of showing the blocked-reason modal when precheck
  // finds the astrologer busy/offline (the list's own isOnline/isBusy
  // fields can be stale — precheck is the live authority, see
  // CLAUDE.md). Lets the card update its own button to a "Busy"/
  // "Offline" pill instead of popping up a dialog for this case.
  // Busy no longer ends here: a busy (or queue-reserved) astrologer
  // switches this modal into "join the waiting queue" mode instead, and
  // onUnavailable only tells the card to relabel its button.
  onUnavailable?: (reason: "ASTROLOGER_BUSY" | "ASTROLOGER_OFFLINE") => void;
}

interface ConsulteeForm {
  name: string;
  birthDate: string;
  birthTime: string;
  birthPlace: string;
  gender: string;
  maritalStatus: string;
  topic: string;
}

const EMPTY_FORM: ConsulteeForm = {
  name: "",
  birthDate: "",
  birthTime: "",
  birthPlace: "",
  gender: "",
  maritalStatus: "",
  topic: "",
};

// Confirmed live (Consultation API Handbook): blocked_reason is one of
// these — blocked_message is usually populated too, but fall back to
// a friendly string per reason if it's ever blank.
const BLOCKED_REASON_FALLBACK: Record<string, string> = {
  ASTROLOGER_OFFLINE: "This astrologer is currently offline.",
  ASTROLOGER_BUSY: "This astrologer is busy with another consultation right now.",
  QUEUE_RESERVED: "This astrologer is reserved for the next customer in the waiting queue.",
  INSUFFICIENT_BALANCE: "Your wallet balance is too low to start this consultation.",
  MEDIUM_DISABLED: "This astrologer isn't accepting this type of consultation right now.",
  NO_RATE_CONFIGURED: "This astrologer hasn't set a rate for this yet.",
  SESSION_ALREADY_OPEN: "You already have an active consultation.",
  SERVICE_NOT_CONFIGURED: "This service isn't available right now — please try again later.",
};

export default function StartConsultationModal({
  show,
  onClose,
  astrologer,
  medium,
  onUnavailable,
}: Props) {
  const router = useLocaleRouter();

  const [step, setStep] = useState<"loading" | "blocked" | "form">("loading");
  const [loading, setLoading] = useState(false);
  const [blockedReason, setBlockedReason] = useState("");
  const [blockedMessage, setBlockedMessage] = useState("");
  const [precheckInfo, setPrecheckInfo] = useState<{
    isFreeChat?: boolean;
    freeMinutes?: number;
    ratePerMinute?: number;
    walletBalance?: number;
    requiredBalance?: number;
  }>({});
  const [form, setForm] = useState<ConsulteeForm>(EMPTY_FORM);
  // True when precheck says the astrologer is busy / reserved for the
  // queue: the same consultee form is shown, but submitting joins the
  // waiting queue instead of ringing the astrologer.
  const [queueMode, setQueueMode] = useState(false);

  useEffect(() => {
    if (!show) return;

    setStep("loading");
    setQueueMode(false);
    setBlockedMessage("");
    setBlockedReason("");

    const token = localStorage.getItem("token");

    if (!token) {
      router.push("/signin");
      return;
    }

    precheckConsultation(astrologer.id, medium)
      .then(async (response) => {
        if (!response.success || !response.data) {
          setBlockedReason("SERVICE_NOT_CONFIGURED");
          setBlockedMessage(response.message || BLOCKED_REASON_FALLBACK.SERVICE_NOT_CONFIGURED);
          setStep("blocked");
          return;
        }

        const data = response.data;

        setPrecheckInfo({
          isFreeChat: data.is_free_chat,
          freeMinutes: data.free_minutes,
          ratePerMinute: data.rate_per_minute,
          walletBalance: data.wallet_balance,
          requiredBalance: data.required_balance,
        });

        const joinsQueue =
          !data.can_start &&
          (data.blocked_reason === "ASTROLOGER_BUSY" || data.blocked_reason === "QUEUE_RESERVED");

        if (!data.can_start && !joinsQueue) {
          // Offline is already represented on the card itself (see
          // AstrologerCard) — skip the modal entirely and let the card
          // reflect this live-confirmed state on its own button,
          // silently, instead of popping up a dialog OR a toast for
          // something the list UI already has a home for.
          if (data.blocked_reason === "ASTROLOGER_OFFLINE") {
            onUnavailable?.(data.blocked_reason);
            onClose();
            return;
          }

          setBlockedReason(data.blocked_reason || "");
          setBlockedMessage(
            data.blocked_message ||
              BLOCKED_REASON_FALLBACK[data.blocked_reason] ||
              "This consultation can't be started right now."
          );
          setStep("blocked");
          return;
        }

        if (joinsQueue) {
          setQueueMode(true);
          onUnavailable?.("ASTROLOGER_BUSY");
        }

        // Prefill the consultee form from the logged-in user's own
        // profile — the API notes the consultee "is often not the
        // account holder", so this is just a convenient starting point.
        try {
          const profileResponse = await getProfile(token);
          const user = profileResponse?.user ?? {};

          setForm({
            name: user.Name || "",
            birthDate: user.BirthDate || "",
            birthTime: user.BirthTime || "",
            birthPlace: user.BirthPlace || "",
            gender: user.Gender || "",
            maritalStatus: "",
            topic: "",
          });
        } catch {
          // Non-fatal — the form just starts blank.
        }

        setStep("form");
      })
      .catch(() => {
        setBlockedReason("SERVICE_NOT_CONFIGURED");
        setBlockedMessage(BLOCKED_REASON_FALLBACK.SERVICE_NOT_CONFIGURED);
        setStep("blocked");
      });
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [show, astrologer.id, medium]);

  if (!show) return null;

  const updateForm = (patch: Partial<ConsulteeForm>) =>
    setForm((prev) => ({ ...prev, ...patch }));

  const goToWallet = () => {
    onClose();
    router.push("/add-wallet-money/price-list");
  };

  const handleJoinQueue = async () => {
    try {
      setLoading(true);

      const response = await joinConsultationQueue(astrologer.id, medium);
      let entry = response.success ? extractQueueEntry(response.data) : null;

      if (!response.success) {
        const message = response.message || "";

        // Astrologer freed up between precheck and join — back to the
        // normal "ring them" form.
        if (/available now/i.test(message)) {
          setQueueMode(false);
          toast.success(`${astrologer.name} is available now.`);
          return;
        }

        // Already queued (409): jump to the existing entry instead.
        if (/already in the waiting queue/i.test(message)) {
          const active = await getConsultationQueueStatus();
          const list = Array.isArray(active.data?.list) ? active.data.list : [];
          entry =
            list.find((item: any) => Number(item.astrologer_id) === Number(astrologer.id)) ?? null;
        }

        if (!entry) {
          toast.error(message || "Unable to join the waiting queue.");
          return;
        }
      }

      if (!entry) {
        toast.error("Unable to join the waiting queue.");
        return;
      }

      cacheQueueConsulteeDetails(entry.queue_id, {
        name: form.name || undefined,
        birth_date: form.birthDate || undefined,
        birth_time: form.birthTime || undefined,
        birth_place: form.birthPlace || undefined,
        gender: form.gender || undefined,
        marital_status: form.maritalStatus || undefined,
        topic: form.topic || undefined,
      });

      onClose();
      router.push(`/waiting-queue/${entry.queue_id}`);
    } catch (error: any) {
      toast.error(error?.message || "Something went wrong.");
    } finally {
      setLoading(false);
    }
  };

  const handleSubmit = async () => {
    const token = localStorage.getItem("token");

    if (!token) {
      router.push("/signin");
      return;
    }

    // Confirmed live: a session started without a birth date can never
    // be ended — /consultation/end (and the astrologer's end) fail with
    // a raw "Column 'birthDate' cannot be null" and the session sticks
    // open (and keeps billing) until the sweeper closes it. Never let
    // one start.
    if (!form.birthDate) {
      toast.error("Please enter the date of birth to continue.");
      return;
    }

    if (queueMode) {
      await handleJoinQueue();
      return;
    }

    try {
      setLoading(true);

      // Confirmed live: /consultation/start now only RINGS the
      // astrologer — nothing is billed here, no Agora channel is
      // joined yet. The customer confirms separately once accepted
      // (see /consultation/[id]).
      const response = await startConsultation({
        astrologer_id: astrologer.id,
        medium,
        name: form.name || undefined,
        birth_date: form.birthDate || undefined,
        birth_time: form.birthTime || undefined,
        birth_place: form.birthPlace || undefined,
        gender: form.gender || undefined,
        marital_status: form.maritalStatus || undefined,
        topic: form.topic || undefined,
      });

      if (!response.success) {
        if (/insufficient wallet balance/i.test(response.message || "")) {
          setBlockedReason("INSUFFICIENT_BALANCE");
          setBlockedMessage(response.message);
          setStep("blocked");
          return;
        }

        // Another customer took the turn (or the astrologer just got
        // busy) between precheck and start — fall into queue mode.
        if (/waiting queue|reserved for the next customer/i.test(response.message || "")) {
          setQueueMode(true);
          onUnavailable?.("ASTROLOGER_BUSY");
          toast("This astrologer is busy — you can join the waiting queue.");
          return;
        }

        toast.error(response.message || "Unable to start the consultation.");
        return;
      }

      const consultationId = response.data?.consultation_id;

      if (consultationId) {
        cacheSubmittedConsulteeDetails(consultationId, {
          name: form.name || undefined,
          gender: form.gender || undefined,
          birthDate: form.birthDate || undefined,
          birthTime: form.birthTime || undefined,
          birthPlace: form.birthPlace || undefined,
          maritalStatus: form.maritalStatus || undefined,
          topic: form.topic || undefined,
        });
      }

      onClose();
      router.push(`/consultation/${consultationId}`);
    } catch (error: any) {
      toast.error(error?.message || "Something went wrong.");
    } finally {
      setLoading(false);
    }
  };

  return (
    <>
      <div className="modal-backdrop fade show" onClick={onClose} />

      <div
        className="modal fade show d-block"
        tabIndex={-1}
        role="dialog"
        onClick={onClose}
      >
        <div
          className="modal-dialog modal-dialog-centered"
          onClick={(e) => e.stopPropagation()}
        >
          <div className="modal-content card-bg-primary border-0 rounded-4 overflow-hidden">
            {step !== "form" && (
              <button
                type="button"
                className="btn-close btn-close-white position-absolute"
                style={{ top: 16, right: 16, zIndex: 1 }}
                aria-label="Close"
                onClick={onClose}
              />
            )}

          {step === "loading" && (
            <div className="modal-body p-4 text-center text-white">Checking availability...</div>
          )}

          {step === "blocked" && (
            <div className="modal-body p-4 text-center text-white">
              <p className="mb-4">{blockedMessage}</p>

              <div className="d-flex gap-3 justify-content-center">
                <button type="button" className="btn btn-outline-light px-4" onClick={onClose}>
                  Cancel
                </button>
                {blockedReason === "INSUFFICIENT_BALANCE" && (
                  <button type="button" className="btn btn-warning px-4 fw-bold" onClick={goToWallet}>
                    Proceed
                  </button>
                )}
              </div>
            </div>
          )}

          {step === "form" && (
            <>
              <div className="modal-header bg-warning border-0">
                <h5 className="modal-title w-100 text-center fw-bold">
                  {queueMode
                    ? `Join waiting queue for ${astrologer.name}`
                    : `${medium === "AUDIO" ? "Start Call" : "Start Chat"} with ${astrologer.name}`}
                </h5>
                <button
                  type="button"
                  className="btn-close position-absolute"
                  style={{ top: 16, right: 16 }}
                  aria-label="Close"
                  onClick={onClose}
                />
              </div>

              <div className="modal-body text-white p-4">
                {queueMode && (
                  <p
                    className="small mb-3 p-2 rounded-3"
                    style={{ background: "rgba(239,68,68,0.12)", color: "#FCA5A5" }}
                  >
                    {astrologer.name} is busy right now. Join the waiting queue — you&apos;ll
                    be notified when it&apos;s your turn, and you can leave any time.
                  </p>
                )}

                {precheckInfo.isFreeChat ? (
                  <p className="mb-3" style={{ color: "#22C55E" }}>
                    Your first {precheckInfo.freeMinutes} minutes are free with this astrologer.
                  </p>
                ) : (
                  <p className="terms-text-color small mb-3">
                    ₹{precheckInfo.ratePerMinute}/min · Wallet balance ₹{precheckInfo.walletBalance}
                  </p>
                )}

                <p className="terms-text-color small mb-3">
                  These details help {astrologer.name} personalize the reading — often for
                  someone other than yourself.
                </p>

                <div className="mb-3">
                  <label className="form-label fw-semibold">Full name</label>
                  <input
                    className="form-control form-control-lg"
                    value={form.name}
                    onChange={(e) => updateForm({ name: e.target.value })}
                  />
                </div>

                <div className="row g-3 mb-3">
                  <div className="col-6">
                    <label className="form-label fw-semibold">Date of birth *</label>
                    <input
                      type="date"
                      className="form-control form-control-lg"
                      value={form.birthDate}
                      onChange={(e) => updateForm({ birthDate: e.target.value })}
                    />
                  </div>
                  <div className="col-6">
                    <label className="form-label fw-semibold">Time of birth</label>
                    <input
                      type="time"
                      className="form-control form-control-lg"
                      value={form.birthTime}
                      onChange={(e) => updateForm({ birthTime: e.target.value })}
                    />
                  </div>
                </div>

                <div className="mb-3">
                  <label className="form-label fw-semibold">Place of birth</label>
                  <input
                    className="form-control form-control-lg"
                    value={form.birthPlace}
                    onChange={(e) => updateForm({ birthPlace: e.target.value })}
                  />
                </div>

                <div className="row g-3 mb-2">
                  <div className="col-6">
                    <label className="form-label fw-semibold">Gender</label>
                    <select
                      className="form-control form-control-lg"
                      value={form.gender}
                      onChange={(e) => updateForm({ gender: e.target.value })}
                    >
                      <option value="">Select</option>
                      <option value="MALE">Male</option>
                      <option value="FEMALE">Female</option>
                    </select>
                  </div>
                  <div className="col-6">
                    <label className="form-label fw-semibold">Marital status</label>
                    <select
                      className="form-control form-control-lg"
                      value={form.maritalStatus}
                      onChange={(e) => updateForm({ maritalStatus: e.target.value })}
                    >
                      <option value="">Select</option>
                      <option value="Single">Single</option>
                      <option value="Married">Married</option>
                      <option value="Divorced">Divorced</option>
                      <option value="Widowed">Widowed</option>
                    </select>
                  </div>
                </div>

                <div className="mb-2">
                  <label className="form-label fw-semibold">
                    What would you like to talk about?
                  </label>
                  <select
                    className="form-control form-control-lg"
                    value={form.topic}
                    onChange={(e) => updateForm({ topic: e.target.value })}
                  >
                    <option value="">Select</option>
                    <option value="Love">Love</option>
                    <option value="Career">Career</option>
                    <option value="Marriage">Marriage</option>
                    <option value="Health">Health</option>
                    <option value="Finance">Finance</option>
                    <option value="Family">Family</option>
                    <option value="Education">Education</option>
                    <option value="General">General</option>
                  </select>
                </div>
              </div>

              <div className="modal-footer justify-content-center border-0 gap-3">
                <button type="button" className="btn btn-outline-light px-4" onClick={onClose} disabled={loading}>
                  Cancel
                </button>
                <button
                  type="button"
                  className="btn btn-warning px-4 fw-bold"
                  onClick={handleSubmit}
                  disabled={loading}
                >
                  {queueMode
                    ? loading
                      ? "Joining..."
                      : "Join Queue"
                    : loading
                      ? "Ringing..."
                      : medium === "AUDIO"
                        ? "Start Call"
                        : "Start Chat"}
                </button>
              </div>
            </>
          )}
          </div>
        </div>
      </div>
    </>
  );
}
