"use client";

import { useCallback, useEffect, useMemo, useRef, useState } from "react";

import { useRouter } from "next/navigation";

import Header from "../components/layout/Header";
import Footer from "../components/layout/Footer";

import { getProfile } from "../lib/auth";
import {
  getWalletBalance,
  getWalletTransactions,
  categorizeWalletTransaction,
  WalletTransaction,
} from "../lib/wallet";

const PAGE_SIZE = 20;

function formatDate(iso: string) {
  const date = new Date(iso);
  if (Number.isNaN(date.getTime())) return iso;

  return date.toLocaleString("en-IN", {
    day: "2-digit",
    month: "short",
    year: "numeric",
    hour: "2-digit",
    minute: "2-digit",
  });
}

const ICONS: Record<string, string> = {
  chat: "💬",
  call: "📞",
  debit: "➖",
  credit: "➕",
};

export default function WalletPage() {
  const router = useRouter();

  const [activeTab, setActiveTab] = useState("wallet");
  const [activeHistory, setActiveHistory] = useState("wallet");

  const [loading, setLoading] = useState(true);
  const [loadingMore, setLoadingMore] = useState(false);
  const [hasMore, setHasMore] = useState(true);
  const nextPageRef = useRef(1);
  const loadingMoreRef = useRef(false);
  const hasMoreRef = useRef(true);

  const [balance, setBalance] = useState(0);
  const [transactions, setTransactions] = useState<WalletTransaction[]>([]);

  const [error, setError] = useState("");

  const sentinelRef = useRef<HTMLDivElement | null>(null);

  // Fetches the next page of the real, paginated transactions list and
  // appends it — the backend has no server-side type filter (confirmed
  // in app/lib/wallet.ts), so "load more" always pulls the next chunk
  // of the full history regardless of which tab is active; the tabs
  // below just filter whatever has been loaded so far.
  const loadMore = useCallback(async () => {
    if (loadingMoreRef.current || !hasMoreRef.current) return;

    loadingMoreRef.current = true;
    setLoadingMore(true);

    try {
      const response = await getWalletTransactions(nextPageRef.current, PAGE_SIZE);

      if (response?.success === false) {
        // Stop trying rather than looping on a persistent failure.
        hasMoreRef.current = false;
        setHasMore(false);
        return;
      }

      const list: WalletTransaction[] = Array.isArray(response?.data?.recordList)
        ? response.data.recordList
        : [];

      setTransactions((prev) => [...prev, ...list]);
      nextPageRef.current += 1;

      const noMore = list.length < PAGE_SIZE;
      hasMoreRef.current = !noMore;
      setHasMore(!noMore);
    } catch (err) {
      console.error("Wallet load-more error:", err);
      hasMoreRef.current = false;
      setHasMore(false);
    } finally {
      loadingMoreRef.current = false;
      setLoadingMore(false);
    }
  }, []);

  useEffect(() => {
    let cancelled = false;

    async function loadWallet() {
      const token = localStorage.getItem("token");

      if (!token) {
        router.replace("/signin?redirect=/wallet");
        return;
      }

      try {
        const [profileResponse, transactionsResponse] = await Promise.all([
          getProfile(token),
          getWalletTransactions(1, PAGE_SIZE),
        ]);

        if (cancelled) return;

        let errorMessage = "";

        if (profileResponse?.success === false) {
          errorMessage = profileResponse?.message || "Unable to load wallet balance.";
        } else {
          const freshBalance = getWalletBalance(profileResponse?.user);
          setBalance(freshBalance);

          // Header's profile dropdown shows this same balance from its
          // own login-time cached snapshot, which never updates on its
          // own — this keeps it in sync with whatever the wallet page
          // itself just fetched fresh.
          window.dispatchEvent(new Event("wallet-updated"));
        }

        if (transactionsResponse?.success === false) {
          errorMessage = errorMessage || transactionsResponse?.message || "Unable to load wallet transactions.";
        } else {
          const list: WalletTransaction[] = Array.isArray(transactionsResponse?.data?.recordList)
            ? transactionsResponse.data.recordList
            : [];

          setTransactions(list);
          nextPageRef.current = 2;

          const noMore = list.length < PAGE_SIZE;
          hasMoreRef.current = !noMore;
          setHasMore(!noMore);
        }

        setError(errorMessage);
      } catch (err) {
        console.error("Wallet load error:", err);

        if (!cancelled) {
          setError("Unable to load wallet.");
        }
      } finally {
        if (!cancelled) {
          setLoading(false);
        }
      }
    }

    loadWallet();

    return () => {
      cancelled = true;
    };
  }, [router]);

  // Infinite scroll: load the next page as soon as the sentinel at the
  // bottom of whichever list is currently visible scrolls into view.
  useEffect(() => {
    const node = sentinelRef.current;
    if (!node) return;

    const observer = new IntersectionObserver(
      (entries) => {
        if (entries[0]?.isIntersecting) {
          void loadMore();
        }
      },
      { rootMargin: "200px" },
    );

    observer.observe(node);

    return () => observer.disconnect();
  }, [loadMore, loading]);

  // "All Transactions" means literally all of it — call + chat +
  // everything-else debits — merged back together in the order the
  // server returned it, per explicit request. Payment Logs (recharges,
  // isCredit) stays its own separate sub-tab.
  const visibleTransactions = useMemo(() => {
    if (activeTab === "call") {
      return transactions.filter((tx) => categorizeWalletTransaction(tx) === "call");
    }

    if (activeTab === "chat") {
      return transactions.filter((tx) => categorizeWalletTransaction(tx) === "chat");
    }

    if (activeHistory === "payment") {
      return transactions.filter((tx) => categorizeWalletTransaction(tx) === "payment");
    }

    return transactions.filter((tx) => categorizeWalletTransaction(tx) !== "payment");
  }, [transactions, activeTab, activeHistory]);

  const emptyMessage =
    activeTab === "call"
      ? "No call transactions to show yet."
      : activeTab === "chat"
        ? "No chat transactions to show yet."
        : activeHistory === "payment"
          ? "No payment logs to show yet."
          : "No transactions to show yet.";

  if (loading) {
    return (
      <>
        <Header />
        <main className="horoscope-loading">Loading wallet...</main>
        <Footer />
      </>
    );
  }

  return (
    <>
    <Header />
    <section className="wallet-page py-4">
      <div className="container">

        <div className="wallet-wrapper card-bg-primary">

          {/* Top Tabs */}

          <ul className="nav wallet-nav">
            <li className="nav-item flex-fill">
              <button
                className={`nav-link ${
                  activeTab === "wallet" ? "active" : ""
                }`}
                onClick={() => setActiveTab("wallet")}
              >
                Wallet
              </button>
            </li>

            <li className="nav-item flex-fill">
              <button
                className={`nav-link ${
                  activeTab === "call" ? "active" : ""
                }`}
                onClick={() => setActiveTab("call")}
              >
                Call
              </button>
            </li>

            <li className="nav-item flex-fill">
              <button
                className={`nav-link ${
                  activeTab === "chat" ? "active" : ""
                }`}
                onClick={() => setActiveTab("chat")}
              >
                Chat
              </button>
            </li>
          </ul>

          {/* Balance */}

          <div className="wallet-balance">

            <div>

              <small>Available balance:</small>

              <h2>₹ {balance.toLocaleString("en-IN")}</h2>

              {error && (
                <div className="text-danger small mt-1">{error}</div>
              )}

            </div>

            <button
              className="btn btn-warning rounded-pill px-4"
              onClick={() => router.push("/add-wallet-money/price-list")}
            >
              Recharge
            </button>

          </div>

          {/* History Tabs (only meaningful under the Wallet top tab —
              Call/Chat each show their own single list) */}

          {activeTab === "wallet" && (
            <div className="d-flex gap-3 my-4">

              <button
                className={`history-btn ${
                  activeHistory === "wallet"
                    ? "active"
                    : ""
                }`}
                onClick={() =>
                  setActiveHistory("wallet")
                }
              >
                All Transactions
              </button>

              <button
                className={`history-btn ${
                  activeHistory === "payment"
                    ? "active"
                    : ""
                }`}
                onClick={() =>
                  setActiveHistory("payment")
                }
              >
                Payment Logs
              </button>

            </div>
          )}

          {activeTab !== "wallet" && <div className="mt-4" />}

          {/* Transactions */}

          {visibleTransactions.length === 0 ? (
            <div className="wallet-empty-state text-center">
              <p className="mb-0">{emptyMessage}</p>
            </div>
          ) : (
            <div className="wallet-tx-list">
              {visibleTransactions.map((tx) => (
                <div
                  className="wallet-tx-row"
                  key={tx.id}
                  role="link"
                  tabIndex={0}
                  onClick={() =>
                    router.push(`/wallet/transaction/${tx.id}?type=${encodeURIComponent(tx.transactionType)}`)
                  }
                  onKeyDown={(event) => {
                    if (event.key === "Enter" || event.key === " ") {
                      event.preventDefault();
                      router.push(`/wallet/transaction/${tx.id}?type=${encodeURIComponent(tx.transactionType)}`);
                    }
                  }}
                >
                  <span
                    className={`wallet-tx-icon ${tx.isCredit ? "credit" : "debit"}`}
                  >
                    {ICONS[tx.icon] || (tx.isCredit ? ICONS.credit : ICONS.debit)}
                  </span>

                  <div className="wallet-tx-body">
                    <h5>{tx.title}</h5>
                    <small>{formatDate(tx.createdAt)}</small>
                  </div>

                  <span
                    className={`wallet-tx-amount ${tx.isCredit ? "credit" : "debit"}`}
                  >
                    {tx.isCredit ? "+" : "-"}₹{Math.abs(tx.amount).toLocaleString("en-IN")}
                  </span>
                </div>
              ))}
            </div>
          )}

          {/* Infinite scroll sentinel — pulls the next page of the real
              paginated transactions list into view regardless of which
              tab is active (see loadMore above). */}
          {hasMore && (
            <div ref={sentinelRef} className="wallet-load-more">
              {loadingMore && <span className="wallet-load-more-spinner" aria-hidden="true" />}
              <span>{loadingMore ? "Loading more..." : ""}</span>
            </div>
          )}

          {!hasMore && visibleTransactions.length > 0 && (
            <div className="wallet-list-end">You&apos;ve reached the end.</div>
          )}

        </div>
      </div>
    </section>
    <Footer />
    </>
  );
}
