import React, { createContext, useCallback, useContext, useEffect, useMemo, useState } from 'react';
import { Platform } from 'react-native';
import { authApi } from '../api/endpoints';
import { api, apiErrorMessage, setRefreshHandler } from '../api/client';
import { tokenStore } from '../storage/secure';

export interface AuthUser {
  id: number;
  username: string;
  full_name: string;
  avatar_url: string | null;
  level?: number;
  vip_badge?: string | null;
  frame_url?: string | null;
  unique_id?: string;
}

interface AuthCtx {
  user: AuthUser | null;
  booting: boolean;
  login: (identifier: string, password: string) => Promise<void>;
  register: (payload: Record<string, unknown>) => Promise<void>;
  logout: () => Promise<void>;
  refreshMe: () => Promise<void>;
}

const Ctx = createContext<AuthCtx>(null as unknown as AuthCtx);

export function AuthProvider({ children }: { children: React.ReactNode }) {
  const [user, setUser] = useState<AuthUser | null>(null);
  const [booting, setBooting] = useState(true);

  const refreshMe = useCallback(async () => {
    try {
      const res = await api.get('/users/me');
      setUser(res.data.data.user);
    } catch {
      /* keep current */
    }
  }, []);

  useEffect(() => {
    setRefreshHandler(async () => {
      try {
        const refresh = tokenStore.getRefreshToken();
        if (!refresh) return null;
        const res = await authApi.refresh(refresh);
        tokenStore.setTokens(res.accessToken, res.refreshToken);
        return res.accessToken as string;
      } catch {
        tokenStore.clear();
        setUser(null);
        return null;
      }
    });

    (async () => {
      const token = tokenStore.getAccessToken();
      if (token) {
        try {
          const res = await api.get('/users/me');
          setUser(res.data.data.user);
        } catch {
          tokenStore.clear();
        }
      }
      setBooting(false);
    })();
  }, []);

  const login = useCallback(async (identifier: string, password: string) => {
    try {
      const res = await authApi.login(identifier, password);
      tokenStore.setTokens(res.accessToken, res.refreshToken);
      const me = await api.get('/users/me');
      setUser(me.data.data.user);
    } catch (err) {
      throw new Error(apiErrorMessage(err));
    }
  }, []);

  const register = useCallback(async (payload: Record<string, unknown>) => {
    try {
      const res = await authApi.register(payload);
      tokenStore.setTokens(res.accessToken, res.refreshToken);
      const me = await api.get('/users/me');
      setUser(me.data.data.user);
    } catch (err) {
      throw new Error(apiErrorMessage(err));
    }
  }, []);

  const logout = useCallback(async () => {
    await authApi.logout(tokenStore.getRefreshToken());
    tokenStore.clear();
    setUser(null);
  }, []);

  // Register device for push notifications (token arrives from FCM setup — see BUILD_GUIDE)
  useEffect(() => {
    if (user) {
      usersDeviceRegister();
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [user?.id]);

  async function usersDeviceRegister() {
    try {
      const { usersApi } = await import('../api/endpoints');
      await usersApi.registerDevice(`${Platform.OS}-${Date.now().toString(36)}`, Platform.OS === 'android' ? 'android' : 'ios');
    } catch {
      /* non-fatal */
    }
  }

  const value = useMemo(() => ({ user, booting, login, register, logout, refreshMe }), [user, booting, login, register, logout, refreshMe]);
  return <Ctx.Provider value={value}>{children}</Ctx.Provider>;
}

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