import { create } from 'zustand';
import { ApiError } from './api-client';
import { authApi, type UserProfile, type LoginPayload, type RegisterPayload } from './auth-api';

function hasAuthCookie(): boolean {
  if (typeof document === 'undefined') return false;
  return document.cookie.includes('goodgo_authenticated=1');
}

interface AuthState {
  user: UserProfile | null;
  isAuthenticated: boolean;
  isInitialized: boolean;
  isLoading: boolean;
  error: string | null;

  login: (data: LoginPayload) => Promise<void>;
  register: (data: RegisterPayload) => Promise<void>;
  handleOAuthCallback: (accessToken: string, refreshToken: string, expiresIn?: number) => Promise<void>;
  logout: () => Promise<void>;
  refreshToken: () => Promise<boolean>;
  fetchProfile: () => Promise<void>;
  initialize: () => Promise<void>;
  clearError: () => void;
}

export const useAuthStore = create<AuthState>((set, get) => ({
  user: null,
  isAuthenticated: false,
  isInitialized: false,
  isLoading: false,
  error: null,

  login: async (data) => {
    set({ isLoading: true, error: null });
    try {
      await authApi.login(data);
      set({ isAuthenticated: true, isLoading: false });
      await get().fetchProfile();
    } catch (e) {
      const message = e instanceof ApiError ? e.message : 'Đăng nhập thất bại';
      set({ isLoading: false, error: message });
      throw e;
    }
  },

  register: async (data) => {
    set({ isLoading: true, error: null });
    try {
      await authApi.register(data);
      set({ isAuthenticated: true, isLoading: false });
      await get().fetchProfile();
    } catch (e) {
      const message = e instanceof ApiError ? e.message : 'Đăng ký thất bại';
      set({ isLoading: false, error: message });
      throw e;
    }
  },

  handleOAuthCallback: async (accessToken, refreshToken, expiresIn) => {
    set({ isLoading: true, error: null });
    try {
      await authApi.exchangeToken(accessToken, refreshToken, expiresIn);
      set({ isAuthenticated: true, isLoading: false });
      await get().fetchProfile();
    } catch (e) {
      const message = e instanceof ApiError ? e.message : 'Đăng nhập OAuth thất bại';
      set({ isLoading: false, error: message });
      throw e;
    }
  },

  logout: async () => {
    try {
      await authApi.logout();
    } catch {
      // Clear state even if API call fails
    }
    set({ user: null, isAuthenticated: false, error: null });
  },

  refreshToken: async () => {
    try {
      await authApi.refresh();
      set({ isAuthenticated: true });
      return true;
    } catch {
      set({ user: null, isAuthenticated: false });
      return false;
    }
  },

  fetchProfile: async () => {
    try {
      const user = await authApi.getProfile();
      set({ user, isAuthenticated: true });
    } catch (e) {
      if (e instanceof ApiError && e.status === 401) {
        const refreshed = await get().refreshToken();
        if (refreshed) {
          try {
            const user = await authApi.getProfile();
            set({ user, isAuthenticated: true });
          } catch {
            set({ user: null, isAuthenticated: false });
          }
        }
      }
    }
  },

  initialize: async () => {
    try {
      if (!hasAuthCookie()) return;
      set({ isAuthenticated: true });
      await get().fetchProfile();
    } finally {
      // Always mark as initialized so downstream guards stop showing spinners.
      set({ isInitialized: true });
    }
  },

  clearError: () => set({ error: null }),
}));
