"use client";

import { useMemo, useState } from "react";
import { useFormStatus } from "react-dom";
import { CheckCircle2, Wallet } from "lucide-react";
import type { ApiBidding, ApiWalletSummary } from "@/lib/api/types";
import { acceptQuotation } from "./actions";
import BookingTermsConsent from "@/components/rfq/BookingTermsConsent";

/**
 * Constructing an `Intl.NumberFormat` costs roughly an order of magnitude more
 * than the `.format()` call it enables, and this one is used inside `.map()`
 * bodies — so it is built once here rather than per invocation.
 *
 * Not `formatCurrency` from `@/lib/utils`: that one rounds to whole rupees,
 * while quotations are shown to the paisa.
 */
const inr2 = new Intl.NumberFormat("en-IN", {
  style: "currency",
  currency: "INR",
  maximumFractionDigits: 2,
});

function fmtINR(n: number | string | null | undefined) {
  if (n === null || n === undefined || n === "") return "—";
  const num = typeof n === "string" ? parseFloat(n) : n;
  if (Number.isNaN(num)) return "—";
  return inr2.format(num);
}

function bidTotal(bid: ApiBidding) {
  // The auction's own figure when there is one: it already carries freight and
  // other charges, and it is what the buyer was shown as the doorstep price.
  if (bid.for_price != null) return bid.for_price;

  const base = parseFloat(String(bid.base_price ?? 0)) || 0;
  const transport = parseFloat(String(bid.transport_price ?? 0)) || 0;
  const commission = parseFloat(String(bid.commission ?? 0)) || 0;
  return base + transport + (bid.commission_type === "include" ? 0 : commission);
}

/**
 * How an offer is referred to in the UI.
 *
 * Falls back to the seller's name for callers that still receive one; the
 * buyer's list does not, by design.
 */
function offerName(bid: ApiBidding): string {
  return bid.seller_label || bid.seller?.company_name || bid.seller?.name || "Offer";
}

/**
 * The quotation list plus its accept modal.
 *
 * This is the one genuinely interactive part of the page: which bid is being
 * accepted, which wallet pays, and the two editable amounts are all local UI
 * state with no URL or server representation. Everything around it — the
 * enquiry header, the detail cards, the timeline — renders on the server.
 *
 * The wallet arrives as a prop instead of being fetched here. The client
 * version only requested it once the modal mounted, which put a third network
 * round trip behind the enquiry fetch *and* a user click; the page now asks for
 * all three payloads in one `Promise.all` during SSR.
 */
export default function AcceptQuotation({
  bids,
  wallet,
  enquiryId,
  disabled,
  bookingPolicy,
}: {
  bids: ApiBidding[];
  wallet: ApiWalletSummary | null;
  enquiryId: number;
  disabled: boolean;
  bookingPolicy: string;
}) {
  const [acceptingBid, setAcceptingBid] = useState<ApiBidding | null>(null);

  return (
    <>
      <div className="space-y-3">
        {bids.map((b) => (
          <BiddingCard key={b.id} bid={b} disabled={disabled} onAccept={() => setAcceptingBid(b)} />
        ))}
      </div>

      {acceptingBid && (
        <AcceptModal
          enquiryId={enquiryId}
          bid={acceptingBid}
          wallet={wallet}
          bookingPolicy={bookingPolicy}
          onClose={() => setAcceptingBid(null)}
        />
      )}
    </>
  );
}

function BiddingCard({
  bid,
  disabled,
  onAccept,
}: {
  bid: ApiBidding;
  disabled: boolean;
  onAccept: () => void;
}) {
  const total = useMemo(() => bidTotal(bid), [bid]);

  const isAccepted = bid.is_marked || (bid.status ?? "").toLowerCase() === "ordered";

  return (
    <div
      className={`rounded-xl border p-4 transition ${
        isAccepted ? "border-emerald-300 bg-emerald-50/30" : "border-gray-200 hover:border-[#CC1414]/40"
      }`}
    >
      <div className="flex flex-wrap items-start justify-between gap-3">
        <div className="min-w-0">
          <div className="flex items-center gap-2">
            <div className="font-semibold text-gray-900">{offerName(bid)}</div>
            {isAccepted && (
              <span className="inline-flex items-center gap-1 rounded-full bg-emerald-100 px-2 py-0.5 text-xs font-medium text-emerald-700">
                <CheckCircle2 className="h-3 w-3" /> Accepted
              </span>
            )}
          </div>
          {/* The loading city is commercial information the buyer needs to
              judge an offer; it does not name the seller. */}
          {(bid.ex_works_city || bid.seller?.city) && (
            <div className="text-xs text-gray-500">
              Loads from {bid.ex_works_city || bid.seller?.city}
            </div>
          )}
        </div>
        <div className="text-right">
          <div className="text-lg font-bold text-gray-900">
            {fmtINR(bid.for_price ?? bid.base_price)}
          </div>
          <div className="text-xs text-gray-500">
            {bid.for_price != null ? "F.O.R price" : "Base price"}
          </div>
        </div>
      </div>

      <dl className="mt-4 grid grid-cols-2 gap-3 text-sm sm:grid-cols-4">
        <Stat label="Ex-works" value={fmtINR(bid.ex_works_price ?? bid.base_price)} />
        <Stat label="Freight" value={fmtINR(bid.freight_charges ?? bid.transport_price)} />
        <Stat label="Other charges" value={fmtINR(bid.other_charges ?? bid.commission)} />
        <Stat label="Total est." value={fmtINR(total)} highlight />
        <Stat label="Delivery" value={bid.delivery_by ?? "—"} />
        {bid.credit_days != null && <Stat label="Credit days" value={String(bid.credit_days)} />}
        {bid.price_validity && <Stat label="Valid till" value={bid.price_validity} />}
        {bid.load_within && <Stat label="Loading" value={bid.load_within} />}
        {bid.gst != null && <Stat label="GST" value={`${bid.gst}%`} />}
      </dl>

      {bid.description && (
        <p className="mt-3 rounded-lg bg-gray-50 p-3 text-xs text-gray-600">{bid.description}</p>
      )}

      <div className="mt-4 flex items-center justify-end gap-2">
        {!isAccepted && !disabled && (
          <button
            type="button"
            onClick={onAccept}
            className="rounded-lg bg-[#CC1414] px-4 py-2 text-sm font-medium text-white hover:bg-[#a30f0f]"
          >
            Accept &amp; Order
          </button>
        )}
      </div>
    </div>
  );
}

function Stat({ label, value, highlight }: { label: string; value: string; highlight?: boolean }) {
  return (
    <div>
      <dt className="text-xs uppercase text-gray-500">{label}</dt>
      <dd className={`mt-0.5 ${highlight ? "font-semibold text-[#CC1414]" : "text-gray-700"}`}>{value}</dd>
    </div>
  );
}

/**
 * Submit button, split out so `useFormStatus` has a form to read from — the hook
 * only reports on a form *above* the component calling it.
 */
function ConfirmButton({ disabled }: { disabled: boolean }) {
  const { pending } = useFormStatus();

  return (
    <button
      type="submit"
      disabled={pending || disabled}
      className="rounded-lg bg-[#CC1414] px-4 py-2 text-sm font-medium text-white hover:bg-[#a30f0f] disabled:opacity-50"
    >
      {pending ? "Confirming…" : "Confirm Order"}
    </button>
  );
}

function AcceptModal({
  enquiryId,
  bid,
  wallet,
  bookingPolicy,
  onClose,
}: {
  enquiryId: number;
  bid: ApiBidding;
  wallet: ApiWalletSummary | null;
  bookingPolicy: string;
  onClose: () => void;
}) {
  const defaultTotal = bidTotal(bid);
  const minToken = parseFloat(String(bid.required_booking_amount ?? 0)) || 0;

  const [totalAmount, setTotalAmount] = useState<string>(defaultTotal.toFixed(2));
  const [tokenAmount, setTokenAmount] = useState<string>(minToken > 0 ? String(minToken) : String(Math.round(defaultTotal * 0.1)));
  const [selectedWallet, setSelectedWallet] = useState<"cash_balance" | "credit_balance">("cash_balance");

  const balance = selectedWallet === "cash_balance"
    ? wallet?.cash_balance ?? 0
    : wallet?.credit_balance ?? 0;

  return (
    /* items-start + overflow on the backdrop: with `items-center` alone, a panel
       taller than the viewport (iOS keyboard open) overflows upward and the
       Confirm button becomes physically unreachable. */
    <div className="fixed inset-0 z-[100] flex items-start justify-center overflow-y-auto overscroll-contain bg-black/50 p-4 sm:items-center">
      <form action={acceptQuotation} className="my-auto w-full max-w-md rounded-xl bg-white p-5 shadow-xl sm:p-6">
        <input type="hidden" name="enquiry_id" value={enquiryId} />
        <input type="hidden" name="seller_quotation_id" value={bid.id} />
        <input type="hidden" name="selected_wallet" value={selectedWallet} />

        <h3 className="text-lg font-bold text-gray-900">Confirm Order</h3>
        <p className="mt-1 text-sm text-gray-600">
          Accepting <span className="font-medium">{offerName(bid)}</span> at{" "}
          <span className="font-medium">{fmtINR(bid.for_price ?? bid.base_price)}</span>. The seller is
          revealed once the order is confirmed.
        </p>

        <div className="mt-4 space-y-3">
          <div>
            <label className="mb-1 block text-sm font-medium text-gray-700">Total Order Amount (₹)</label>
            <input
              type="number"
              name="total_amount"
              value={totalAmount}
              placeholder="Enter total order amount"
              onChange={(e) => setTotalAmount(e.target.value)}
              min={1}
              className="w-full rounded-lg border border-gray-200 px-3 py-2 text-sm focus:border-[#CC1414] focus:outline-none"
            />
          </div>
          <div>
            <label className="mb-1 block text-sm font-medium text-gray-700">
              Token Amount (₹){minToken > 0 ? ` — min ${fmtINR(minToken)}` : ""}
            </label>
            <input
              type="number"
              name="token_amount"
              value={tokenAmount}
              placeholder="Enter token amount"
              onChange={(e) => setTokenAmount(e.target.value)}
              min={Math.max(1, minToken)}
              className="w-full rounded-lg border border-gray-200 px-3 py-2 text-sm focus:border-[#CC1414] focus:outline-none"
            />
          </div>
          <div>
            <label className="mb-1 block text-sm font-medium text-gray-700">Pay From</label>
            <div className="grid grid-cols-2 gap-2">
              {(["cash_balance", "credit_balance"] as const).map((w) => (
                <button
                  key={w}
                  type="button"
                  onClick={() => setSelectedWallet(w)}
                  className={`rounded-lg border p-3 text-left text-xs transition ${
                    selectedWallet === w
                      ? "border-[#CC1414] bg-red-50 text-[#CC1414]"
                      : "border-gray-200 hover:border-gray-300"
                  }`}
                >
                  <div className="flex items-center gap-1 font-medium">
                    <Wallet className="h-3 w-3" /> {w === "cash_balance" ? "Cash" : "Credit"}
                  </div>
                  <div className="mt-1 font-semibold text-gray-900">
                    {fmtINR(w === "cash_balance" ? wallet?.cash_balance ?? 0 : wallet?.credit_balance ?? 0)}
                  </div>
                </button>
              ))}
            </div>
            <p className="mt-1 text-xs text-gray-500">Available: {fmtINR(balance)}</p>
          </div>
        </div>

        <BookingTermsConsent policy={bookingPolicy} />

        <div className="mt-5 flex items-center justify-end gap-2">
          <button
            type="button"
            onClick={onClose}
            className="rounded-lg border border-gray-200 px-4 py-2 text-sm font-medium text-gray-700 hover:bg-gray-50"
          >
            Cancel
          </button>
          <ConfirmButton disabled={Number(tokenAmount) <= 0 || Number(totalAmount) <= 0} />
        </div>
      </form>
    </div>
  );
}
