import { create } from 'zustand';
import { toast } from 'react-toastify';
import authService, { 
  LoginCredentials, 
  RegisterData,
  ForgotPasswordData,
  ResetPasswordData
} from '../services/api/authService';

interface UserInfo {
  id: number;
  name: string;
  email: string;
  phone?: string;
  avatar?: string;
  role: string;
  createdAt?: string;
}

interface AuthState {
  
  token: string | null;
  userInfo: UserInfo | null;
  isAuthenticated: boolean;
  isLoading: boolean;
  error: string | null;
  requiresMFA: boolean;
  mfaUserId: number | null;
  pendingCredentials: LoginCredentials | null;

  
  login: (credentials: LoginCredentials) => Promise<void>;
  verifyMFA: (mfaToken: string) => Promise<void>;
  register: (data: RegisterData) => Promise<void>;
  logout: () => Promise<void>;
  setUser: (user: UserInfo) => void;
  refreshAuthToken: () => Promise<void>;
  forgotPassword: (
    data: ForgotPasswordData
  ) => Promise<void>;
  resetPassword: (
    data: ResetPasswordData
  ) => Promise<void>;
  initializeAuth: () => void;
  clearError: () => void;
  clearMFA: () => void;
}

const useAuthStore = create<AuthState>((set, get) => ({
  
  token: localStorage.getItem('token') || null,
  userInfo: localStorage.getItem('userInfo')
    ? JSON.parse(localStorage.getItem('userInfo')!)
    : null,
  isAuthenticated: !!localStorage.getItem('token'),
  isLoading: false,
  error: null,
  requiresMFA: false,
  mfaUserId: null,
  pendingCredentials: null,

  
  login: async (credentials: LoginCredentials) => {
    set({ isLoading: true, error: null });
    try {
      const response = await authService.login(credentials);

      
      if (response.requires_mfa) {
        set({
          isLoading: false,
          requiresMFA: true,
          mfaUserId: response.user_id || null,
          pendingCredentials: credentials,
          error: null,
        });
        return; 
      }

      
      if (response.success || response.status === 'success') {
        const token = response.data?.token;
        const user = response.data?.user ?? null;

        
        if (!token || !user) {
          throw new Error(response.message || 'Login failed.');
        }

        
        localStorage.setItem('token', token);
        localStorage.setItem('userInfo', JSON.stringify(user));

        
        set({
          token,
          userInfo: user,
          isAuthenticated: true,
          isLoading: false,
          error: null,
          requiresMFA: false,
          mfaUserId: null,
          pendingCredentials: null,
        });

        toast.success('Login successful!');
      }
    } catch (error: any) {
      const errorMessage = 
        error.response?.data?.message || 
        'Login failed. Please try again.';
      
      set({ 
        isLoading: false, 
        error: errorMessage,
        isAuthenticated: false,
        requiresMFA: false,
        mfaUserId: null,
        pendingCredentials: null,
      });
      
      toast.error(errorMessage);
      throw error;
    }
  },

  
  verifyMFA: async (mfaToken: string) => {
    const state = get();
    if (!state.pendingCredentials) {
      throw new Error('No pending login credentials');
    }

    set({ isLoading: true, error: null });
    try {
      const credentials = {
        ...state.pendingCredentials,
        mfaToken,
      };

      const response = await authService.login(credentials);

      if (response.success || response.status === 'success') {
        const token = response.data?.token;
        const user = response.data?.user ?? null;

        if (!token || !user) {
          throw new Error(response.message || 'MFA verification failed.');
        }

        
        localStorage.setItem('token', token);
        localStorage.setItem('userInfo', JSON.stringify(user));

        
        set({
          token,
          userInfo: user,
          isAuthenticated: true,
          isLoading: false,
          error: null,
          requiresMFA: false,
          mfaUserId: null,
          pendingCredentials: null,
        });

        toast.success('Login successful!');
      }
    } catch (error: any) {
      const errorMessage = 
        error.response?.data?.message || 
        'MFA verification failed. Please try again.';
      
      set({ 
        isLoading: false, 
        error: errorMessage,
      });
      
      toast.error(errorMessage);
      throw error;
    }
  },

  
  clearMFA: () => {
    set({
      requiresMFA: false,
      mfaUserId: null,
      pendingCredentials: null,
    });
  },

  
  register: async (data: RegisterData) => {
    set({ isLoading: true, error: null });
    try {
      const response = await authService.register(data);
      
  if (response.success || response.status === 'success') {
        set({ isLoading: false, error: null });
        toast.success(
          'Registration successful! Please login.'
        );
      }
    } catch (error: any) {
      const errorMessage = 
        error.response?.data?.message || 
        'Registration failed. Please try again.';
      
      set({ isLoading: false, error: errorMessage });
      toast.error(errorMessage);
      throw error;
    }
  },

  
  logout: async () => {
    set({ isLoading: true });
    try {
      await authService.logout();
    } catch (error) {
      console.error('Logout error:', error);
    } finally {
      
      localStorage.removeItem('token');
      localStorage.removeItem('userInfo');

      
      set({
        token: null,
        userInfo: null,
        isAuthenticated: false,
        isLoading: false,
        error: null,
      });

      toast.info('Logged out');
    }
  },

  
  setUser: (user: UserInfo) => {
    localStorage.setItem('userInfo', JSON.stringify(user));
    set({ userInfo: user });
  },

  
  refreshAuthToken: async () => {
    try {
      const response = await authService.refreshToken();

      if (response.success || response.status === 'success') {
        const token = response.data?.token;

        if (!token) {
          throw new Error(response.message || 'Unable to refresh token');
        }

        localStorage.setItem('token', token);

        set({
          token,
        });
      }
    } catch (error) {
      
      get().logout();
      throw error;
    }
  },

  
  forgotPassword: async (data: ForgotPasswordData) => {
    set({ isLoading: true, error: null });
    try {
      const response = 
        await authService.forgotPassword(data);
      
  if (response.success || response.status === 'success') {
        set({ isLoading: false, error: null });
        toast.success(
          response.message || 
          'Please check your email to reset password.'
        );
      }
    } catch (error: any) {
      const errorMessage = 
        error.response?.data?.message || 
        'An error occurred. Please try again.';
      
      set({ isLoading: false, error: errorMessage });
      toast.error(errorMessage);
      throw error;
    }
  },

  
  resetPassword: async (data: ResetPasswordData) => {
    set({ isLoading: true, error: null });
    try {
      const response = 
        await authService.resetPassword(data);
      
  if (response.success || response.status === 'success') {
        set({ isLoading: false, error: null });
        toast.success(
          response.message || 
          'Password reset successful!'
        );
      }
    } catch (error: any) {
      const errorMessage = 
        error.response?.data?.message || 
        'Password reset failed. ' +
        'Please try again.';
      
      set({ isLoading: false, error: errorMessage });
      toast.error(errorMessage);
      throw error;
    }
  },

  
  initializeAuth: () => {
    const token = localStorage.getItem('token');
    const userInfo = localStorage.getItem('userInfo');

    if (token && userInfo) {
      set({
        token,
        userInfo: JSON.parse(userInfo),
        isAuthenticated: true,
      });
    }
  },

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

export default useAuthStore;
