"use client";

import Image from "next/image";
import { useEffect, useMemo, useRef, useState } from "react";

import "./style.css";
import {
  fetchInventoryCards,
  InventoryPack,
  InventoryCard,
  lockInventoryCards,
} from "../lib/api/inventory";
import WithdrawActionBar from "../components/withdraw/WithdrawActionBar";
import { useSelector } from "react-redux";
import { User } from "@/constants/types";
import WithdrawHeader from "../components/withdraw/WithdrawHeader";
import { redirect } from "next/navigation";
import NotAvailable from "../components/ui/NotAvailable";
// Types
type ParentTab = "cards" | "packs";
type ChildTab = "all" | "magic" | "pokemon" | "lorcana" | "slab";

interface CardItem {
  id: string;
  backendIds: number[]; // inv_id (for selling)
  cardId: number; // id from API (the TCG card id)
  name: string;
  price: string; // "$12.34"
  series: string;
  image: string;
  brand: string;
  quantity: number;
  rarity: string;
  probability?: string;
  locked?: boolean;
}
interface Props {
  userId: string;
}

export default function WithdrawPage() {
  const [parentTab, setParentTab] = useState<ParentTab>("cards");
  const [childTab, setChildTab] = useState<ChildTab>("all");

  // 🔹 Packs API data
  const [packs, setPacks] = useState<InventoryPack[]>([]);
  const [isLoadingPacks, setIsLoadingPacks] = useState(false);

  // 🔹 Cards API data
  const [cards, setCards] = useState<InventoryCard[]>([]);
  const [isLoadingCards, setIsLoadingCards] = useState(false);
  const [cardsError, setCardsError] = useState<string | null>(null);
  const [hasLoadedCards, setHasLoadedCards] = useState(false);

  const [selectedIds, setSelectedIds] = useState<string[]>([]);
  const [cartOpen, setCartOpen] = useState(false);
  const [lockedIds, setLockedIds] = useState<string[]>([]);
  const CARDS_PAGE_SIZE = 20;
  const PACKS_PAGE_SIZE = 10;

  const [visibleCardsCount, setVisibleCardsCount] = useState(CARDS_PAGE_SIZE);
  const [visiblePacksCount, setVisiblePacksCount] = useState(PACKS_PAGE_SIZE);
  const [selectedCopies, setSelectedCopies] = useState<Record<string, number>>(
    {},
  );
  const [offset, setOffset] = useState<number | null>(null);
  const [hasMoreInv, setHasMoreInv] = useState(true);
  const [apiLoading, setApiLoading] = useState(false);
  const [more, setMore] = useState<"yes" | "no">("no");
  const [sameCards, setSameCards] = useState<any[]>([]);

  const [search, setSearch] = useState("");

  const user = useSelector((state: any) => state.auth.user) as User | null;
  if (!user) {
    redirect("/");
  }
  const status = useSelector((state: any) => state.auth.status);
  const cardsLoaderRef = useRef<HTMLDivElement | null>(null);
  const isFetchingMoreRef = useRef(false);
  const lastOffsetFetchedRef = useRef<number | null>(null);
  const visibleCardsCountRef = useRef(visibleCardsCount);

  useEffect(() => {
    visibleCardsCountRef.current = visibleCardsCount;
  }, [visibleCardsCount]);

  // 🧠 Cards brand filtering
  const filteredCards = useMemo(() => {
    if (childTab === "all") return cards;

    if (childTab === "magic") return cards.filter((c) => c.brand === "MTG");

    if (childTab === "pokemon")
      return cards.filter((c) => c.brand === "Pokemon");

    if (childTab === "lorcana")
      return cards.filter((c) => c.brand === "Lorcana");

    if (childTab === "slab")
      return cards.filter((c) => (c.brand ?? "").toLowerCase() === "slab");
    return cards;
  }, [cards, childTab]);

  // ✅ SEARCH (cards only)
  const uiCards: CardItem[] = useMemo(() => {
    const map = new Map<
      string,
      {
        locked: any;
        key: string;
        cardId: number;
        name: string;
        price: number;
        series: string;
        image: string;
        brand: string;
        rarity: string;
        probability?: string;
        backendIds: number[];
        quantity: number;
      }
    >();

    for (const c of filteredCards) {
      // ✅ define what makes a card “the same”
      // include fields that matter visually/meaningfully
      const key = [
        c.id,
        c.name,
        c.pack_name,
        c.rarity,
        c.probability ?? "",
        c.image,
      ].join("|");

      const existing = map.get(key);

      const qty = c.count ?? 1;

      if (!existing) {
        const extraIds = (sameCards ?? [])
          .filter(
            (s) => Number(s.card_id ?? s.cardId ?? s.card) === Number(c.id),
          )
          .map((s) => s.inv_id);

        const mergedIds = Array.from(new Set([c.inv_id, ...extraIds])); // unique

        // qty = c.count
        const qty = c.count ?? 1;

        // ensure backendIds length = qty (jitni copies)
        const finalIds = mergedIds.slice(0, qty);
        map.set(key, {
          key,
          cardId: Number(c.id),
          name: c.name,
          price: Number(c.price || 0),
          series: c.pack_name,
          image: c.image,
          brand: c.brand,
          rarity: c.rarity,
          probability: c.probability,
          backendIds: finalIds,
          quantity: qty,
          locked: c.locked,
        });
      } else {
        existing.quantity = qty;
        existing.backendIds.push(c.inv_id);
      }
    }

    return Array.from(map.values()).map((x) => ({
      id: x.key, // stable id per merged group
      backendIds: x.backendIds,
      cardId: x.cardId,
      name: x.name,
      price: `$${x.price.toFixed(2)}`,
      series: x.series,
      image: x.image,
      brand: x.brand,
      quantity: x.quantity,
      rarity: x.rarity,
      probability: x.probability,
      locked: x.locked,
    }));
  }, [filteredCards, sameCards]);

  const searchText = search.trim().toLowerCase();

  const searchedCards: CardItem[] = useMemo(() => {
    if (!searchText) return uiCards;

    return uiCards.filter((item) => {
      const name = (item.name ?? "").toLowerCase();
      const rarity = (item.rarity ?? "").toLowerCase();
      const series = (item.series ?? "").toLowerCase();

      return (
        name.includes(searchText) ||
        rarity.includes(searchText) ||
        series.includes(searchText)
      );
    });
  }, [uiCards, searchText]);

  useEffect(() => {
    if (parentTab === "cards") {
      setVisibleCardsCount(CARDS_PAGE_SIZE);
    }
    if (parentTab === "packs") {
      setVisiblePacksCount(PACKS_PAGE_SIZE);
    }
  }, [parentTab, childTab]);

  // Packs brand filtering
  const filteredPacks = useMemo(() => {
    if (childTab === "all") return packs;

    if (childTab === "magic") return packs.filter((p) => p.brand === "MTG");

    if (childTab === "pokemon")
      return packs.filter((p) => p.brand === "Pokemon");

    if (childTab === "lorcana")
      return packs.filter((p) => p.brand === "Lorcana");

    if (childTab === "slab")
      return packs.filter((p) => (p.brand ?? "").toLowerCase() === "slab");

    return packs;
  }, [packs, childTab]);

  const uiPacks: CardItem[] = useMemo(
    () =>
      filteredPacks.map((p, index) => ({
        backendIds: [],
        id: `${p.id}-${index}`, // 🔥 always unique
        backendId: p.inv_id, // 👈 inventory id (for selling)
        cardId: p.id,
        name: p.name,
        price: `$${p.price.toFixed(2)}`,
        series: p.brand,
        image: p.image,
        brand: p.brand,
        quantity: p.count,
        rarity: "PACK",
      })),
    [filteredPacks],
  );

  const { bulkCount, bulkPrice } = useMemo(() => {
    let count = 0;

    selectedIds.forEach((id) => {
      if (lockedIds.includes(id)) return;

      const item = uiCards.find((c) => c.id === id);
      if (!item) return;

      const rarity = item.rarity?.toLowerCase() ?? "";
      const probability = item?.probability?.toLowerCase() ?? "";
      const qty = selectedCopies[id] ?? item.quantity ?? 1;

      const isBulkRarity =
        rarity === "common" ||
        rarity === "uncommon" ||
        rarity === "code card" ||
        rarity === "energy";

      const isBulkProb =
        probability === "normal" ||
        probability === "code card" ||
        probability === "energy";

      if (isBulkRarity && isBulkProb) {
        count += qty;
      }
    });

    // if (count <= 50) return { bulkCount: count, bulkPrice: "0.00" };

    // const surcharge = (count - 50) * 0.1;

    // return { bulkCount: count, bulkPrice: surcharge.toFixed(2) };

    if (count <= 50) {
      return { bulkCount: 0, bulkPrice: "0.00" };
    }

    const extra = count - 50;
    const surcharge = extra * 0.1;

    // 👇 bulkCount = sirf extra cards
    return { bulkCount: extra, bulkPrice: surcharge.toFixed(2) };
  }, [selectedIds, lockedIds, uiCards, selectedCopies]);

  const displayItems: CardItem[] = useMemo(() => {
    if (parentTab === "cards") {
      return searchedCards.slice(0, visibleCardsCount);
    }

    // packs
    return uiPacks.slice(0, visiblePacksCount);
  }, [parentTab, searchedCards, uiPacks, visibleCardsCount, visiblePacksCount]);

  const selectedItems = displayItems.filter((i) => selectedIds.includes(i.id));
  const isLockedAll =
    selectedItems.length > 0 &&
    selectedItems.every((item) => lockedIds.includes(item.id));

  const totalValue = selectedItems
    .filter((item) => !lockedIds.includes(item.id)) // ← EXCLUDE LOCKED ITEMS
    .reduce((sum, item) => {
      const price = parseFloat(item.price.replace(/[^0-9.]/g, ""));
      const qty = selectedCopies[item.id] ?? item.quantity ?? 1;
      if (isNaN(price)) return sum;
      return sum + price * qty;
    }, 0)
    .toFixed(2);

  const allIdsOnScreen = displayItems.map((i) => i.id);

  const toggleSelect = (id: string) => {
    setCartOpen(true);
    setSelectedIds((prev) => {
      const isAlreadySelected = prev.includes(id);

      if (isAlreadySelected) {
        // deselect: remove from selectedIds and selectedCopies
        setSelectedCopies((prevCopies) => {
          const { [id]: _, ...rest } = prevCopies;
          return rest;
        });
        return prev.filter((x) => x !== id);
      } else {
        // select: default to full quantity
        const item = displayItems.find((i) => i.id === id);
        if (item) {
          setSelectedCopies((prevCopies) => ({
            ...prevCopies,
            [id]: item.quantity ?? 1,
          }));
        }
        return [...prev, id];
      }
    });
  };

  const handleSelectAll = () => {
    if (selectedIds.length === allIdsOnScreen.length) {
      // clear selection
      setSelectedIds([]);
      setSelectedCopies({});
    } else {
      setSelectedIds(allIdsOnScreen);

      const newCopies: Record<string, number> = {};
      displayItems.forEach((item) => {
        newCopies[item.id] = item.quantity ?? 1;
      });

      setSelectedCopies(newCopies);
    }
  };

  const loadCards = async () => {
    setIsLoadingCards(true);
    setCardsError(null);
    try {
      const data = await fetchInventoryCards(user.userId, "yes", user.token);
      setCards(data.cards);
      setSameCards(data.same ?? []);
      setOffset(data?.offset ?? null);

      setHasMoreInv(data.more === "yes");

      setMore(data.more as "yes" | "no");
      setHasLoadedCards(true);
    } catch (err: any) {
      console.error(err);
      setCardsError(err.message ?? "Failed to load cards");
    } finally {
      setIsLoadingCards(false);
    }
  };

  const loadMoreInventory = async () => {
    if (!user?.userId || !user?.token) return;

    // ✅ must have more = yes
    if (more !== "yes") return;

    if (offset == null) return;

    if (isFetchingMoreRef.current) return;
    if (lastOffsetFetchedRef.current === offset) return;

    isFetchingMoreRef.current = true;
    lastOffsetFetchedRef.current = offset;
    setApiLoading(true);

    try {
      const data = await fetchInventoryCards(
        user.userId,
        "yes",
        user.token,
        offset,
      );

      if (!data.cards || data.cards.length === 0) {
        setHasMoreInv(false);
        return;
      }

      setCards((prev) => [...prev, ...data.cards]);
      setSameCards((prev) => [...prev, ...(data.same ?? [])]);
      setOffset(data?.offset ?? null);

      // ✅ UPDATE THESE ON EVERY PAGE
      setMore(data.more as "yes" | "no");
      setHasMoreInv(data.more === "yes"); // stop when "no"
    } catch (e) {
      console.error(e);
      lastOffsetFetchedRef.current = null;
    } finally {
      isFetchingMoreRef.current = false;
      setApiLoading(false);
    }
  };

  const selectedCardsForSidebar = useMemo(() => {
    const out: { key: string; id: string; image: string }[] = [];

    selectedIds.forEach((id) => {
      const item = uiCards.find((c) => c.id === id);
      if (!item) return;

      const qty = selectedCopies[id] ?? item.quantity ?? 1;

      for (let i = 0; i < qty; i++) {
        out.push({
          key: `${id}__${i}`, // ✅ unique key per copy
          id,
          image: item.image,
        });
      }
    });

    return out;
  }, [selectedIds, uiCards, selectedCopies]);

  useEffect(() => {
    if (selectedIds.length === 0) {
      setCartOpen(false);
    }
  }, [selectedIds]);

  useEffect(() => {
    // search / tab change par first page se start
    if (parentTab === "cards") setVisibleCardsCount(CARDS_PAGE_SIZE);
    if (parentTab === "packs") setVisiblePacksCount(PACKS_PAGE_SIZE);
  }, [search, parentTab, childTab]);

  useEffect(() => {
    if (parentTab === "cards" && !hasLoadedCards) {
      loadCards();
    }
  }, [parentTab, hasLoadedCards]);

  useEffect(() => {
    if (parentTab !== "cards") return;

    const node = cardsLoaderRef.current;
    if (!node) return;
    const observer = new IntersectionObserver(
      (entries) => {
        const first = entries[0];
        if (!first.isIntersecting) return;

        const total = searchedCards.length;
        const currentVisible = visibleCardsCountRef.current;

        // ✅ UI pagination first
        if (currentVisible < total) {
          setVisibleCardsCount((prev) => prev + CARDS_PAGE_SIZE);
          return;
        }

        if (more === "yes" && hasMoreInv && !apiLoading) {
          loadMoreInventory();
        }
      },

      {
        root: null,
        rootMargin: "0px 0px 200px 0px", // thoda pehle trigger ho jaye
        threshold: 0,
      },
    );

    observer.observe(node);

    return () => {
      observer.disconnect();
    };
  }, [parentTab, searchedCards.length, visibleCardsCount]);

  // ✅ TOTAL ITEMS = selected quantities ka sum
  const selectedCount = useMemo(() => {
    return selectedIds.reduce((sum, id) => {
      const item = uiCards.find((c) => c.id === id);
      const qty = selectedCopies[id] ?? item?.quantity ?? 1;
      return sum + qty;
    }, 0);
  }, [selectedIds, selectedCopies, uiCards]);

  const removeOneCopy = (id: string) => {
    const item = uiCards.find((c) => c.id === id);
    const maxQty = item?.quantity ?? 1;

    setSelectedCopies((prev) => {
      const current = prev[id] ?? maxQty; // default full qty if not set
      const nextQty = current - 1;

      const next = { ...prev };

      if (nextQty > 0) {
        next[id] = nextQty;
      } else {
        delete next[id];
      }

      return next;
    });

    setSelectedIds((prev) => {
      const item = uiCards.find((c) => c.id === id);
      const maxQty = item?.quantity ?? 1;
      const current = selectedCopies[id] ?? maxQty;

      if (current <= 1) {
        return prev.filter((x) => x !== id);
      }
      return prev;
    });
  };

  const noResults =
    parentTab === "cards" && searchedCards.length === 0 && !isLoadingCards;

  return (
    <div className="min-h-screen bg-black text-white">
      {user?.activeMode === "gems" ? (
        <NotAvailable />
      ) : (
        <div
          className={`
     gap-6
    transition-all duration-500 ease-in-out
    ${cartOpen ? "md:w-[calc(100%-350px)] 2xl:w-[calc(100%-500px)]" : "w-full"}
    `}
        >
          <WithdrawHeader
            search={search}
            setSearch={setSearch}
            childTab={childTab}
            setChildTab={setChildTab}
            bulkPrice={bulkPrice}
            // onBack={() => router.back()}
          />

          {(parentTab === "packs" && isLoadingPacks) ||
          (parentTab === "cards" && isLoadingCards && !hasLoadedCards) ? (
            <div className=" flex w-full h-65 items-center justify-center">
              <div className="w-8 h-8 border-4 border-white/20 border-t-white rounded-full animate-spin" />
            </div>
          ) : (
            <>
              {/* Content Grid */}
              <div className="container mx-auto py-3 md:py-8 2xl:py-8">
                <div className="grid justify-items-center gap-3 2xl:gap-7 pb-10 [grid-template-columns:repeat(auto-fit,minmax(160px,1fr))]">
                  {noResults && (
                    <div className="col-span-full text-center py-20 text-(--color-slate)">
                      <p className="text-xl md:text-3xl font-bold">
                        No items found
                      </p>
                      <p className="text-sm md:text-2xl mt-1">
                        Try a different name or rarity
                      </p>
                    </div>
                  )}
                  {!noResults && (
                    <>
                      {displayItems.map((item) => {
                        const isSelected = selectedIds.includes(item.id);
                        // const isLocked = lockedIds.includes(item.id);
                        const isLocked = item.locked;
                        return (
                          <div
                            key={item.id}
                            onClick={() => {
                              toggleSelect(item.id);
                            }}
                            className={` col-span-1 hover:-translate-y-1 duration-500 group relative h-full pb-2 w-full    overflow-hidden transition-all cursor-pointer
${isLocked ? "cursor-not-allowed pointer-events-none bg-[#202A38]" : null}
${isSelected && !isLocked && " ring-2 ring-[var(--color-blue)]"}
${parentTab === "packs" ? "pointer-events-none" : ""}
`}
                          >
                            {item.quantity > 1 && (
                              <div className="absolute top-2 left-2 z-10 px-2 py-1 text-xs font-extrabold rounded-full bg-black/60 border border-white/10">
                                {item.quantity}
                              </div>
                            )}
                            {!isLocked && (
                              <div className="absolute group-hover:w-40 bottom-17 left-1/2 -translate-x-1/2 w-[150px] md:w-[120px] h-[150px] md:h-[150px] group-hover:md:h-40 bg-[var(--color-blue)] group-hover:blur-xl transition-all duration-500 blur-3xl rounded-full opacity-50"></div>
                            )}

                            {/* Inner padding wrapper so button can be full width */}
                            <div className="pt-6 px-4 2xl:px-6 relative z-10">
                              {/* Card Image */}
                              <div className=" flex justify-center ">
                                <div className="w-17.5 h-24 2xl:w-27.5 2xl:h-38.25">
                                  <Image
                                    src={item.image.replace(
                                      "cardsimages",
                                      "cards/images",
                                    )}
                                    width={110}
                                    height={153}
                                    alt={item.name}
                                    className="w-full h-full img-border-radius group-hover:rotate-4 transition-all object-contain transform duration-500"
                                  />
                                </div>
                              </div>

                              {/* Card Details */}
                              <div className="py-4 pt-2 w-full font-sofia pb-0 text-center">
                                <div className="text-xs md:text-base 2xl:text-lg text-(--color-blue) font-bold uppercase">
                                  {item?.rarity}
                                </div>
                                <h3 className="font-bold text-sm md:text-lg uppercase">
                                  {item.name.split(" ").slice(0, 2).join(" ") +
                                    (item.name.split(" ").length > 2
                                      ? "…"
                                      : "")}
                                </h3>

                                <div className="text-sm md:text-lg font-bold  ">
                                  {item.price}
                                </div>
                                {/* <div className="text-xs text-[var(--color-slate)] uppercase ">
                          {item?.series}
                        </div> */}
                              </div>
                            </div>
                            {!isLocked && (
                              <>
                                {isSelected ? (
                                  <div className="absolute bottom-0 left-0 w-full shadow-lg">
                                    <div className="flex items-center w-full gap-2">
                                      {/* TICK */}
                                      <div className="bg-[var(--color-blue)] p-3">
                                        <img
                                          src="/images/coinFlip/modal/tick.svg"
                                          alt="tick"
                                          className="w-3 h-3 "
                                        />
                                      </div>
                                    </div>
                                  </div>
                                ) : null}
                              </>
                            )}
                          </div>
                        );
                      })}
                    </>
                  )}
                </div>
                {/* Load more for CARDS */}
                {/* Infinite scroll sentinel for CARDS */}
                {parentTab === "cards" &&
                  (searchedCards.length > visibleCardsCount || hasMoreInv) && (
                    <div
                      ref={cardsLoaderRef}
                      className="h-8 mb-20 flex items-center justify-center text-xs text-[var(--color-slate)]"
                    >
                      {apiLoading
                        ? "Loading more cards..."
                        : hasMoreInv
                          ? "Scroll to load more..."
                          : "All items loaded"}
                    </div>
                  )}
              </div>
              {/* Bottom bar – only when something selected */}

              <WithdrawActionBar
                open={cartOpen}
                onClose={() => setCartOpen(false)}
                onOpen={() => setCartOpen(true)}
                // selectedCount={selectedIds.length}
                selectedCount={selectedCount}
                allOnScreenCount={allIdsOnScreen.length}
                totalValue={totalValue}
                onSelectAll={handleSelectAll}
                isLockedAll={isLockedAll}
                selectedCards={selectedCardsForSidebar}
                // selectedCards={selectedCardsForSidebar}
                // toggleSelect={toggleSelect}
                toggleSelect={removeOneCopy}
                cards={selectedIds
                  .flatMap((id) => {
                    const item = uiCards.find((c) => c.id === id);
                    if (!item) return [];
                    const qty = selectedCopies[id] ?? item.quantity ?? 1;
                    return (item.backendIds ?? []).slice(0, qty);
                  })
                  .join(",")}
                cardImage={selectedIds
                  .map((id) => {
                    const item = uiCards.find((c) => c.id === id);
                    return item?.image;
                  })
                  .filter((src): src is string => Boolean(src))}
                bulkCount={bulkCount}
                bulkPrice={bulkPrice}
              />

              {/* Right side drawer */}
            </>
          )}
        </div>
      )}
    </div>
  );
}
