"use client";

import Image from "next/image";
import { useEffect, useMemo, useRef, useState } from "react";
import InventoryActionBar from "../components/inventory/InventoryActionBar";
import InventoryDetailDrawer from "../components/inventory/InventoryDetailDrawer";
import CardSelectionModal from "../components/inventory/CardSelectionModal";
import "./style.css";
import {
  fetchInventoryPacks,
  fetchInventoryCards,
  InventoryPack,
  InventoryCard,
  sellInventoryCards,
  lockInventoryCards,
  updateSession,
} from "../lib/api/inventory";
import SellConfirmModal from "../components/inventory/SellConfirmationModal";
import { useRouter, useSearchParams } from "next/navigation";

// Types
type ParentTab = "cards" | "packs";
type ChildTab = "all" | "magic" | "pokemon" | "lorcana" | "slab";

interface CardItem {
  inv_id: number;
  invIds: number[];
  id: string;
  backendId: 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;
}

// ✅ ADD (near other state)
type SameInv = {
  inv_id: number;
  card_id: number;
  pack_name?: string;
  rarity?: string;
  image?: string;
  price?: number | string;
};

import { useSelector } from "react-redux";
import InventoryHeader from "../components/inventory/InventoryHeader";
import { updateUser } from "../store/authSlice";
import { useAppDispatch } from "../lib/hooks";
import AlertModal from "../components/ui/AlertModal";
import { setSelectedPackCover } from "../store/inventorySlice";
import { AuthState } from "../wallet/page";

export default function InventoryPage() {
  const searchParams = useSearchParams();
  const showPacks = searchParams.get("packs") === "true";

  const [modalOpen, setModalOpen] = useState(false);
  const [modalType, setModalType] = useState<"success" | "error">("success");
  const [modalMsg, setModalMsg] = useState("");

  const [parentTab, setParentTab] = useState<ParentTab>("cards");
  const user = useSelector((state: { auth: AuthState }) => state.auth.user);
  const [search, setSearch] = useState("");
  const [childTab, setChildTab] = useState<ChildTab>("all");

  // 🔹 Packs API data
  const [packs, setPacks] = useState<InventoryPack[]>([]);
  const [isLoadingPacks, setIsLoadingPacks] = useState(false);
  const [packsError, setPacksError] = useState<string | null>(null);
  const [hasLoadedPacks, setHasLoadedPacks] = useState(false);

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

  const [isSellModalOpen, setIsSellModalOpen] = useState(false);

  const [isOpenCardModal, setIsOpenCardModal] = useState(false);
  const [detailCard, setDetailCard] = useState<CardItem | null>(null);
  const [lockedIds, setLockedIds] = useState<number[]>([]);
  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 [opendrawer, setOpenDrawer] = useState(false);
  const [selectedIds, setSelectedIds] = useState<number[]>([]);
  const [selectedCopies, setSelectedCopies] = useState<Record<number, number>>(
    {},
  );

  const [sameInv, setSameInv] = useState<SameInv[]>([]);

  const [more, setMore] = useState<"yes" | "no">("no");
  const [hasMoreInv, setHasMoreInv] = useState(true);
  const [apiLoading, setApiLoading] = useState(false);
  const [isSellCardsLoading, setIsSellCardsLoading] = useState(false);
  const cardsLoaderRef = useRef<HTMLDivElement | null>(null);
  const packsLoaderRef = useRef<HTMLDivElement | null>(null);
  const dispatch = useAppDispatch();
  const router = useRouter();
  const isFetchingMoreRef = useRef(false);
  const lastOffsetFetchedRef = useRef<number | null>(null);
  const userScrolledRef = useRef(false);
  const lastScrollYRef = useRef(0);
  const isRun = useRef(false);
  const visibleCardsCountRef = useRef(visibleCardsCount);

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

  useEffect(() => {
    if (showPacks) {
      setParentTab("packs");
    }
  }, [showPacks]);

  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]);

  // 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");
    // 👇 SLAB TAB
    if (childTab === "slab")
      return cards.filter((c) => (c.brand ?? "").toLowerCase() === "slab");

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

  const brandCounts = useMemo(() => {
    const list = parentTab === "cards" ? cards : packs;

    const safeCount = (x: any) => Number(x?.count ?? 1) || 0;

    return {
      magic: list
        .filter((x: any) => x.brand === "MTG")
        .reduce((s: number, x: any) => s + safeCount(x), 0),

      pokemon: list
        .filter((x: any) => x.brand === "Pokemon")
        .reduce((s: number, x: any) => s + safeCount(x), 0),

      lorcana: list
        .filter((x: any) => x.brand === "Lorcana")
        .reduce((s: number, x: any) => s + safeCount(x), 0),

      slab: list
        .filter((x: any) => (x.brand ?? "").toLowerCase() === "slab")
        .reduce((s: number, x: any) => s + safeCount(x), 0),
    };
  }, [parentTab, cards, packs]); // ✅ update deps

  const uiPacks: CardItem[] = useMemo(
    () =>
      filteredPacks.map((p, index) => {
        return {
          invIds: [p.inv_id],
          id: `${p.un_id}`,
          backendId: p.inv_id,
          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",
          inv_id: p.inv_id,
        };
      }),
    [filteredPacks],
  );

  const uiCardsAll: CardItem[] = useMemo(() => {
    const sorted = [...cards].sort((a, b) => a.inv_id - b.inv_id);

    return buildGroupedCards(sorted, sameInv);
  }, [cards, sameInv]);

  const uiPacksAll: CardItem[] = useMemo(() => {
    return packs.map((p) => ({
      invIds: [p.inv_id],
      id: `${p.un_id}`,
      backendId: p.inv_id,
      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",
      inv_id: p.inv_id,
    }));
  }, [packs]);

  const uiCards: CardItem[] = useMemo(() => {
    const sorted = [...filteredCards].sort((a, b) => a.inv_id - b.inv_id);
    return buildGroupedCards(sorted, sameInv);
  }, [filteredCards, sameInv]);

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

  const getPriceNumber = (p: string | number) => {
    if (typeof p === "number") return p;
    const n = parseFloat(String(p).replace(/[^0-9.]/g, ""));
    return Number.isFinite(n) ? n : 0;
  };

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

    return uiCards.filter((item) => {
      const name = item.name?.toLowerCase() ?? "";
      const series = item.series?.toLowerCase() ?? "";
      const rarity = item.rarity?.toLowerCase() ?? "";
      return (
        name.includes(searchText) ||
        series.includes(searchText) ||
        rarity.includes(searchText)
      );
    });
  }, [uiCards, searchText]);

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

    return uiPacks.filter((item) => {
      const name = item.name?.toLowerCase() ?? "";
      const series = item.series?.toLowerCase() ?? "";
      const rarity = item.rarity?.toLowerCase() ?? "";
      return (
        name.includes(searchText) ||
        series.includes(searchText) ||
        rarity.includes(searchText)
      );
    });
  }, [uiPacks, searchText]);

  // 🔥 PRICE SORT (HIGH → LOW)
  const sortedSearchedCards: CardItem[] = useMemo(() => {
    return [...searchedCards].sort(
      (a, b) => getPriceNumber(b.price) - getPriceNumber(a.price),
    );
  }, [searchedCards]);

  const sortedSearchedPacks: CardItem[] = useMemo(() => {
    return [...searchedPacks].sort(
      (a, b) => getPriceNumber(b.price) - getPriceNumber(a.price),
    );
  }, [searchedPacks]);

  const allDisplayItems: CardItem[] = useMemo(() => {
    if (parentTab === "cards") {
      return sortedSearchedCards.slice(0, visibleCardsCount);
    }
    return sortedSearchedPacks.slice(0, visiblePacksCount);
  }, [
    parentTab,
    sortedSearchedCards,
    sortedSearchedPacks,
    visibleCardsCount,
    visiblePacksCount,
  ]);

  const allInventoryItems: CardItem[] = useMemo(() => {
    return [...uiCardsAll, ...uiPacksAll];
  }, [uiCardsAll, uiPacksAll]);

  const selectedItems = useMemo(() => {
    // selection should not depend on current tab or current page slice
    return allInventoryItems.filter((i) => selectedIds.includes(i.inv_id));
  }, [allInventoryItems, selectedIds]);

  // ✅ count = selected quantities ka sum
  const selectedCount = selectedItems.reduce((sum, item) => {
    const qty =
      selectedCopies[item.inv_id] ??
      (selectedIds.includes(item.inv_id) ? (item.quantity ?? 1) : 0);
    return sum + qty;
  }, 0);

  const isLockedAll =
    selectedItems.length > 0 &&
    selectedItems.every((item) => lockedIds.includes(item.inv_id));

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

  const allIdsOnScreen = allDisplayItems.map((i) => i.inv_id);

  const toggleSelect = (item: any) => {
    setSelectedIds((prev) => {
      const groupIds: number[] = item?.invIds?.length
        ? item.invIds
        : [item.inv_id]; // ✅ expand

      const isAlreadySelected = prev.includes(item.inv_id); // ✅ minId check (same as before)

      if (isAlreadySelected) {
        // ✅ remove ALL ids of that group
        setSelectedCopies((prevCopies) => {
          const { [item.inv_id]: _, ...rest } = prevCopies;
          return rest;
        });

        return prev.filter((x) => !groupIds.includes(x));
      } else {
        // ✅ select ALL ids of that group
        setSelectedCopies((prevCopies) => ({
          ...prevCopies,
          [item.inv_id]: item.quantity ?? 1, // keep as before
        }));

        return Array.from(new Set([...prev, ...groupIds]));
      }
    });
  };

  const handleSelectAll = () => {
    // ✅ expand all ids on screen
    const expandedAllIds = allDisplayItems.flatMap((i) =>
      i?.invIds?.length ? i.invIds : [i.inv_id],
    );

    // if everything selected -> clear
    const allSelected = expandedAllIds.every((id) => selectedIds.includes(id));

    if (allSelected) {
      setSelectedIds((prev) =>
        prev.filter((id) => !expandedAllIds.includes(id)),
      );
      setSelectedCopies({});
    } else {
      setSelectedIds((prev) =>
        Array.from(new Set([...prev, ...expandedAllIds])),
      );

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

  const handleLockSelected = async () => {
    if (selectedItems.length === 0) return;

    // Is everything selected already locked?
    const allSelectedLocked = selectedItems.every((item) =>
      lockedIds.includes(item.inv_id),
    );

    const shouldLock = allSelectedLocked ? 0 : 1;

    // Backend needs inv_id → stored as backendId
    const cardIds = selectedItems
      .flatMap((item) => {
        const qty = selectedCopies[item.inv_id] ?? item.quantity ?? 1;
        const ids = item.invIds?.length ? item.invIds : [item.backendId];
        return ids.slice(0, qty);
      })
      .filter((id) => typeof id === "number" && !Number.isNaN(id));

    if (cardIds.length === 0) return;

    try {
      await lockInventoryCards(user.userId, cardIds, shouldLock, user.token);

      // Update UI state after success
      if (shouldLock) {
        // 🔐 LOCK in UI
        setLockedIds((prev) => Array.from(new Set([...prev, ...selectedIds])));
      } else {
        // 🔓 UNLOCK in UI
        setLockedIds((prev) => prev.filter((id) => !selectedIds.includes(id)));
      }
    } catch (err: any) {
      console.error("Lock error:", err);
      alert(err.message || "Failed to update lock/unlock status.");
    }
  };

  const handleUnlockAll = async () => {
    if (!lockedIds || lockedIds.length === 0) return;

    try {
      // 0 = unlock
      await lockInventoryCards(user.userId, lockedIds, 0, user.token);

      // UI se bhi clear kar do
      setLockedIds([]);
    } catch (err: any) {
      console.error("Unlock All error:", err);
      alert(err.message || "Failed to unlock cards.");
    }
  };

  const handleSellCards = () => {
    if (selectedItems.length === 0) return; // optional: no items selected, do nothing / show toast
    setIsSellModalOpen(true);
  };

  const loadPacks = async () => {
    try {
      setIsLoadingPacks(true);
      setPacksError(null);

      const data = await fetchInventoryPacks(user?.userId, user?.token);
      setPacks(data);
      setHasLoadedPacks(true);
    } catch (err: any) {
      console.error(err);
      setPacksError(err.message ?? "Failed to load packs");
    } finally {
      setIsLoadingPacks(false);
    }
  };

  const loadCards = async (userId: any, token: any) => {
    setIsLoadingCards(true);
    setCardsError(null);
    try {
      const data = await fetchInventoryCards(userId, "yes", token);
      setCards(data.cards);
      setSameInv(data.same ?? []);
      setOffset(data?.offset ?? null);
      setMore(data.more as "yes" | "no");
      setHasMoreInv(data.more === "yes");
      lastOffsetFetchedRef.current = null; // ✅ ADD
      isFetchingMoreRef.current = false;
      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]);
      if (data.same?.length) setSameInv((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 toggleLockOne = async (item: CardItem) => {
    if (!item?.backendId || typeof item.backendId !== "number") return;

    // if currently locked -> unlock, else lock
    const shouldLock: 0 | 1 = lockedIds.includes(item.inv_id) ? 0 : 1;

    // ✅ quantity jitni ids bhejo (same behavior as Lock All/Unlock All)
    const qty = selectedCopies[item.inv_id] ?? item.quantity ?? 1;

    // If invIds exist, use them, else repeat backendId qty times
    const idsToSend = item.invIds?.length
      ? item.invIds.slice(0, qty)
      : Array.from({ length: qty }, () => item.backendId);

    try {
      await lockInventoryCards(user.userId, idsToSend, shouldLock, user.token);

      setLockedIds((prev) => {
        if (shouldLock) {
          // lock UI
          return Array.from(new Set([...prev, item.inv_id]));
        } else {
          // unlock UI
          return prev.filter((x) => x !== item.inv_id);
        }
      });
    } catch (err: any) {
      console.error("Single lock error:", err);
      alert(err.message || "Failed to lock/unlock card.");
    }
  };

  useEffect(() => {
    lastScrollYRef.current = window.scrollY;

    const onScroll = () => {
      // user actually scrolled (down/up). You can make it "down only" if you want.
      if (Math.abs(window.scrollY - lastScrollYRef.current) > 5) {
        userScrolledRef.current = true;
        lastScrollYRef.current = window.scrollY;
      }
    };

    window.addEventListener("scroll", onScroll, { passive: true });
    return () => window.removeEventListener("scroll", onScroll);
  }, []);

  useEffect(() => {
    // search type karte hi first page se start
    if (parentTab === "cards") setVisibleCardsCount(CARDS_PAGE_SIZE);
    if (parentTab === "packs") setVisiblePacksCount(PACKS_PAGE_SIZE);
    userScrolledRef.current = false; // ✅ reset: search typing pe auto load nahi
    lastScrollYRef.current = window.scrollY;
  }, [search, parentTab, childTab]);

  useEffect(() => {
    if (!user.userId || !user.token) return;
    if (parentTab === "packs" && !hasLoadedPacks) {
      loadPacks();
    }
  }, [parentTab, hasLoadedPacks]);

  useEffect(() => {
    if (isRun.current) return;

    isRun.current = true;

    if (parentTab === "cards" && !hasLoadedCards) {
      if (showPacks) return;
      loadCards(user.userId, user.token);
    }
  }, [parentTab, hasLoadedCards]);

  async function openPack(pack: any) {
    try {
      router.push(`/inventory/${pack.brand}/${pack.id}`);
    } catch (err) {
      console.log("ERROR", err);
    }
  }

  const fetchCards = () => {
    if (showPacks) {
      loadCards(user.userId, user.token);
    }
  };
  useEffect(() => {
    if (parentTab === "cards") {
      setVisibleCardsCount(CARDS_PAGE_SIZE);
    }
    if (parentTab === "packs") {
      setVisiblePacksCount(PACKS_PAGE_SIZE);
    }
  }, [parentTab]);

  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 (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, hasMoreInv, apiLoading, offset, more]);

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

    const node = packsLoaderRef.current;
    if (!node) return;

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

        setVisiblePacksCount((prev) => {
          if (prev >= searchedPacks.length) return prev; // aur packs nahi hain
          return prev + PACKS_PAGE_SIZE;
        });
      },
      {
        root: null,
        rootMargin: "0px 0px 200px 0px",
        threshold: 0,
      },
    );

    observer.observe(node);

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

  useEffect(() => {
    if (!cards.length) return;

    const initiallyLocked = cards
      .filter((c) => c.locked === 1)
      .map((c) => c.inv_id);

    setLockedIds(initiallyLocked);
  }, [cards]);

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

  function buildGroupedCards(
    list: InventoryCard[],
    same: SameInv[] = [],
  ): CardItem[] {
    const map = new Map<string, CardItem>();

    // ✅ same[] ko card_id ke basis pe queue bana do
    const sameByCardId = new Map<number, number[]>();
    for (const s of same) {
      const cid = Number(s.card_id);
      const arr = sameByCardId.get(cid) ?? [];
      arr.push(Number(s.inv_id));
      sameByCardId.set(cid, arr);
    }

    for (const c of list) {
      const cardId = Number(c.id);

      const isSlab = String(c.brand ?? "").toLowerCase() === "slab";

      // ✅ SLAB: key MUST be unique per inventory row (use inv_id)
      const key = isSlab
        ? `slab|${Number(c.inv_id)}`
        : [
            cardId,
            c.rarity ?? "",
            c.pack_name ?? "",
            c.brand ?? "",
            c.image ?? "",
            Number(c.price || 0),
          ].join("|");

      const qty = c.count ?? 1;

      // ✅ qty>1 ho to same[] se extra inv_id(s) uthao
      const extrasQueue = sameByCardId.get(cardId) ?? [];
      const need = Math.max(0, qty - 1);
      const extras = extrasQueue.splice(0, need); // ✅ consume (reuse nahi honge)
      sameByCardId.set(cardId, extrasQueue);

      const invIdsForThisRow = [Number(c.inv_id), ...extras];
      while (invIdsForThisRow.length < qty)
        invIdsForThisRow.push(Number(c.inv_id)); // safety

      if (!map.has(key)) {
        map.set(key, {
          id: key,
          inv_id: c.inv_id,
          backendId: c.inv_id,
          invIds: invIdsForThisRow, // ✅ REAL ids (same se)
          cardId,
          name: c.name,
          price: `$${Number(c.price || 0).toFixed(2)}`,
          series: c.pack_name,
          image: c.image,
          brand: c.brand,
          quantity: qty,
          rarity: c.rarity,
        });
      } else {
        // ✅ never merge SLAB cards
        if (String(c.brand ?? "").toLowerCase() === "slab") {
          map.set(`slab|${Number(c.inv_id)}`, {
            id: `slab|${Number(c.inv_id)}`,
            inv_id: c.inv_id,
            backendId: c.inv_id,
            invIds: [Number(c.inv_id)],
            cardId,
            name: c.name,
            price: `$${Number(c.price || 0).toFixed(2)}`,
            series: c.pack_name,
            image: c.image,
            brand: c.brand,
            quantity: 1,
            rarity: c.rarity,
          });
          continue;
        }

        const existing = map.get(key)!;
        existing.quantity += qty;
        existing.invIds.push(...invIdsForThisRow);
        const minId = Math.min(existing.inv_id, c.inv_id);
        existing.inv_id = minId;
        existing.backendId = minId;
      }
    }

    return Array.from(map.values());
  }

  const showAllBrands = useMemo(() => {
    const activeBrands = [
      brandCounts.magic,
      brandCounts.pokemon,
      brandCounts.lorcana,
      brandCounts.slab,
    ].filter((n) => n > 0).length;

    return activeBrands >= 2; // ✅ only if 2 or more brands have data
  }, [brandCounts]);

  useEffect(() => {
    const available = (Object.entries(brandCounts) as [ChildTab, number][])
      .filter(([_, count]) => count > 0)
      .map(([key]) => key);

    // ✅ If only one brand has data, force-select it
    if (available.length === 1) {
      const onlyBrand = available[0];
      if (childTab !== onlyBrand) setChildTab(onlyBrand);
      return;
    }

    // ✅ If multiple brands, and current tab is invalid, fallback to "all"
    if (
      available.length > 1 &&
      childTab !== "all" &&
      !available.includes(childTab)
    ) {
      setChildTab("all");
    }
  }, [brandCounts, childTab, setChildTab]);

  const uiHasMore = searchedCards.length > visibleCardsCount;
  const canLoadMore = hasMoreInv && uiHasMore;

  return (
    <div className="min-h-screen no-scrollbar bg-black text-white">
      {/* Header */}
      {/* sticky top-0 */}
      <InventoryHeader
        parentTab={parentTab}
        setParentTab={setParentTab}
        childTab={childTab}
        setChildTab={setChildTab}
        search={search}
        setSearch={setSearch}
        showAllBrands={showAllBrands}
        onBack={() => router.back()} // or set some state / navigation
        brandCounts={brandCounts}
        fetchCards={fetchCards}
        isLockedAll={isLockedAll}
        onLockSelected={handleUnlockAll}
        hasLockedCards={lockedIds.length > 0}
      />

      {(parentTab === "packs" && isLoadingPacks && !hasLoadedPacks) ||
      (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 no-scrollbar mx-auto py-3 md:py-8  2xl:py-8">
            {/* <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-6 2xl:grid-cols-7 justify-items-center gap-3 2xl:gap-7 pb-10"> */}
            <div
              // justify-items-center
              className="
    grid pb-10
    justify-start
    gap-3 2xl:gap-7
    [grid-template-columns:repeat(auto-fill,minmax(120px,1fr))]
    sm:[grid-template-columns:repeat(auto-fill,minmax(140px,1fr))]
    lg:[grid-template-columns:repeat(auto-fill,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 && (
                <>
                  {allDisplayItems
                    .slice() // original array ko mutate hone se bachata hai
                    .sort((a: any, b: any) => b.price - a.price)
                    .map((item, index) => {
                      const isSelected = selectedIds.includes(item.inv_id);
                      const isLocked = lockedIds.includes(item.inv_id);
                      return (
                        <div
                          key={index}
                          onClick={() => {
                            console.log("click");
                            if (parentTab === "cards") {
                              if (isLocked) return;
                              toggleSelect(item);
                            }
                          }}
                          className={` col-span-1 hover:-translate-y-1 duration-500 group relative h-65 2xl:h-88.75 w-full   max-w-50 overflow-hidden transition-all cursor-pointer
${isLocked ? "  bg-[#202A38]" : ""}
${isSelected && !isLocked && " ring-2 ring-(--color-blue)"}
`}
                        >
                          {!isLocked && (
                            <div className="pointer-events-none absolute group-hover:w-40 bottom-17 left-1/2 -translate-x-1/2 w-37.5 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 ">
                            {/* Card Image */}
                            <div className=" flex justify-center">
                              {item.quantity > 1 && (
                                <div className="absolute  transiton-all duration-500 top-3 left-3 bg-(--color-gray) text-[#DBFAFF] px-2 py-1 rounded-full text-sm font-semibold">
                                  {item.quantity}
                                </div>
                              )}
                              {parentTab !== "packs" && (
                                <div
                                  onClick={(e) => {
                                    e.stopPropagation();
                                    toggleLockOne(item);
                                  }}
                                  className="absolute border duration-300 border-transparent w-8 flex items-center justify-center cursor-pointer h-8  hover:border-white top-3 right-3"
                                >
                                  <img
                                    src={
                                      isLocked
                                        ? "/images/inventory/lock-ac.svg"
                                        : "/images/inventory/lock.svg"
                                    }
                                    alt=""
                                  />
                                </div>
                              )}

                              <div className="w-18 h-24 2xl:w-25 2xl:h-38.25 ">
                                {item?.image && (
                                  <Image
                                    src={item?.image.replace(
                                      "cardsimages",
                                      "cards/images",
                                    )}
                                    width={110}
                                    height={153}
                                    alt={item.name}
                                    className={`
                                    ${
                                      parentTab === "packs"
                                        ? ""
                                        : "img-border-radius"
                                    }
                                    w-full h-full 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 line-clamp-2 uppercase">
                                {String(item.name).length > 20
                                  ? String(item.name).slice(0, 20) + "…"
                                  : item.name}
                              </h3>
                              <div className="text-xl flex items-center justify-center gap-1 font-bold text-green-400 ">
                                {user?.activeMode === "coins" ? (
                                  <img
                                    src="/images/header/win.svg"
                                    alt=""
                                    className="h-4 w-4"
                                  />
                                ) : (
                                  <img
                                    src="/images/header/star.svg"
                                    alt=""
                                    className="h-4 w-4"
                                  />
                                )}
                                {item.price.replace("$", "")}
                              </div>
                              <div className="text-xs text-(--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-(--color-blue) flex items-center justify-center py-2.5 md:py-3 px-4">
                                      <img
                                        src="/images/coinFlip/modal/tick.svg"
                                        alt="tick"
                                        className="w-3 h-3 "
                                      />
                                    </div>

                                    {/* VIEW BUTTON (full remaining width) */}
                                    {item.quantity > 1 && (
                                      <div className="flex-1 ">
                                        <button
                                          onClick={(e) => {
                                            e.stopPropagation();
                                            setDetailCard(item);
                                            setOpenDrawer(true);

                                            setSelectedIds((prev) =>
                                              prev.includes(item.inv_id)
                                                ? prev
                                                : [...prev, item.inv_id],
                                            );

                                            setSelectedCopies((prev) =>
                                              prev[item.inv_id]
                                                ? prev
                                                : {
                                                    ...prev,
                                                    [item.inv_id]:
                                                      item.quantity ?? 1,
                                                  },
                                            );
                                          }}
                                          className="text-center text-xs md:text-sm w-full duration-500 transition-all 2xl:text-base bg-[var(--color-blue)] hover:bg-[var(--color-hoverBlue)]  text-white font-bold py-2 cursor-pointer "
                                        >
                                          VIEW
                                        </button>
                                      </div>
                                    )}
                                  </div>
                                </div>
                              ) : (
                                // Not selected → normal full-width button
                                <button
                                  onClick={(e) => {
                                    e.stopPropagation();
                                    setOpenDrawer(true);
                                    if (parentTab === "packs") {
                                      dispatch(
                                        setSelectedPackCover(item.image),
                                      );
                                      openPack(item); // 👉 call your function here
                                    } else {
                                      setDetailCard(item);
                                    }
                                  }}
                                  className={`w-full text-xs md:text-sm group-hover:md:text-base duration-500 transition-all 2xl:text-base absolute bottom-0 bg-[var(--color-blue)] hover:bg-blue-700 text-white font-bold py-2 2xl:py-3 cursor-pointer`}
                                >
                                  {parentTab === "packs" ? "OPEN PACK" : "VIEW"}
                                </button>
                              )}
                            </>
                          )}
                        </div>
                      );
                    })}
                </>
              )}
            </div>
            {/* Infinite scroll sentinel for CARDS */}
            {!noResults && (
              <>
                {parentTab === "cards" &&
                  (searchedCards.length > visibleCardsCount || hasMoreInv) && (
                    <div
                      ref={cardsLoaderRef}
                      className="h-8 mb-20 flex items-center justify-center text-xs text-(--color-slate)"
                    >
                      {apiLoading
                        ? "Loading more cards..."
                        : canLoadMore
                          ? "Scroll to load more..."
                          : ""}
                    </div>
                  )}
              </>
            )}

            {/* Infinite scroll sentinel for PACKS */}
            {parentTab === "packs" &&
              searchedPacks.length > visiblePacksCount && (
                <div
                  ref={packsLoaderRef}
                  className="h-8 mb-20 flex items-center justify-center text-xs text-(--color-slate)"
                >
                  Loading more packs...
                </div>
              )}
          </div>
          {/* Bottom bar – only when something selected */}
          {parentTab === "cards" && (
            <InventoryActionBar
              user={user}
              childTab={childTab}
              selectedCount={selectedCount}
              selectedItemCount={selectedIds.length}
              allOnScreenCount={allIdsOnScreen.length}
              totalValue={totalValue}
              onSelectAll={handleSelectAll}
              onLockSelected={handleLockSelected}
              onSell={handleSellCards}
              isLockedAll={isLockedAll}
            />
          )}

          {/* Right side drawer */}
          <InventoryDetailDrawer
            user={user}
            card={detailCard}
            onClose={() => setDetailCard(null)}
            setIsOpenCardModal={setIsOpenCardModal}
            setIsOpen={setOpenDrawer}
            isOpen={opendrawer}
          />

          <CardSelectionModal
            user={user}
            isOpen={isOpenCardModal}
            setIsOpen={setIsOpenCardModal}
            card={detailCard}
            selectedQuantity={
              detailCard
                ? (selectedCopies[detailCard.inv_id] ??
                  (selectedIds.includes(detailCard.inv_id)
                    ? (detailCard.quantity ?? 0)
                    : 0))
                : 0
            }
            onQuantityChange={(qty) => {
              if (!detailCard) return;

              // 1) Keep copies in sync
              setSelectedCopies((prev) => {
                const next = { ...prev };
                if (qty > 0) {
                  next[detailCard.inv_id] = qty;
                } else {
                  delete next[detailCard.inv_id];
                }
                return next;
              });

              setSelectedIds((prev) => {
                const isSelected = prev.includes(detailCard.inv_id);

                if (qty > 0 && !isSelected) {
                  return [...prev, detailCard.inv_id];
                }

                if (qty === 0 && isSelected) {
                  return prev.filter((id) => id !== detailCard.inv_id);
                }

                return prev;
              });
            }}
          />
          <SellConfirmModal
            isOpen={isSellModalOpen}
            onClose={() => setIsSellModalOpen(false)}
            isSellCardsLoading={isSellCardsLoading}
            totalValue={totalValue} // you already compute this as string ".toFixed(2)"
            onConfirm={async () => {
              setIsSellCardsLoading(true);
              try {
                const cardIds = selectedItems
                  .flatMap((item) => {
                    const qty =
                      selectedCopies[item.inv_id] ?? item.quantity ?? 1;

                    // 1) base ids (from UI)
                    const base = (
                      item.invIds?.length ? item.invIds : [item.backendId]
                    ).map(Number);

                    // 2) unique preserve order
                    const seen = new Set<number>();
                    const unique = base.filter(
                      (id) =>
                        Number.isFinite(id) &&
                        !seen.has(id) &&
                        (seen.add(id), true),
                    );

                    // 3) if qty not fulfilled, fill from sameInv by cardId
                    if (unique.length < qty) {
                      const extras = sameInv
                        .filter(
                          (s: any) =>
                            Number(s.card_id ?? s.card) === item.cardId,
                        ) // ✅ card_id OR card
                        .map((s) => Number(s.inv_id))
                        .filter((id) => Number.isFinite(id) && !seen.has(id));

                      for (const id of extras) {
                        if (unique.length >= qty) break;
                        unique.push(id);
                        seen.add(id);
                      }
                    }

                    return unique.slice(0, qty);
                  })
                  .filter((id) => typeof id === "number" && !Number.isNaN(id))
                  .filter((id) => !lockedIds.includes(id));

                if (!cardIds.length) {
                  console.warn("No valid card IDs to sell");
                  setIsSellModalOpen(false);
                  return;
                }

                const data = await sellInventoryCards(
                  user.userId,
                  cardIds,
                  "yes",
                  user.token,
                );
                console.log("data", data);
                if (data?.error) {
                  setIsSellCardsLoading(false);
                  setModalType("error");
                  setModalMsg(data.error);
                  setModalOpen(true);
                  return;
                }
                if (data?.resp === "success") {
                  setIsSellCardsLoading(false);
                  setIsSellModalOpen(false);
                  dispatch(
                    updateUser({ coins: data?.coins, gems: data?.gems }),
                  );
                  await updateSession({ coins: data?.coins, gems: data?.gems });
                  setModalType("success");
                  setModalMsg("sell card successfully");
                  setModalOpen(true);
                }

                await loadCards(user.userId, user.token); // refresh inventory
                setSelectedIds([]);
                setSelectedCopies({});
                setIsSellModalOpen(false);
              } catch (err: any) {
                console.error("Sell error:", err);
                alert(err.message || "Failed to sell cards");
              }
            }}
          />
        </>
      )}
      <AlertModal
        open={modalOpen}
        type={modalType}
        message={modalMsg}
        onClose={() => setModalOpen(false)}
      />
    </div>
  );
}
