"use client";

import React, {
  createContext,
  useCallback,
  useContext,
  useEffect,
  useMemo,
  useState,
} from "react";
import Cookies from "js-cookie";
import DataService from "@/config/axios";

export type PublicUser = {
  _id: string;
  username: string;
  firstName?: string;
  lastName?: string;
  email?: string;
  type?: string;
};

type PublicSessionContextValue = {
  user: PublicUser | null;
  loading: boolean;
  refresh: () => Promise<void>;
  isAuthenticated: boolean;
  /** Number of wishlist rows (0 when logged out). */
  wishlistCount: number;
};

const PublicSessionContext = createContext<PublicSessionContextValue | null>(null);

export function PublicSessionProvider({ children }: { children: React.ReactNode }) {
  const [user, setUser] = useState<PublicUser | null>(null);
  const [loading, setLoading] = useState(true);
  const [wishlistCount, setWishlistCount] = useState(0);

  const refresh = useCallback(async () => {
    const token = Cookies.get("token");
    if (!token) {
      setUser(null);
      setWishlistCount(0);
      setLoading(false);
      return;
    }
    try {
      const res = await DataService.get("/user/me");
      const u = (res.data?.data ?? null) as PublicUser | null;
      setUser(u);
      if (u) {
        try {
          const w = await DataService.get("/user/shop/wishlist");
          const arr = w.data?.data;
          setWishlistCount(Array.isArray(arr) ? arr.length : 0);
        } catch {
          setWishlistCount(0);
        }
      } else {
        setWishlistCount(0);
      }
    } catch {
      setUser(null);
      setWishlistCount(0);
    } finally {
      setLoading(false);
    }
  }, []);

  useEffect(() => {
    refresh();
  }, [refresh]);

  const value = useMemo(
    () => ({
      user,
      loading,
      refresh,
      isAuthenticated: Boolean(user),
      wishlistCount,
    }),
    [user, loading, refresh, wishlistCount],
  );

  return (
    <PublicSessionContext.Provider value={value}>{children}</PublicSessionContext.Provider>
  );
}

export function usePublicSession() {
  const ctx = useContext(PublicSessionContext);
  if (!ctx) {
    throw new Error("usePublicSession must be used within PublicSessionProvider");
  }
  return ctx;
}
