import { createContext, useContext, useEffect, useState, useCallback, useRef } from 'react';
import { api, getSocket, socketAuth, disconnectSocket } from '../api';

const TOKEN_KEY = 'irohbet_token';
const AuthContext = createContext(null);

// Token, localStorage'dan çekilir; onceden bağlanmış socket varsa yeni token gönder.
let cachedToken = null;
export function getToken() {
  if (cachedToken) return cachedToken;
  return localStorage.getItem(TOKEN_KEY);
}

export function AuthProvider({ children }) {
  const [user, setUser] = useState(null);
  const [loading, setLoading] = useState(true);
  const [balance, setBalance] = useState(null); // cents
  const [locked, setLocked] = useState(null); // cents
  const [badgeEvent, setBadgeEvent] = useState(null);
  const [avatarEvent, setAvatarEvent] = useState(null);
  const userRef = useRef(null);
  userRef.current = user;

  // balance güncelle → ayrıca user.wallet da güncelle (senkron kal)
  const applyBalance = useCallback((b) => {
    setBalance(b.balanceCents ?? null);
    setLocked(b.lockedCents ?? null);
    setUser((u) => (u ? { ...u, wallet: { ...(u.wallet || {}), ...b } } : u));
  }, []);

  // Socket olaylarını bağla
  useEffect(() => {
    const s = getSocket();
    const onBalance = (data) => applyBalance(data);
    const onBadge = (data) => setBadgeEvent((prev) => ({ ...(prev || {}), ...data, _n: (prev?._n || 0) + 1 }));
    const onAvatar = (data) => {
      setAvatarEvent((prev) => ({ ...data, _n: (prev?._n || 0) + 1 }));
      setUser((u) => (u ? { ...u, isAvatar: true, avatarAt: data?.avatarAt || u.avatarAt } : u));
    };
    s.on('balance', onBalance);
    s.on('badge', onBadge);
    s.on('avatar', onAvatar);
    return () => {
      s.off('balance', onBalance);
      s.off('badge', onBadge);
      s.off('avatar', onAvatar);
    };
  }, [applyBalance]);

  const loadMe = useCallback(async () => {
    const t = getToken();
    if (!t) {
      setUser(null);
      setLoading(false);
      return null;
    }
    try {
      const me = await api('/auth/me', { token: t });
      setUser(me);
      if (me?.wallet) applyBalance(me.wallet);
      socketAuth(t);
      return me;
    } catch (e) {
      if (e.status === 401) {
        localStorage.removeItem(TOKEN_KEY);
        setUser(null);
      }
      return null;
    } finally {
      setLoading(false);
    }
  }, [applyBalance]);

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

  const login = useCallback(async (email, password) => {
    const data = await api('/auth/login', { method: 'POST', body: { email, password } });
    localStorage.setItem(TOKEN_KEY, data.token);
    cachedToken = data.token;
    setUser(data.user);
    if (data.user?.wallet) applyBalance(data.user.wallet);
    socketAuth(data.token);
    return data.user;
  }, [applyBalance]);

  const register = useCallback(async (email, username, password) => {
    const data = await api('/auth/register', { method: 'POST', body: { email, username, password } });
    localStorage.setItem(TOKEN_KEY, data.token);
    cachedToken = data.token;
    setUser(data.user);
    if (data.user?.wallet) applyBalance(data.user.wallet);
    socketAuth(data.token);
    return data.user;
  }, [applyBalance]);

  const logout = useCallback(async () => {
    try {
      await api('/auth/logout', { method: 'POST' });
    } catch {
      /* sessiz */
    }
    localStorage.removeItem(TOKEN_KEY);
    cachedToken = null;
    setUser(null);
    setBalance(null);
    setLocked(null);
    disconnectSocket();
  }, []);

  const updateUser = useCallback((patch) => {
    setUser((u) => (u ? { ...u, ...patch } : u));
  }, []);

  // Ulus seçimi
  const selectNation = useCallback(
    async (nation) => {
      const data = await api('/nations/select', { method: 'POST', body: { nation } });
      setUser(data);
      return data;
    },
    []
  );

  const value = {
    user,
    loading,
    balance,
    locked,
    login,
    register,
    logout,
    loadMe,
    updateUser,
    selectNation,
    applyBalance,
    badgeEvent,
    avatarEvent,
    clearBadgeEvent: () => setBadgeEvent(null),
    clearAvatarEvent: () => setAvatarEvent(null),
  };

  return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;
}

export function useAuth() {
  return useContext(AuthContext);
}

// Bileşenlerin bağımsız erişimi için
export { cachedToken };
