"use client";

import { useEffect, useRef, useState } from "react";
import { useQueryClient } from "@tanstack/react-query";
import { useSession } from "@/auth/session-provider";
import { useSetAtom } from "jotai";
import { loginModalAtom } from "@/components/state/loginAtom";

import { BaseModal } from "@/components/modal";
import DynamicButton from "@/components/button";
import { payWithWallet, payWithGateway } from "@/actions/payment";
import {
  buildReturnPathForGatewayRequest,
  persistGatewayMetaFromGatewayResponse,
} from "@/lib/payment-return";
import { createPurchaseOffer } from "@/actions/purchase-offers";
import { useAppToast, useNumberFormatter } from "@/app/[lang]/providers";
import { useLocale, useTranslations } from "next-intl";
import {
  getVaccinationStatusForDisplay,
  vaccinationStatusValueLabel,
} from "@/lib/animalVaccinationStatus";
import { usePaymentMethods, useWalletBalances } from "@/lib/clientQueries";
import { useApplePayVisible } from "@/lib/platform";
import TopUpModal from "@/components/sections/wallet/TopUpModal";
import PaymentGatewayModal from "@/components/payment/PaymentGatewayModal";
import PaddleElectronicPaymentInfo from "@/components/paddles/PaddleElectronicPaymentInfo";
import {
  Wallet,
  CreditCard,
  CheckCircle2,
  Send,
  MapPin,
  Gavel,
} from "lucide-react";

import MediaSection from "./parts/Media";
import InfoSection from "./parts/Info";
import CamelDetailsSection from "./parts/CamelDetails";
import DocumentsSection from "./parts/Documents";
import VideosSection from "./parts/Video";
import SidebarSection from "./parts/Sidebar";
import SellerReviewsSection from "@/components/reviews/SellerReviewsSection";
import RelatedItems from "./parts/RelatedItems";
import Modals from "./parts/Modals";
import { usePathname, useRouter } from "next/navigation";
import { useAuctionSocket } from "@/lib/socket/useAuctionSocket";
import {
  AuctionStatus,
  AuctionType as SocketAuctionType,
  Bidder,
} from "@/lib/socket/types";
import { getSocket } from "@/lib/socket/socketClient";
import { validateBidDelta } from "@/lib/auction/biddingRules";
import {
  playAuctionSound,
  resolveBidSoundAnimalType,
} from "@/lib/utils/soundPlayer";
import axios from "axios";
import Money from "@/components/ui/Money";
import MobileActionBar, {
  MobileActionBarPrice,
  MobileActionBarButton,
} from "@/components/ui/MobileActionBar";
import AuctionUnifiedTimer from "@/components/count/AuctionUnifiedTimer";
import type { AuctionItem } from "./types";
import { usePaymentSuccess } from "@/hooks/usePaymentSuccess";
import { API_BASE_URL } from "@/lib/axios";
import { parseMoneyValue, toMoneyNumber } from "@/lib/moneyParse";

const API_URL = API_BASE_URL;

const parseAuctionDateMs = (raw: unknown): number | null => {
  if (!raw) return null;
  if (raw instanceof Date) {
    const ms = raw.getTime();
    return Number.isFinite(ms) ? ms : null;
  }

  const value = String(raw).trim();
  if (!value) return null;

  if (/^\d+$/.test(value)) {
    const n = Number(value);
    if (!Number.isFinite(n)) return null;
    return value.length <= 10 ? n * 1000 : n;
  }

  const normalized = value.includes("T") ? value : value.replace(" ", "T");
  const ms = new Date(normalized).getTime();
  return Number.isFinite(ms) ? ms : null;
};

const TERMINAL_AUCTION_STATUS_SET = new Set<string>([
  "ended",
  "closed",
  "unsold",
  "sold",
  "withdrawn",
]);

const normalizeAuctionStatusToken = (raw: unknown): string | null => {
  if (raw == null) return null;
  const s = String(raw).trim().toLowerCase();
  return s || null;
};

/**
 * REST is authoritative for “auction already finished”; realtime may briefly send
 * stale `active` / `upcoming` after join, which would hide post-auction actions (e.g. purchase offer).
 */
const getRestTerminalAuctionStatus = (
  auctionItem: AuctionItem,
): AuctionStatus | null => {
  // Only `auction_state` represents the auction lifecycle.
  // `item.status` is the listing/review status (e.g. "accepted") and
  // `item.state` is geographic — neither should override realtime status.
  const n = normalizeAuctionStatusToken(auctionItem?.auction_state);
  if (n && TERMINAL_AUCTION_STATUS_SET.has(n)) {
    return n as AuctionStatus;
  }
  return null;
};

export const getAuctionStatusLabel = (
  status: string | undefined,
  locale: string,
) => {
  const isArUi = locale === "ar";
  switch (status) {
    case "active":
      return isArUi ? "نشط" : "Active";
    case "upcoming":
      return isArUi ? "قادم" : "Upcoming";
    case "ended":
      return isArUi ? "منتهي" : "Ended";
    case "withdrawn":
      return isArUi ? "منسحب" : "Withdrawn";
    case "closed":
      return isArUi ? "مغلق" : "Closed";
    case "accepted":
      return isArUi ? "مقبول" : "Accepted";

    case "sold":
      return isArUi ? "مباع" : "Sold";
    case "unsold":
      return isArUi ? "غير مباع" : "Unsold";
    default:
      return isArUi ? "غير معروف" : "Unknown";
  }
};
export type AuctionClosedOverlayData = {
  winnerName: string | null;
  winnerPaddleUniqueId?: string | null;
  winnerPaddleNumber?: string | number | null;
  finalPrice: number;
  reason: string;
};

export default function AuctionClient({
  item,
  onAuctionClosed,
}: {
  item: AuctionItem;
  onAuctionClosed?: (data: AuctionClosedOverlayData) => void;
}) {
  const session = useSession();
  const setLoginModal = useSetAtom(loginModalAtom);
  const pathname = usePathname();
  const router = useRouter();
  const isDashboard = pathname.includes("dashboard");
  const toast = useAppToast();
  const locale = useLocale();
  const isAr = locale === "ar";
  const tAuction = useTranslations("AUCTION");
  const tToast = useTranslations("TOAST");
  const tPaddle = useTranslations("PADDLE_PURCHASE");
  const tModals = useTranslations("SINGLE_AUCTION.MODALS");
  const tHorseDetails = useTranslations("HORSES_DETAILS");
  const tVax = useTranslations("ANIMAL_VACCINATION_STATUS");
  const tStep4 = useTranslations("ADD_LISTING.STEP4");
  const tPayment = useTranslations("PAYMENT");
  const queryClient = useQueryClient();
  const { toLatinDigits } = useNumberFormatter();
  const [confirmBidOpen, setConfirmBidOpen] = useState(false);
  const [successOpen, setSuccessOpen] = useState(false);
  const [notLoggedInModal, setNotLoggedInModal] = useState(false);
  const [postBidInfoOpen, setPostBidInfoOpen] = useState(false);
  const [deadlineText, setDeadlineText] = useState("");
  const [isClosed, setIsClosed] = useState(false);

  // Purchase offer state
  const [sendOfferModalOpen, setSendOfferModalOpen] = useState(false);
  const [offerAmount, setOfferAmount] = useState<string>("");
  const [sendingOffer, setSendingOffer] = useState(false);

  const isOwner = Boolean(item?.is_owner);
  const [canBuyPaddle, setCanBuyPaddle] = useState(
    Boolean(item?.can_buy_paddle) && !Boolean(item?.is_owner),
  );
  const [buyingPaddle, setBuyingPaddle] = useState(false);
  const [buyPaddleModalOpen, setBuyPaddleModalOpen] = useState(false);
  const { data: walletBalances } = useWalletBalances();

  const payment_purpose = "publish_auction";
  usePaymentMethods(payment_purpose);

  const wallet = toMoneyNumber(walletBalances?.available_balance, 0);
  const REQUIRED = toMoneyNumber(item?.paddle_price, 0);

  const topUpShortfall = Math.max(0, REQUIRED - wallet);

  const getAnimalTypeLabel = (
    typeValue: unknown,
    genderValue: unknown,
  ): string => {
    const type = String(typeValue || "").trim();
    const gender = String(genderValue || "").trim();

    if (!type) return "—";

    if (type === "breeding_female")
      return tStep4("type_options.horse_breeding_female");
    if (type === "non_breeding_female")
      return tStep4("type_options.horse_non_breeding_female");
    if (type === "male") return tStep4("type_options.male");
    if (type === "castrated") return tStep4("type_options.castrated");
    if (type === "foal_male") return tStep4("type_options.foal_male");
    if (type === "foal_female") return tStep4("type_options.foal_female");
    return type;
  };

  const [showBalanceModal, setShowBalanceModal] = useState(false);
  const [showTopUpModal, setShowTopUpModal] = useState(false);
  const [topUpNoticeOpen, setTopUpNoticeOpen] = useState(false);
  const applePayVisible = useApplePayVisible();
  const [paddlePaymentMethod, setPaddlePaymentMethod] = useState<
    "wallet" | "gateway" | "apple_pay"
  >("gateway");
  const [paddleGatewayUrl, setPaddleGatewayUrl] = useState<string | null>(null);
  const canAffordPaddle = REQUIRED <= 0 || wallet >= REQUIRED;

  // Owner controls (dashboard only)
  const [ownerWithdrawOpen, setOwnerWithdrawOpen] = useState(false);
  const [ownerWithdrawSaving, setOwnerWithdrawSaving] = useState(false);

  const backendPaddleNumberRaw = item?.paddle_number as
    | string
    | number
    | null
    | undefined;
  const backendPaddleNumberNumeric =
    backendPaddleNumberRaw != null &&
    String(backendPaddleNumberRaw).trim() !== "" &&
    Number.isFinite(Number(backendPaddleNumberRaw))
      ? Number(backendPaddleNumberRaw)
      : null;

  const [paddleNumber, setPaddleNumber] = useState<number | null>(
    backendPaddleNumberNumeric,
  );
  const [paddleUniqueId, setPaddleUniqueId] = useState<string | null>(
    item?.paddle_unique_id || null,
  );
  // Optimistic flag to unblock bidding immediately after purchasing a paddle
  const [paddlePurchased, setPaddlePurchased] = useState(false);
  useEffect(() => {
    setPaddlePurchased(false);
  }, [item?.id]);
  const [currentPrice, setCurrentPrice] = useState<number>(
    toMoneyNumber(item?.last_price ?? item?.current_price, 0),
  );

  const [bidders, setBidders] = useState<Bidder[]>([]);

  const [bidDelta, setBidDelta] = useState<number>(0);

  // --- New NestJS realtime fields ---
  // Detect auction type from various possible field names the REST API might use
  const initialAuctionType = ((): SocketAuctionType => {
    const raw = item?.auction_type;
    const lowered = String(raw).toLowerCase();
    // Check for "live" variations (including Arabic "مباشر")
    if (lowered === "live") {
      return "live";
    }
    return "electronic";
  })();
  const [auctionType, setAuctionType] =
    useState<SocketAuctionType>(initialAuctionType);

  const [auctionStatus, setAuctionStatus] = useState<AuctionStatus>(
    (item?.auction_state as AuctionStatus) || "upcoming",
  );
  const [highestBidder, setHighestBidder] = useState<{
    id: string;
    name: string;
    paddleNumber?: string | number | null;
  } | null>(null);
  const [endTimeMs, setEndTimeMs] = useState<number | null>(null);
  const [closeAtMs, setCloseAtMs] = useState<number | null>(null);
  const [reserveTriggered, setReserveTriggered] = useState<boolean>(false);
  const [closeReason, setCloseReason] = useState<string | null>(null);
  const parsePrice = (value: unknown): number | null => {
    const n = parseMoneyValue(value);
    return n !== undefined && n > 0 ? n : null;
  };

  const [marketEntryPrice, setMarketEntryPrice] = useState<number | null>(() =>
    parsePrice(item?.market_entry_price),
  );
  const offerSubmissionBlocked =
    auctionStatus === "active" || auctionStatus === "upcoming";
  const activeOfferWarning = isAr
    ? "أثناء المزاد النشط لا يمكن تقديم طلب شراء من هنا، والمزايدة تتم من الريل تايم."
    : "During an active auction, sending a purchase request is not available here. Bidding is handled through realtime.";
  const upcomingOfferWarning = isAr
    ? "قبل بدء المزاد لا يمكن تقديم طلب شراء من هنا."
    : "Before the auction starts, sending a purchase request is not available here.";
  const offerSubmissionBlockedWarning = auctionStatus === "active"
    ? activeOfferWarning
    : upcomingOfferWarning;

  const reserveTriggeredRef = useRef<boolean>(false);
  const lastTimerResetToastAtRef = useRef<number>(0);
  const lastClosedOverlayKeyRef = useRef<string>("");

  const emitAuctionClosedOverlay = ({
    winnerName,
    winnerPaddleNumber,
    finalPrice,
    reason,
  }: {
    winnerName: string | null;
    winnerPaddleNumber?: string | number | null;
    finalPrice: number;
    reason: string;
  }) => {
    const payloadKey = [
      auctionId,
      winnerName || "",
      winnerPaddleNumber != null ? String(winnerPaddleNumber) : "",
      String(finalPrice || 0),
      reason || "",
    ].join(":");

    if (payloadKey === lastClosedOverlayKeyRef.current) return;
    lastClosedOverlayKeyRef.current = payloadKey;

    onAuctionClosed?.({
      winnerName,
      winnerPaddleUniqueId: null,
      winnerPaddleNumber: winnerPaddleNumber ?? null,
      finalPrice,
      reason,
    });
  };

  // --- Socket Integration ---
  // Allow socket connection even for unauthenticated users to view auction updates
  const token = session?.access_token;
  const auctionId = item?.id ? String(item.id) : "";

  // Pay paddle / wallet: Laravel expects `auction_type: annual` only for yearly-mazad flows
  // (with `type_paddle`, etc.). `is_group` on a listing is NOT the same as "annual" — e.g. camel
  // group listings can have `is_group: true` while the auction is still a regular single auction.
  const backendAuctionType: "normal" | "annual" = (() => {
    const at = String(item?.auction_type ?? "").trim().toLowerCase();
    return at === "annual" ? "annual" : "normal";
  })();

  const hasReservedPaddle = Boolean(
    paddleNumber ||
    paddleUniqueId ||
    (backendPaddleNumberRaw != null &&
      String(backendPaddleNumberRaw).trim() !== ""),
  );

  const refreshAuctionAfterPaddlePurchase = () => {
    queryClient.invalidateQueries({ queryKey: ["user-paddles"] });
    queryClient.invalidateQueries({
      queryKey: ["available-paddles", auctionId, backendAuctionType],
    });
    queryClient.invalidateQueries({ queryKey: ["wallet-balances"] });
    router.refresh();
  };

  // Derive paddle number and unique_id from existing data only
  const derivedPaddleNumber = (() => {
    if (paddleNumber) return paddleNumber;
    // Fallback to item data if available
    if (item?.paddle_number) {
      const raw = item.paddle_number;
      const n = Number(raw);
      if (Number.isFinite(n)) return n;
    }
    return null;
  })();

  usePaymentSuccess({
    successMessage:
      locale === "ar"
        ? "تم شراء المضرب بنجاح"
        : "Paddle purchased successfully",
    onSuccess: refreshAuctionAfterPaddlePurchase,
  });

  const derivedPaddleUniqueId = (() => {
    if (paddleUniqueId) return paddleUniqueId;
    // Fallback to item data if available
    if (item?.paddle_unique_id) {
      return item.paddle_unique_id;
    }
    return null;
  })();

  const hasPaddleForThisAuction = hasReservedPaddle || paddlePurchased;
  const needsPaddle =
    !isOwner && !hasPaddleForThisAuction && Boolean(item?.can_buy_paddle);

  // Keep local state in sync so Sidebar shows correct button.
  useEffect(() => {
    if (hasPaddleForThisAuction) {
      setCanBuyPaddle(false);
      if (!paddleNumber && derivedPaddleNumber)
        setPaddleNumber(derivedPaddleNumber);
      if (!paddleUniqueId && derivedPaddleUniqueId)
        setPaddleUniqueId(derivedPaddleUniqueId);
    } else {
      setCanBuyPaddle(
        Boolean(item?.can_buy_paddle) && !Boolean(item?.is_owner),
      );
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [
    auctionId,
    item?.can_buy_paddle,
    item?.is_owner,
    hasPaddleForThisAuction,
    derivedPaddleNumber,
    derivedPaddleUniqueId,
  ]);

  const [socketConnected, setSocketConnected] = useState(false);
  const [receivedInitialState, setReceivedInitialState] = useState(false);
  const bidSoundAnimalTypeRef = useRef<"horse" | "camel">("horse");
  useEffect(() => {
    bidSoundAnimalTypeRef.current = resolveBidSoundAnimalType(item);
  }, [item]);
  const { placeBid: socketPlaceBid } = useAuctionSocket({
    auctionId,
    token,

    onState: (payload) => {
      setSocketConnected(true);
      setReceivedInitialState(true);
      setAuctionType(payload.type);
      const restTerminal = getRestTerminalAuctionStatus(item);
      const incoming = payload.status;
      if (
        restTerminal &&
        (incoming === "active" || incoming === "upcoming")
      ) {
        setAuctionStatus(restTerminal);
      } else {
        setAuctionStatus(incoming);
      }
      setCurrentPrice(toMoneyNumber(payload.currentPrice, 0));
      setHighestBidder(payload.highestBidder);
      // Some backends might send null even when REST `item.market_entry_price` exists; keep existing fallback.
      if (payload.marketEntryPrice != null) {
        const me = parseMoneyValue(payload.marketEntryPrice);
        if (me !== undefined) setMarketEntryPrice(me);
      }
      setEndTimeMs(payload.endTimeMs);
      // IMPORTANT: Don't wipe a local fallback countdown if backend isn't providing closeAtMs/reserveTriggered yet.
      // Only apply server values when they are explicitly provided (non-null).
      if (payload.closeAtMs != null) {
        setCloseAtMs(payload.closeAtMs);
      }

      const prevReserveTriggered = reserveTriggeredRef.current;
      if (payload.reserveTriggered != null) {
        const nextReserveTriggered = Boolean(payload.reserveTriggered);
        setReserveTriggered(nextReserveTriggered);
        reserveTriggeredRef.current = nextReserveTriggered;
        if (!nextReserveTriggered) setCloseAtMs(null);
      }
      const derivedCloseReason =
        payload.reason ||
        (payload.status === "withdrawn"
          ? "withdrawn"
          : payload.status === "closed" && payload.reserveTriggered
            ? "reserve_timeout"
            : null);
      if (derivedCloseReason) setCloseReason(derivedCloseReason);

      const mappedBidders: Bidder[] = payload.bids.map((b) => ({
        name: b.bidderName || "مزايد",
        paddle: b.paddleNumber || 0, // Backend might not send paddle if privacy is concerned, but interface expects it
        amount: b.amount,
        timestamp: b.timestamp,
        id: b.userId,
      }));
      setBidders(mappedBidders);

      // Detect live reserve countdown start transition from state snapshot
      if (
        payload.auctionType === "live" &&
        payload.reserveTriggered === true &&
        payload.closeAtMs != null &&
        prevReserveTriggered === false
      ) {
        toast.warning(tAuction("countdown_started"));
      }

      if (
        payload.status === "closed" ||
        payload.status === "ended" ||
        payload.status === "withdrawn"
      ) {
        setIsClosed(true);
        // When auction ends, clear any local countdown.
        setReserveTriggered(false);
        reserveTriggeredRef.current = false;
        setCloseAtMs(null);

        emitAuctionClosedOverlay({
          winnerName:
            payload.highestBidder?.name ??
            item?.winner_name ??
            item?.highest_bidder_name ??
            null,
          winnerPaddleNumber:
            payload.highestBidder?.paddleNumber ??
            payload.highestBidder?.paddle_number ??
            item?.winner_paddle_number ??
            item?.highest_bidder_paddle_number ??
            null,
          finalPrice: toMoneyNumber(
            payload.currentPrice ?? currentPrice,
            0,
          ),
          reason:
            derivedCloseReason ||
            (payload.highestBidder ? "reserve_timeout" : "time"),
        });
      }
    },
    onBidCreated: (payload) => {
      playAuctionSound(bidSoundAnimalTypeRef.current);

      setCurrentPrice(toMoneyNumber(payload.amount, 0));
      const paddleFromBid =
        payload.bidder.paddleNumber ?? payload.bidder.paddle_number ?? null;
      setHighestBidder({
        id: String(payload.bidder.id),
        name: payload.bidder.name || "مزايد",
        paddleNumber: paddleFromBid,
      });
      const newBidder: Bidder = {
        name: payload.bidder.name || "مزايد",
        paddle: paddleFromBid ?? 0,
        amount: payload.amount,
        timestamp: payload.timestamp,
        id: payload.bidder.id,
      };
      setBidders((prev) => [newBidder, ...prev]);

      if (payload.closeAtMs !== undefined) {
        setCloseAtMs(payload.closeAtMs ?? null);
        // Throttle reset toast to avoid spamming on frequent bids
        const now = Date.now();
        if (
          payload.closeAtMs &&
          now - lastTimerResetToastAtRef.current > 7000
        ) {
          toast.info(tAuction("timer_reset"));
          lastTimerResetToastAtRef.current = now;
        }
      } else {
        // Client-side fallback: if live auction countdown is active but server didn't provide closeAtMs,
        // reset locally on each bid after market_entry_price is reached.
        if (auctionType === "live") {
          const effectiveMarketEntryPrice =
            marketEntryPrice ?? parsePrice(item?.market_entry_price);
          const bidAmountNum = toMoneyNumber(payload.amount, 0);
          const shouldRunLocalCountdown =
            reserveTriggeredRef.current ||
            (effectiveMarketEntryPrice != null &&
              bidAmountNum >= effectiveMarketEntryPrice);
          if (shouldRunLocalCountdown) {
            const nextCloseAt = Date.now() + 30_000;
            setReserveTriggered(true);
            reserveTriggeredRef.current = true;
            setCloseAtMs(nextCloseAt);

            const now = Date.now();
            if (now - lastTimerResetToastAtRef.current > 7000) {
              toast.info(tAuction("timer_reset"));
              lastTimerResetToastAtRef.current = now;
            }
          }
        }
      }
      if (payload.endTimeMs !== undefined) {
        setEndTimeMs(payload.endTimeMs ?? null);
      }
    },
    onClosed: (payload) => {
      setIsClosed(true);
      setCurrentPrice(toMoneyNumber(payload.finalPrice, 0));
      setAuctionStatus("closed");
      setCloseReason(payload.reason || null);
      const winnerName =
        payload.winner?.name ?? highestBidder?.name ?? item?.winner_name ?? null;
      const winnerPaddleNumber =
        payload.winner?.paddle_number ??
        payload.winner?.paddleNumber ??
        payload.winner_paddle_number ??
        highestBidder?.paddleNumber ??
        item?.winner_paddle_number ??
        item?.highest_bidder_paddle_number ??
        null;

      if (payload.winner) {
        setHighestBidder({
          id: String(payload.winner.id),
          name: winnerName || payload.winner.name,
          paddleNumber:
            winnerPaddleNumber,
        });
      } else if (payload.winnerId && highestBidder?.id === payload.winnerId) {
        setHighestBidder((prev) =>
          prev
            ? {
                ...prev,
                paddleNumber:
                  prev.paddleNumber ?? winnerPaddleNumber ?? null,
              }
            : prev,
        );
      }

      emitAuctionClosedOverlay({
        winnerName,
        winnerPaddleNumber,
        finalPrice: toMoneyNumber(payload.finalPrice ?? currentPrice, 0),
        reason: payload.reason || "time",
      });

      const r = String(payload.reason || "");
      if (r.includes("withdrawn")) toast.warning(tAuction("withdrawn"));
      else if (r.includes("reserve_timeout"))
        toast.warning(tAuction("ended_reserve"));
      else if (r.includes("owner_close_below_reserve"))
        toast.warning(tAuction("below_reserve"));
      else if (r.includes("time")) toast.warning(tAuction("ended_time"));
      else toast.warning(tAuction("closed"));
    },
    onExtended: (payload) => {
      setEndTimeMs(payload.newEndTimeMs);
      toast.info(tAuction("auction_extended"));
    },
    onReserveTriggered: (payload) => {
      setReserveTriggered(true);
      reserveTriggeredRef.current = true;
      setCloseAtMs(payload.closeAtMs);
      toast.warning(tAuction("countdown_started"));
    },
    onError: (payload) => {
      toast.error(payload.message || tAuction("socket_connection_error"));
    },
  });

  // Client-side fallback: start 30s countdown once currentPrice reaches market_entry_price,
  // in case backend doesn't send reserveTriggered/closeAtMs yet.
  // Only applies when market_entry_price is set (i.e., live auctions).
  useEffect(() => {
    if (auctionStatus !== "active") return;
    const effectiveMarketEntryPrice =
      marketEntryPrice ?? parsePrice(item?.market_entry_price);
    if (effectiveMarketEntryPrice == null) return; // no market entry price means no countdown trigger
    if (reserveTriggeredRef.current) return; // already triggered
    if (closeAtMs != null) return; // server already provided closeAtMs
    if (currentPrice < effectiveMarketEntryPrice) return; // not reached yet

    const nextCloseAt = Date.now() + 30_000;
    setReserveTriggered(true);
    reserveTriggeredRef.current = true;
    setCloseAtMs(nextCloseAt);
    toast.warning(tAuction("countdown_started"));
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [auctionStatus, marketEntryPrice, currentPrice, closeAtMs]);

  const handleBidClick = () => {
    if (!session) {
      setNotLoggedInModal(true);
      return;
    }
    if (isOwner) {
      toast.warning(tAuction("toast_owner_cannot_bid"));
      return;
    }
    // اذا كان المستخدم ما زال بحاجة لشراء مضرب، لا نسمح له بالمزايدة
    if (needsPaddle) {
      toast.warning(tAuction("toast_paddle_required_bid"));
      return;
    }
    if (auctionStatus !== "active") {
      toast.warning(tAuction("not_active"));
      return;
    }
    if (isClosed) {
      toast.warning(tAuction("toast_auction_closed_short"));
      return;
    }
    setConfirmBidOpen(true);
  };

  // Handler for when user clicks "Buy Paddle" button
  const handleBuyPaddle = () => {
    if (!session) {
      setNotLoggedInModal(true);
      return;
    }

    if (isOwner) {
      toast.warning(tAuction("toast_owner_cannot_buy_paddle"));
      return;
    }
    // If we already have a paddle for this auction, don't call the API again.
    if (hasPaddleForThisAuction) {
      setCanBuyPaddle(false);
      setBuyPaddleModalOpen(false);
      toast.info(tAuction("toast_paddle_already_owned"));
      return;
    }

    if (!item?.id) {
      toast.error(tAuction("toast_auction_id_missing"));
      return;
    }

    setBuyPaddleModalOpen(true);
  };

  // Handler for purchasing a new paddle (supports wallet & gateway)
  const handlePurchaseNewPaddle = async () => {
    if (!item?.id) {
      toast.error(tAuction("toast_auction_id_missing"));
      return;
    }

    try {
      setBuyingPaddle(true);

      // Gateway / Apple Pay flow
      if (
        paddlePaymentMethod === "gateway" ||
        paddlePaymentMethod === "apple_pay"
      ) {
        try {
          const returnPath = buildReturnPathForGatewayRequest() ?? "/";
          const res = await payWithGateway({
            payment_purpose: "pay_paddle_fee",
            auction_id: String(item.id),
            auction_type: backendAuctionType,
            payment_method:
              paddlePaymentMethod === "apple_pay"
                ? "apple_pay"
                : "online_payment",
            return_path: returnPath,
          });
          const gatewayUrl =
            (res as any)?.data?.payment_url || (res as any)?.data?.redirect_url;
          if ((res as any)?.success && gatewayUrl) {
            persistGatewayMetaFromGatewayResponse(
              (res as any)?.data as Record<string, unknown>,
              returnPath,
            );
            toast.success(tAuction("toast_redirecting_payment_gateway"));
            setPaddleGatewayUrl(gatewayUrl);
            setBuyPaddleModalOpen(false);
          } else {
            const msg =
              (res as any)?.message || tToast("gateway_open_failed");
            toast.error(msg);
          }
        } catch (e: any) {
          toast.error(
            e?.message || tAuction("toast_payment_generic_error"),
          );
        } finally {
          setBuyingPaddle(false);
        }
        return;
      }

      // Wallet payment flow
      if (wallet < REQUIRED) {
        setBuyPaddleModalOpen(false);
        setShowTopUpModal(true);
        return;
      }

      const res = await payWithWallet({
        payment_purpose: "pay_paddle_fee",
        auction_id: String(item.id),
        auction_type: backendAuctionType,
      });

      if ((res as any)?.success) {
        toast.success(
          res?.message || tAuction("toast_paddle_purchased"),
        );
        setPaddlePurchased(true);
        setCanBuyPaddle(false);
        setBuyPaddleModalOpen(false);
        if (!offerSubmissionBlocked) {
          setSendOfferModalOpen(true);
        }

        // رقم المضرب: نحاول من الـ response أولاً
        const apiPaddleRaw =
          (res as any)?.data?.paddle_number ?? (res as any)?.paddle_number;
        const apiPaddleUniqueId =
          (res as any)?.data?.paddle_unique_id ??
          (res as any)?.data?.unique_id ??
          (res as any)?.paddle_unique_id ??
          null;
        const apiPaddleNum = Number(apiPaddleRaw);
        if (Number.isFinite(apiPaddleNum) && apiPaddleNum > 0) {
          setPaddleNumber(apiPaddleNum);
        }
        if (apiPaddleUniqueId) {
          setPaddleUniqueId(String(apiPaddleUniqueId));
        }

        // If paddle number wasn't in purchase response, re-fetch auction to get it
        if (
          !(Number.isFinite(apiPaddleNum) && apiPaddleNum > 0) ||
          !apiPaddleUniqueId
        ) {
          try {
            const freshToken = session?.access_token;
            const auctionRes = await axios.get(
              `${API_URL}/user/auctions/${auctionId}`,
              {
                headers: {
                  Authorization: freshToken ? `Bearer ${freshToken}` : "",
                  Accept: "application/json",
                  lang: locale,
                },
              },
            );
            const freshData = auctionRes?.data?.data;
            if (freshData) {
              const freshPaddleNum = Number(freshData.paddle_number);
              if (Number.isFinite(freshPaddleNum) && freshPaddleNum > 0) {
                setPaddleNumber(freshPaddleNum);
              }
              if (freshData.paddle_unique_id) {
                setPaddleUniqueId(String(freshData.paddle_unique_id));
              }
            }
          } catch {
            // Non-critical: paddle number will show on next page load
          }
        }

        refreshAuctionAfterPaddlePurchase();
      } else {
        const msg =
          (res as any)?.message ||
          (res as any)?.errors ||
          tToast("paddle_purchase_failed");

        // If backend says paddle already exists, just sync UI and unblock bidding.
        if (
          String(msg).includes("active paddle") ||
          String(msg).includes("مضرب فعال")
        ) {
          toast.info(tAuction("toast_paddle_already_owned"));
          setPaddlePurchased(true);
          setCanBuyPaddle(false);
          setBuyPaddleModalOpen(false);
          if (!offerSubmissionBlocked) {
            setSendOfferModalOpen(true);
          }
          // Re-fetch auction to get paddle number
          try {
            const freshToken = session?.access_token;
            const auctionRes = await axios.get(
              `${API_URL}/user/auctions/${auctionId}`,
              {
                headers: {
                  Authorization: freshToken ? `Bearer ${freshToken}` : "",
                  Accept: "application/json",
                  lang: locale,
                },
              },
            );
            const freshData = auctionRes?.data?.data;
            if (freshData) {
              const freshPaddleNum = Number(freshData.paddle_number);
              if (Number.isFinite(freshPaddleNum) && freshPaddleNum > 0) {
                setPaddleNumber(freshPaddleNum);
              }
              if (freshData.paddle_unique_id) {
                setPaddleUniqueId(String(freshData.paddle_unique_id));
              }
            }
          } catch {
            // ignore
          }
          refreshAuctionAfterPaddlePurchase();
          return;
        }

        toast.error(String(msg));
      }
    } catch (e: any) {
      const msg =
        e?.info?.errors ||
        e?.info?.message ||
        e?.message ||
        tToast("paddle_purchase_failed");

      if (
        String(msg).includes("active paddle") ||
        String(msg).includes("مضرب فعال")
      ) {
        toast.info(tAuction("toast_paddle_already_owned"));
        setPaddlePurchased(true);
        setCanBuyPaddle(false);
        setBuyPaddleModalOpen(false);
        if (!offerSubmissionBlocked) {
          setSendOfferModalOpen(true);
        }
        refreshAuctionAfterPaddlePurchase();
        return;
      }

      toast.error(String(msg));
    } finally {
      setBuyingPaddle(false);
    }
  };

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

    const start = Date.now();
    const threeDaysMs = 3 * 24 * 60 * 60 * 1000;

    const update = () => {
      const remain = Math.max(0, threeDaysMs - (Date.now() - start));
      if (remain === 0) {
        setDeadlineText("انتهت المهلة");
        return;
      }
      const d = Math.floor(remain / 86400000);
      const h = Math.floor((remain % 86400000) / 3600000);
      const m = Math.floor((remain % 3600000) / 60000);
      setDeadlineText(`${d} يوم و ${h} ساعة و ${m} دقيقة`);
    };

    update();
    const t = setInterval(update, 60000);
    return () => clearInterval(t);
  }, [postBidInfoOpen]);

  const confirmBid = () => {
    if (!session) {
      setNotLoggedInModal(true);
      return;
    }
    if (isOwner) {
      toast.warning(tAuction("toast_owner_cannot_bid"));
      return;
    }
    if (needsPaddle) {
      toast.warning(tAuction("toast_paddle_required_bid"));
      setBuyPaddleModalOpen(true);
      return;
    }
    if (auctionStatus !== "active") {
      toast.warning(tAuction("not_active"));
      setConfirmBidOpen(false);
      return;
    }
    if (isClosed) {
      toast.warning(tAuction("toast_auction_closed_short"));
      return;
    }

    // Validate increment (pass marketEntryPrice for special condition: if < 1000, min bid is 500)
    const effectiveMarketEntryPrice =
      marketEntryPrice ?? parsePrice(item?.market_entry_price);
    const validation = validateBidDelta(
      bidDelta,
      currentPrice,
      effectiveMarketEntryPrice,
    );
    if (!validation.valid) {
      toast.warning(
        validation.error || tAuction("toast_invalid_bid_increment"),
      );
      return;
    }

    // Calculate final bid
    const finalBid = currentPrice + bidDelta;

    // Emit bid via socket with final total
    socketPlaceBid(finalBid);

    // Reset and close
    setBidDelta(0);
    setConfirmBidOpen(false);

    // Show info toast
    toast.info(tAuction("toast_submitting_bid"));
  };

  const canOwnerEnterMarket =
    isDashboard &&
    isOwner &&
    auctionType === "live" &&
    auctionStatus === "active";

  const confirmOwnerWithdraw = async () => {
    if (!auctionId) return;
    try {
      setOwnerWithdrawSaving(true);
      const socket = getSocket(token);
      if (!socket.connected) socket.connect();
      socket.emit("auction:withdraw", { auctionId });
      toast.info(tAuction("toast_withdraw_request_submitted"));
      setOwnerWithdrawOpen(false);
    } finally {
      setOwnerWithdrawSaving(false);
    }
  };

  const confirmOwnerEnterMarket = async () => {
    if (!auctionId) return;
    try {
      const socket = getSocket(token);
      if (!socket.connected) socket.connect();
      // Backend will use current highest bid as market_entry_price
      socket.emit("auction:enterMarket", { auctionId });
      toast.info(tAuction("enter_market_request_sent"));
    } catch (error) {
      console.error("Error entering market:", error);
      toast.error(tAuction("toast_enter_market_error"));
    }
  };

  const closeSuccess = () => {
    setSuccessOpen(false);
    setPostBidInfoOpen(true);
  };

  const auctionLocation = [item?.country, item?.state]
    .filter(Boolean)
    .join(" - ");

  const mobileTimerMeta = (() => {
    const now = Date.now();

    if (
      isClosed ||
      auctionStatus === "ended" ||
      auctionStatus === "withdrawn" ||
      auctionStatus === "closed"
    ) {
      return { target: null as number | null, label: null as string | null };
    }

    if (reserveTriggered && closeAtMs && closeAtMs > now) {
      return {
        target: closeAtMs,
        label: tAuction("live_timer_label"),
      };
    }

    const startMs = parseAuctionDateMs(
      item?.auction_start_time ||
        item?.auction_start_datetime ||
        item?.auction_start_date,
    );
    const endMs =
      endTimeMs ||
      parseAuctionDateMs(
        item?.auction_end_time ||
          item?.auction_end_datetime ||
          item?.auction_end_date,
      );

    if (auctionStatus === "upcoming" && startMs && startMs > now) {
      return {
        target: startMs,
        label:
          locale === "ar" ? "العد التنازلي لبدء المزاد" : "Auction starts in",
      };
    }

    if (auctionStatus === "active" && endMs && endMs > now) {
      return {
        target: endMs,
        label: tAuction("electronic_timer_label"),
      };
    }

    return { target: null as number | null, label: null as string | null };
  })();

  return (
    <>
      {/* Mobile Bottom Action Bar for Auctions
          - Visible for active & upcoming auctions when user is not owner and auction not closed
          - Buying paddle does NOT require socket
          - Bidding still requires active socket & active auction */}
      {!isOwner &&
        !isClosed &&
        (auctionStatus === "active" || auctionStatus === "upcoming") && (
          <MobileActionBar>
            {mobileTimerMeta.target && mobileTimerMeta.label ? (
              <AuctionUnifiedTimer
                targetDate={mobileTimerMeta.target}
                label={mobileTimerMeta.label}
                variant="surface"
                compact
              />
            ) : null}
          </MobileActionBar>
        )}

      <main
        className="max-w-7xl mx-auto px-4 py-8 pb-28 sm:pb-8 space-y-8"
        dir={locale === "ar" ? "rtl" : "ltr"}
      >
        <section className="rounded-2xl border border-[#0F5132]/20 bg-gradient-to-br from-[#0F5132] via-[#155c3c] to-[#1d724b] p-5 sm:p-6 text-white shadow-[0_16px_40px_rgba(15,81,50,0.3)]">
          <div className="flex flex-col gap-4">
            <div className="flex items-center justify-between gap-3 flex-wrap">
              <div className="inline-flex items-center gap-2 text-sm text-white/90">
                <Gavel className="w-4 h-4" />
                <span>
                  {item?.unique_id
                    ? `${locale === "ar" ? "رقم المزاد" : "Auction ID"}: ${item.unique_id}`
                    : locale === "ar"
                      ? "تفاصيل المزاد"
                      : "Auction Details"}
                </span>
              </div>
              <div className="text-sm text-white/90 border border-white/20 rounded-full px-2 py-1">
                {getAuctionStatusLabel(
                  item?.auction_state as string | undefined,
                  locale,
                )}
              </div>
            </div>

            <h1 className="text-2xl sm:text-3xl font-extrabold leading-tight">
              {item?.title || (locale === "ar" ? "المزاد" : "Auction")}
            </h1>

            {auctionLocation ? (
              <div className="inline-flex items-center gap-2 text-sm text-white/90">
                <MapPin className="w-4 h-4" />
                <span>{auctionLocation}</span>
              </div>
            ) : null}
          </div>
        </section>

        <div className="grid lg:grid-cols-3 gap-6 items-start">
          <div className="lg:col-span-2 space-y-6">
            <MediaSection item={item} />
            <InfoSection item={item} />
            {item?.animal_type === "horse" &&
              !item?.is_group &&
              item?.horse && (
                <div className="bg-white rounded-2xl p-5 border border-[#0F5132]/12 shadow-[0_12px_30px_rgba(15,81,50,0.08)]">
                  <div className="text-lg font-bold text-[#0F5132] mb-3">
                    {tHorseDetails("horseInfo")}
                  </div>
                  <div className="grid md:grid-cols-2 gap-4">
                    <table className="w-full text-sm border border-slate-200 rounded-xl overflow-hidden bg-slate-50/30">
                      <tbody className="divide-y">
                        {item?.horse?.name && (
                          <tr>
                            <td className="p-3 text-slate-500 w-40">
                              {tHorseDetails("name")}
                            </td>
                            <td className="p-3 font-bold">{item.horse.name}</td>
                          </tr>
                        )}
                        {item?.horse?.breed && (
                          <tr>
                            <td className="p-3 text-slate-500">
                              {tHorseDetails("breed")}
                            </td>
                            <td className="p-3 font-bold">
                              {item.horse.breed}
                            </td>
                          </tr>
                        )}
                        {item?.horse?.gender && (
                          <tr>
                            <td className="p-3 text-slate-500">
                              {tHorseDetails("gender")}
                            </td>
                            <td className="p-3 font-bold">
                              {String(item.horse.gender) === "male"
                                ? tHorseDetails("male")
                                : String(item.horse.gender) === "female"
                                  ? tHorseDetails("female")
                                  : String(item.horse.gender)}
                            </td>
                          </tr>
                        )}
                        {item?.horse?.date_of_birth && (
                          <tr>
                            <td className="p-3 text-slate-500">
                              {tHorseDetails("dateOfBirth")}
                            </td>
                            <td className="p-3 font-bold">
                              {String(item.horse.date_of_birth)}
                            </td>
                          </tr>
                        )}
                        {item?.horse?.type && (
                          <tr>
                            <td className="p-3 text-slate-500">
                              {tHorseDetails("type")}
                            </td>
                            <td className="p-3 font-bold">
                              {getAnimalTypeLabel(
                                item.horse.type,
                                item.horse.gender,
                              )}
                            </td>
                          </tr>
                        )}
                      </tbody>
                    </table>

                    <table className="w-full text-sm border border-slate-200 rounded-xl overflow-hidden bg-slate-50/30">
                      <tbody className="divide-y">
                        {item?.horse?.height && (
                          <tr>
                            <td className="p-3 text-slate-500 w-40">
                              {tHorseDetails("height")}
                            </td>
                            <td className="p-3 font-bold">
                              {item.horse.height} سم
                            </td>
                          </tr>
                        )}
                        {item?.horse?.animal_color && (
                          <tr>
                            <td className="p-3 text-slate-500">
                              {tHorseDetails("color")}
                            </td>
                            <td className="p-3 font-bold">
                              {item.horse.animal_color}
                            </td>
                          </tr>
                        )}
                        {item?.horse?.animal_usage && (
                          <tr>
                            <td className="p-3 text-slate-500">
                              {tHorseDetails("usage")}
                            </td>
                            <td className="p-3 font-bold">
                              {item.horse.animal_usage}
                            </td>
                          </tr>
                        )}
                        {(() => {
                          const vax = getVaccinationStatusForDisplay(
                            item?.horse,
                          );
                          if (!vax) return null;
                          return (
                            <tr>
                              <td className="p-3 text-slate-500">
                                {tVax("label")}
                              </td>
                              <td className="p-3 font-bold">
                                {vaccinationStatusValueLabel(vax, tVax)}
                              </td>
                            </tr>
                          );
                        })()}
                      </tbody>
                    </table>
                  </div>
                </div>
              )}
            {item?.animal_type === "camel" && (
              <CamelDetailsSection item={item} />
            )}
            <DocumentsSection item={item} />
            <VideosSection item={item} />
          </div>

          <div className="space-y-6">
            <SidebarSection
              item={item}
              onBidClick={handleBidClick}
              postBidInfoOpen={postBidInfoOpen}
              deadlineText={deadlineText}
              canBuyPaddle={canBuyPaddle}
              paddlePrice={item?.paddle_price ?? undefined}
              onBuyPaddleClick={handleBuyPaddle}
              buyingPaddle={buyingPaddle}
              isOwner={isOwner}
              isDashboard={isDashboard}
              onOwnerWithdraw={() => setOwnerWithdrawOpen(true)}
              onOwnerEnterMarket={confirmOwnerEnterMarket}
              showOwnerEnterMarket={canOwnerEnterMarket}
              hideBidButton={isDashboard || isClosed}
              liveBidders={bidders}
              currentBidOverride={currentPrice}
              auctionType={auctionType}
              auctionStatus={auctionStatus}
              highestBidder={highestBidder}
              endTimeMs={endTimeMs}
              closeAtMs={closeAtMs}
              reserveTriggered={reserveTriggered}
              closeReason={closeReason}
              canSendOffer={
                !offerSubmissionBlocked &&
                (!session || paddlePurchased || Boolean(item?.can_send_offer))
              }
              onSendOfferClick={() => {
                if (offerSubmissionBlocked) {
                  toast.warning(offerSubmissionBlockedWarning);
                  return;
                }
                if (!session) {
                  setLoginModal(true);
                  return;
                }
                setSendOfferModalOpen(true);
              }}
            />
            {item?.id != null && String(item.id).trim() !== "" ? (
              <SellerReviewsSection
                offerableId={String(item.id)}
                offerableType="auctions"
                sellerLabel={
                  item?.owner?.name ?? item?.created_by?.name ?? undefined
                }
                summary={
                  item?.owner_review_summary
                    ? {
                        avg: Number(item.owner_review_summary.avg ?? 0),
                        count: Number(item.owner_review_summary.count ?? 0),
                      }
                    : null
                }
              />
            ) : null}
          </div>
        </div>

        <RelatedItems />

        {/* Owner withdraw modal (dashboard only) */}
        <BaseModal
          isOpen={ownerWithdrawOpen}
          onOpenChange={setOwnerWithdrawOpen}
          title={tModals("owner_withdraw_title")}
          contentClassName="w-[min(92vw,420px)] text-center"
          footer={
            <div className="flex justify-end gap-2">
              <DynamicButton
                onClick={() => setOwnerWithdrawOpen(false)}
                isDisabled={ownerWithdrawSaving}
                className="px-4 py-2 rounded-lg text-slate-700 bg-slate-100 hover:bg-slate-200"
              >
                {tModals("cancel")}
              </DynamicButton>
              <DynamicButton
                onClick={confirmOwnerWithdraw}
                isDisabled={ownerWithdrawSaving}
                className="px-4 py-2 rounded-lg bg-red-600 text-white"
              >
                {ownerWithdrawSaving ? "..." : tModals("confirm")}
              </DynamicButton>
            </div>
          }
        >
          <p className="text-slate-700 text-sm leading-7">
            {tModals("owner_withdraw_text")}
          </p>
        </BaseModal>

        <BaseModal
          isOpen={notLoggedInModal}
          onOpenChange={setNotLoggedInModal}
          title={tModals("login_required_title")}
          contentClassName="w-[min(92vw,400px)] text-center"
          footer={
            <DynamicButton
              onClick={() => {
                setNotLoggedInModal(false);
                setLoginModal(true);
              }}
              className="px-4 py-2 rounded-lg bg-[#0F5132] text-white hover:bg-[#0F5132]/90"
            >
              {tModals("ok")}
            </DynamicButton>
          }
        >
          <p className="text-slate-700 text-sm leading-7">
            {tModals("login_required_text")}
          </p>
        </BaseModal>

        <BaseModal
          isOpen={buyPaddleModalOpen}
          onOpenChange={setBuyPaddleModalOpen}
          title={tPaddle("buy_paddle_modal_title")}
          contentClassName="w-[min(92vw,480px)] text-center"
        >
          <div className="space-y-5">
            <p className="text-slate-700 text-sm leading-7">
              {tPaddle("buy_paddle_modal_description")}
            </p>
            <div className="text-primary font-extrabold text-lg">
              {tPaddle("paddle_price_label", {
                value: REQUIRED.toLocaleString(),
              })}
            </div>

            {/* Payment Method Selection */}
            <div className="space-y-3">
              <div className="flex items-center justify-between gap-2">
                <div className="text-sm font-bold text-slate-800 text-right min-w-0 flex-1">
                  {tPaddle("payment_method_title")}
                </div>
                <PaddleElectronicPaymentInfo
                  paymentMethod={paddlePaymentMethod}
                />
              </div>
              <div className="grid grid-cols-2 gap-3">
                <label
                  className={`relative border-2 rounded-xl p-3 flex flex-col items-center gap-2 cursor-pointer transition-all hover:shadow-md ${
                    paddlePaymentMethod === "gateway"
                      ? "border-blue-500 ring-2 ring-blue-500/20 bg-blue-50/50"
                      : "border-slate-200 bg-white hover:border-blue-300"
                  }`}
                >
                  {paddlePaymentMethod === "gateway" && (
                    <div className="absolute top-2 left-2">
                      <CheckCircle2 className="w-4 h-4 text-blue-500" />
                    </div>
                  )}
                  <input
                    type="radio"
                    name="paddle_payment_method"
                    checked={paddlePaymentMethod === "gateway"}
                    onChange={() => setPaddlePaymentMethod("gateway")}
                    className="sr-only"
                  />
                  <div className="w-10 h-10 rounded-xl bg-blue-500 flex items-center justify-center">
                    <CreditCard className="w-5 h-5 text-white" />
                  </div>
                  <div className="text-center">
                    <div className="font-bold text-slate-800 text-xs">
                      {tPayment("gateway_title")}
                    </div>
                    <div className="text-[10px] text-slate-500">
                      {tPayment("gateway_desc")}
                    </div>
                  </div>
                </label>

                {applePayVisible && (
                  <label
                    className={`relative border-2 rounded-xl p-3 flex flex-col items-center gap-2 cursor-pointer transition-all hover:shadow-md ${
                      paddlePaymentMethod === "apple_pay"
                        ? "border-slate-900 ring-2 ring-slate-900/20 bg-slate-50"
                        : "border-slate-200 bg-white hover:border-slate-400"
                    }`}
                  >
                    {paddlePaymentMethod === "apple_pay" && (
                      <div className="absolute top-2 left-2">
                        <CheckCircle2 className="w-4 h-4 text-slate-700" />
                      </div>
                    )}
                    <input
                      type="radio"
                      name="paddle_payment_method"
                      checked={paddlePaymentMethod === "apple_pay"}
                      onChange={() => setPaddlePaymentMethod("apple_pay")}
                      className="sr-only"
                    />
                    <div className="w-10 h-10 rounded-xl bg-slate-900 flex items-center justify-center">
                      <svg
                        viewBox="0 0 24 24"
                        className="w-5 h-5 fill-white"
                        aria-hidden="true"
                      >
                        <path d="M17.05 20.28c-.98.95-2.05.8-3.08.35-1.09-.46-2.09-.48-3.24 0-1.44.62-2.2.44-3.06-.35C2.79 15.25 3.51 7.7 9.05 7.4c1.28.07 2.16.72 2.98.73 1.16-.1 2.26-.79 3.47-.68 1.45.13 2.54.79 3.25 2.02-3.13 1.87-2.39 5.88.3 6.97-.5 1.32-1.29 2.59-2 3.84zM12.03 7.25c-.15-2.23 1.66-4.07 3.74-4.25.29 2.58-2.34 4.5-3.74 4.25z" />
                      </svg>
                    </div>
                    <div className="text-center">
                      <div className="font-bold text-slate-800 text-xs">
                        {tPayment("apple_pay_title")}
                      </div>
                      <div className="text-[10px] text-slate-500">
                        {tPayment("apple_pay_desc")}
                      </div>
                    </div>
                  </label>
                )}

                <label
                  className={`relative border-2 rounded-xl p-3 flex flex-col items-center gap-2 cursor-pointer transition-all hover:shadow-md ${
                    paddlePaymentMethod === "wallet"
                      ? "border-emerald-500 ring-2 ring-emerald-500/20 bg-emerald-50/50"
                      : "border-slate-200 bg-white hover:border-emerald-300"
                  }`}
                >
                  {paddlePaymentMethod === "wallet" && (
                    <div className="absolute top-2 left-2">
                      <CheckCircle2 className="w-4 h-4 text-emerald-500" />
                    </div>
                  )}
                  <input
                    type="radio"
                    name="paddle_payment_method"
                    checked={paddlePaymentMethod === "wallet"}
                    onChange={() => setPaddlePaymentMethod("wallet")}
                    className="sr-only"
                  />
                  <div className="w-10 h-10 rounded-xl bg-emerald-500 flex items-center justify-center">
                    <Wallet className="w-5 h-5 text-white" />
                  </div>
                  <div className="text-center">
                    <div className="font-bold text-slate-800 text-xs">
                      {tPayment("wallet_title")}
                    </div>
                    <div className="text-[10px] text-slate-500">
                      {tPayment("wallet_balance")}:{" "}
                      {toLatinDigits(wallet.toLocaleString())}{" "}
                      {tPayment("currency")}
                    </div>
                  </div>
                </label>
              </div>

              {/* Wallet balance warning & top-up button */}
              {paddlePaymentMethod === "wallet" && !canAffordPaddle && (
                <div className="text-xs text-center text-amber-700 bg-amber-50 p-3 rounded-xl space-y-2">
                  <div>{tPaddle("insufficient_wallet_for_paddle")}</div>
                  <button
                    type="button"
                    onClick={() => {
                      setBuyPaddleModalOpen(false);
                      setShowTopUpModal(true);
                    }}
                    className="w-full px-3 py-2 rounded-lg bg-emerald-600 text-white text-xs font-bold hover:bg-emerald-700 transition-colors"
                  >
                    شحن المحفظة (
                    {toLatinDigits(topUpShortfall.toLocaleString())} ريال)
                  </button>
                </div>
              )}
            </div>

            <DynamicButton
              onClick={handlePurchaseNewPaddle}
              isDisabled={
                buyingPaddle ||
                isOwner ||
                (paddlePaymentMethod === "wallet" && !canAffordPaddle)
              }
              className="w-full px-4 py-3 rounded-xl bg-[#0F5132] text-white hover:bg-[#0F5132]/90"
            >
              {buyingPaddle
                ? tPaddle("buy_paddle_processing")
                : tPaddle("buy_paddle_confirm")}
            </DynamicButton>
          </div>
        </BaseModal>

        {showBalanceModal && (
          <div className="fixed inset-0 flex items-center justify-center bg-black/45 p-4 z-50">
            <div className="w-full max-w-[480px] bg-white rounded-2xl shadow-xl overflow-hidden">
              <div className="bg-[#0f5132] text-white px-4 py-3 font-extrabold">
                {tModals("insufficient_wallet_title")}
              </div>
              <div className="p-4 text-sm text-slate-700 space-y-2">
                <p>
                  {tModals("insufficient_wallet_text_1")}{" "}
                  <Money value={REQUIRED} />.
                </p>
                <p>{tModals("insufficient_wallet_text_2")}</p>
              </div>
              <div className="flex gap-3 px-4 pb-4 justify-end">
                <button
                  className="bg-white text-[#0f5132] border border-[#0f5132] px-3 py-2 rounded-xl text-sm"
                  onClick={() => setShowBalanceModal(false)}
                >
                  {tModals("close")}
                </button>
                <button
                  className="bg-[#0f5132] text-white px-3 py-2 rounded-xl text-sm"
                  onClick={() => {
                    setShowBalanceModal(false);
                    setBuyPaddleModalOpen(false);
                    setShowTopUpModal(true);
                  }}
                >
                  {tModals("topup_then_buy_paddle")}
                </button>
              </div>
            </div>
          </div>
        )}

        <TopUpModal
          isOpen={showTopUpModal}
          onOpenChange={(open) => {
            setShowTopUpModal(open);
            if (open) setBuyPaddleModalOpen(false);
          }}
          defaultAmount={topUpShortfall > 0 ? topUpShortfall : undefined}
          onSuccess={() => {
            setShowTopUpModal(false);
            setBuyPaddleModalOpen(false);
            setShowBalanceModal(false);
            setTopUpNoticeOpen(true);
          }}
        />

        <BaseModal
          isOpen={topUpNoticeOpen}
          onOpenChange={setTopUpNoticeOpen}
          placement="center"
          title={tModals("topup_notice_title")}
          contentClassName="w-[min(92vw,420px)] text-center"
        >
          <div className="space-y-4">
            <div className="text-sm text-slate-700 leading-relaxed">
              {tModals("topup_notice_text")}
            </div>
            <button
              className="w-full px-4 py-2 rounded-lg text-sm bg-[#0f5132] text-white"
              onClick={() => setTopUpNoticeOpen(false)}
            >
              {tModals("close")}
            </button>
          </div>
        </BaseModal>

        <Modals
          confirmBidOpen={confirmBidOpen}
          setConfirmBidOpen={setConfirmBidOpen}
          successOpen={successOpen}
          setSuccessOpen={setSuccessOpen}
          onConfirmBid={confirmBid}
          onSuccessClose={closeSuccess}
          bidDelta={bidDelta}
          setBidDelta={setBidDelta}
          currentPrice={currentPrice}
          auctionStatus={auctionStatus}
          isClosed={isClosed}
          marketEntryPrice={
            marketEntryPrice ?? parsePrice(item?.market_entry_price)
          }
        />

        {/* Purchase Offer Modal */}
        <BaseModal
          isOpen={sendOfferModalOpen}
          onOpenChange={setSendOfferModalOpen}
          title={tAuction("send_offer_title")}
          contentClassName="w-[min(92vw,500px)]"
        >
          <div className="space-y-5" dir="rtl">
            {/* Description with icon */}
            <div className="flex gap-3 p-4 rounded-xl bg-gradient-to-br from-amber-50 to-orange-50 border border-amber-200/60">
              <div className="w-10 h-10 rounded-xl bg-amber-500/10 flex items-center justify-center flex-shrink-0 mt-0.5">
                <Send className="w-5 h-5 text-amber-600" />
              </div>
              <p className="text-slate-700 text-sm leading-7 whitespace-pre-line">
                {tAuction("send_offer_description")}
              </p>
            </div>

            {/* Current Price Info */}
            <div className="p-3 rounded-xl bg-slate-50 border border-slate-200 flex items-center justify-between">
              <span className="text-sm text-slate-600">
                {tAuction("current_price")}
              </span>
              <span className="font-black text-lg text-[#0F5132]">
                {currentPrice.toLocaleString()}{" "}
                <span className="text-xs">ر.س</span>
              </span>
            </div>

            {/* Amount Input */}
            <div className="space-y-2">
              <label className="text-sm font-bold text-slate-800">
                {tAuction("offer_amount_label")}
              </label>
              <input
                type="number"
                min="1"
                value={offerAmount}
                onChange={(e) => setOfferAmount(e.target.value)}
                placeholder={tAuction("offer_amount_placeholder")}
                className="w-full px-4 py-3 rounded-xl border-2 border-slate-200 focus:border-[#0F5132] focus:ring-2 focus:ring-[#0F5132]/10 outline-none transition-all text-lg font-bold text-center"
                dir="ltr"
              />
              {/* Hint note */}
              <div className="flex items-start gap-2 p-2.5 rounded-lg bg-blue-50/70 border border-blue-100">
                <span className="text-blue-500 mt-0.5 text-sm">ℹ️</span>
                <p className="text-xs text-blue-700 leading-relaxed">
                  {currentPrice > 0
                    ? locale === "ar"
                      ? `المبلغ يجب أن يكون أعلى من آخر مزايدة (${currentPrice.toLocaleString()} ر.س)`
                      : `Amount must be greater than the last bid (${currentPrice.toLocaleString()} SAR)`
                    : locale === "ar"
                      ? "المبلغ يجب أن يكون أكبر من صفر"
                      : "Amount must be greater than zero"}
                </p>
              </div>
            </div>

            {/* Submit Button */}
            <DynamicButton
              onClick={async () => {
                const amount = toMoneyNumber(offerAmount, 0);
                if (!amount || amount <= 0) {
                  toast.error(tAuction("offer_zero_error"));
                  return;
                }
                // Minimum allowed offer: prefer final bid amount from backend (info_final_bid),
                // fall back to currentPrice if not available.
                const finalBidRaw =
                  item?.info_final_bid?.final_bid_amount ?? null;
                const finalBidAmount = parseMoneyValue(finalBidRaw);
                const minAllowed =
                  finalBidAmount !== undefined && finalBidAmount > 0
                    ? finalBidAmount
                    : currentPrice;
                if (minAllowed > 0 && amount <= minAllowed) {
                  toast.error(
                    tAuction("offer_min_amount_error", {
                      value: minAllowed.toLocaleString(),
                    }),
                  );
                  return;
                }
                try {
                  setSendingOffer(true);
                  const auctionType = item?.is_group ? "group" : "normal";
                  const res = await createPurchaseOffer({
                    auction_type: auctionType,
                    auction_id: String(item?.id),
                    full_amount: amount,
                  });
                  if ((res as any)?.success) {
                    toast.success(
                      (res as any)?.message || tAuction("offer_success"),
                    );
                    setSendOfferModalOpen(false);
                    setOfferAmount("");
                    router.refresh();
                  } else {
                    toast.error(
                      (res as any)?.message || tAuction("offer_error"),
                    );
                  }
                } catch (e: any) {
                  toast.error(e?.message || tAuction("offer_error"));
                } finally {
                  setSendingOffer(false);
                }
              }}
              isDisabled={sendingOffer}
              className="w-full px-4 py-3 rounded-xl bg-gradient-to-r from-[#0F5132] to-emerald-600 text-white font-bold hover:from-[#0F5132]/90 hover:to-emerald-600/90 shadow-lg shadow-emerald-500/20 transition-all disabled:opacity-60"
            >
              {sendingOffer
                ? tAuction("offer_sending")
                : tAuction("offer_confirm")}
            </DynamicButton>
          </div>
        </BaseModal>

        {/* Payment Gateway Modal for Paddle Purchase */}
        <PaymentGatewayModal
          isOpen={!!paddleGatewayUrl}
          onClose={() => setPaddleGatewayUrl(null)}
          gatewayUrl={paddleGatewayUrl || ""}
          isAr={locale === "ar"}
        />
      </main>
    </>
  );
}
