import { create } from 'zustand';
import type { User, Quota, TeamInfo } from '../types';
import { authApi } from '../lib/api';

interface AuthState {
  user: User | null;
  accessToken: string | null;
  refreshToken: string | null;
  isAuthenticated: boolean;
  isLoading: boolean;
  quota: Quota | null;
  team: TeamInfo | null;
  teamDisabled: boolean;
  mustChangePassword: boolean;

  login: (username: string, password: string) => Promise<void>;
  logout: () => void;
  refreshAccessToken: () => Promise<void>;
  fetchUserInfo: () => Promise<void>;
  initialize: () => Promise<void>;
  clearMustChangePassword: () => void;
}

export const useAuthStore = create<AuthState>((set, get) => ({
  user: null,
  accessToken: localStorage.getItem('access_token'),
  refreshToken: localStorage.getItem('refresh_token'),
  isAuthenticated: !!localStorage.getItem('access_token'),
  isLoading: true,
  quota: null,
  team: null,
  teamDisabled: false,
  mustChangePassword: false,

  login: async (username, password) => {
    const { data } = await authApi.login(username, password);
    localStorage.setItem('access_token', data.tokens.access);
    localStorage.setItem('refresh_token', data.tokens.refresh);
    set({
      user: data.user,
      accessToken: data.tokens.access,
      refreshToken: data.tokens.refresh,
      isAuthenticated: true,
      mustChangePassword: data.user.must_change_password || false,
    });
    // Fetch quota after login
    await get().fetchUserInfo();
  },

  logout: () => {
    // 先用当前 token 通知后端清除 ActiveSession，再清本地状态
    const token = localStorage.getItem('access_token');
    if (token) {
      fetch('/api/v1/auth/logout', {
        method: 'POST',
        headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' },
      }).catch(() => {});
    }
    localStorage.removeItem('access_token');
    localStorage.removeItem('refresh_token');
    set({
      user: null,
      accessToken: null,
      refreshToken: null,
      isAuthenticated: false,
      quota: null,
      team: null,
      teamDisabled: false,
      mustChangePassword: false,
    });
  },

  refreshAccessToken: async () => {
    const refresh = get().refreshToken;
    if (!refresh) throw new Error('No refresh token');
    const { data } = await authApi.refreshToken(refresh);
    localStorage.setItem('access_token', data.access);
    if (data.refresh) {
      localStorage.setItem('refresh_token', data.refresh);
      set({ accessToken: data.access, refreshToken: data.refresh });
    } else {
      set({ accessToken: data.access });
    }
  },

  fetchUserInfo: async () => {
    const { data } = await authApi.getMe();
    const { quota, team, team_disabled, ...user } = data;
    set({
      user,
      quota,
      team: team || null,
      teamDisabled: team_disabled || false,
      isAuthenticated: true,
      mustChangePassword: user.must_change_password || false,
    });
  },

  initialize: async () => {
    const token = localStorage.getItem('access_token');
    if (token) {
      // Retry up to 3 times for network errors (e.g. request aborted during page refresh)
      for (let attempt = 0; attempt < 3; attempt++) {
        try {
          await get().fetchUserInfo();
          break;
        } catch (err) {
          const status = (err as { response?: { status?: number } })?.response?.status;
          if (status === 401 || status === 403) {
            get().logout();
            break;
          }
          // Network error / aborted — wait briefly and retry
          if (attempt < 2) {
            await new Promise(r => setTimeout(r, 500));
          }
        }
      }
    }
    set({ isLoading: false });
  },

  clearMustChangePassword: () => {
    set({ mustChangePassword: false });
  },
}));
