import { create } from 'zustand';
import { persist } from 'zustand/middleware';
import { api, registerAuthCallbacks } from '@/lib/api';

interface User {
  id: string;
  email: string;
  name: string;
  role: string;
}

interface AuthState {
  user: User | null;
  accessToken: string | null;
  refreshToken: string | null;
  isAuthenticated: boolean;
  isLoading: boolean;
  error: string | null;
}

interface AuthActions {
  login: (email: string, password: string) => Promise<void>;
  logout: () => Promise<void>;
  refresh: () => Promise<void>;
  hydrate: () => Promise<void>;
  clearAuth: () => void;
  setTokens: (accessToken: string, refreshToken: string) => void;
}

export const useAuthStore = create<AuthState & AuthActions>()(
  persist(
    (set, get) => ({
      user: null,
      accessToken: null,
      refreshToken: null,
      isAuthenticated: false,
      isLoading: true,
      error: null,

      login: async (email: string, password: string) => {
        set({ error: null, isLoading: true });
        try {
          const { data } = await api.post('/auth/login', { email, password });
          set({
            user: data.user,
            accessToken: data.accessToken || null,
            refreshToken: data.refreshToken || null,
            isAuthenticated: true,
            isLoading: false,
          });
        } catch (err: unknown) {
          const resp = (err as { response?: { data?: { error?: { message?: string } } } })
            ?.response?.data?.error;
          set({ error: resp?.message || 'Login failed', isLoading: false });
          throw err;
        }
      },

      logout: async () => {
        const { refreshToken } = get();
        try {
          if (refreshToken) {
            await api.post('/auth/logout', { refreshToken });
          }
        } catch {
          // Ignore logout errors
        }
        get().clearAuth();
      },

      refresh: async () => {
        const { refreshToken } = get();
        if (!refreshToken) {
          get().clearAuth();
          return;
        }
        try {
          const { data } = await api.post('/auth/refresh', { refreshToken });
          set({
            user: data.user,
            accessToken: data.accessToken || null,
            refreshToken: data.refreshToken || null,
            isAuthenticated: true,
          });
        } catch {
          get().clearAuth();
        }
      },

      hydrate: async () => {
        const { accessToken } = get();
        if (!accessToken) {
          set({ isLoading: false });
          return;
        }
        try {
          const { data } = await api.get('/auth/me');
          set({ user: data.user, isAuthenticated: true, isLoading: false });
        } catch {
          get().clearAuth();
        }
      },

      clearAuth: () => {
        set({
          user: null,
          accessToken: null,
          refreshToken: null,
          isAuthenticated: false,
          isLoading: false,
          error: null,
        });
      },

      setTokens: (accessToken: string, refreshToken: string) => {
        set({ accessToken, refreshToken });
      },
    }),
    {
      name: 'ccp-auth',
      partialize: (state) => ({
        accessToken: state.accessToken,
        refreshToken: state.refreshToken,
      }),
    }
  )
);

// Register callbacks to break circular dependency
registerAuthCallbacks({
  getTokens: () => {
    const state = useAuthStore.getState();
    return { accessToken: state.accessToken, refreshToken: state.refreshToken };
  },
  onTokenRefresh: (accessToken, refreshToken) => {
    useAuthStore.getState().setTokens(accessToken, refreshToken);
  },
  onAuthFailure: () => {
    useAuthStore.getState().clearAuth();
    window.location.href = '/login';
  },
});
