import { create } from 'zustand';
import { toast } from 'react-toastify';
import authService, { 
  LoginCredentials, 
  RegisterData,
  ForgotPasswordData,
  ResetPasswordData
} from '../features/auth/services/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: () => Promise<void>;
  clearError: () => void;
  clearMFA: () => void;
}

const useAuthStore = create<AuthState>((set, get) => ({
  
  // SECURITY: Tokens are stored in httpOnly cookies, not localStorage
  // We only store minimal userInfo in localStorage for UI purposes
  // Note: localStorage is accessible to XSS attacks, so we minimize sensitive data
  token: null,  // Token is in httpOnly cookie, not accessible from JS
  userInfo: (() => {
    try {
      const stored = localStorage.getItem('userInfo');
      return stored ? JSON.parse(stored) : null;
    } catch {
      // Invalid JSON, clear it
      localStorage.removeItem('userInfo');
      return null;
    }
  })(),
  // SECURITY: Don't rely solely on localStorage for auth state
  // initializeAuth() will validate with backend
  isAuthenticated: false,  // Will be set after validation
  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 user = response.data?.user ?? null;

        // Token is now in httpOnly cookie, not in response
        if (!user) {
          throw new Error(response.message || 'Login failed.');
        }

        // SECURITY: Store minimal userInfo in localStorage (token is in httpOnly cookie)
        // Only store non-sensitive UI data - sensitive data should come from backend
        const minimalUserInfo = {
          id: user.id,
          name: user.name,
          email: user.email,
          role: user.role,
          avatar: user.avatar,
        };
        localStorage.setItem('userInfo', JSON.stringify(minimalUserInfo));

        
        set({
          token: null,  // Token is in httpOnly cookie, not accessible from JS
          userInfo: user,
          isAuthenticated: true,
          isLoading: false,
          error: null,
          requiresMFA: false,
          mfaUserId: null,
          pendingCredentials: null,
        });

        toast.success('Login successful!');
      }
    } catch (error: unknown) {
      const errorMessage = 
        (error as { response?: { data?: { message?: string } } })?.response?.data?.message || 
        (error instanceof Error ? error.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 user = response.data?.user ?? null;

        // Token is now in httpOnly cookie, not in response
        if (!user) {
          throw new Error(response.message || 'MFA verification failed.');
        }

        // SECURITY: Store minimal userInfo in localStorage (token is in httpOnly cookie)
        const minimalUserInfo = {
          id: user.id,
          name: user.name,
          email: user.email,
          role: user.role,
          avatar: user.avatar,
        };
        localStorage.setItem('userInfo', JSON.stringify(minimalUserInfo));

        
        set({
          token: null,  // Token is in httpOnly cookie, not accessible from JS
          userInfo: user,
          isAuthenticated: true,
          isLoading: false,
          error: null,
          requiresMFA: false,
          mfaUserId: null,
          pendingCredentials: null,
        });

        toast.success('Login successful!');
      }
    } catch (error: unknown) {
      const errorMessage = 
        (error as { response?: { data?: { message?: string } } })?.response?.data?.message || 
        (error instanceof Error ? error.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: unknown) {
      const errorMessage = 
        (error as { response?: { data?: { message?: string } } })?.response?.data?.message || 
        (error instanceof Error ? error.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) {
      // SECURITY: Don't log sensitive error details
      if (import.meta.env.DEV) {
        console.error('Logout error:', error);
      }
    } finally {
      // Clear userInfo from localStorage
      // Tokens in httpOnly cookies are deleted by backend on logout
      localStorage.removeItem('userInfo');
      // Also clear any other potential auth-related items
      localStorage.removeItem('refreshToken');
      localStorage.removeItem('authToken');
      localStorage.removeItem('user');
      
      // Clear sessionStorage as well for extra security
      sessionStorage.clear();
      
      set({
        token: null,
        userInfo: null,
        isAuthenticated: false,
        isLoading: false,
        error: null,
        requiresMFA: false,
        mfaUserId: null,
        pendingCredentials: null,
      });

      toast.info('Logged out');
      
      // Always redirect to homepage after logout
      window.location.href = '/';
    }
  },

  
  setUser: (user: UserInfo) => {
    // SECURITY: Store minimal userInfo
    const minimalUserInfo = {
      id: user.id,
      name: user.name,
      email: user.email,
      role: user.role,
      avatar: user.avatar,
    };
    localStorage.setItem('userInfo', JSON.stringify(minimalUserInfo));
    set({ userInfo: minimalUserInfo });
  },

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

      if (response.success || response.status === 'success') {
        // Token is now in httpOnly cookie, not in response
        // Backend sets the new token in cookie automatically
        // We just need to update userInfo if it's in the response
        const user = response.data?.user;
        if (user) {
          // SECURITY: Store minimal userInfo
          const minimalUserInfo = {
            id: user.id,
            name: user.name,
            email: user.email,
            role: user.role,
            avatar: user.avatar,
          };
          localStorage.setItem('userInfo', JSON.stringify(minimalUserInfo));
          set({
            userInfo: minimalUserInfo,
          });
        }
      }
    } 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: unknown) {
      const errorMessage = 
        (error as { response?: { data?: { message?: string } } })?.response?.data?.message || 
        (error instanceof Error ? error.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: unknown) {
      const errorMessage = 
        (error as { response?: { data?: { message?: string } } })?.response?.data?.message || 
        (error instanceof Error ? error.message : 'Password reset failed. Please try again.');
      
      set({ isLoading: false, error: errorMessage });
      toast.error(errorMessage);
      throw error;
    }
  },

  
  initializeAuth: async () => {
    // Tokens are in httpOnly cookies, we can't check them from JS
    // Validate authentication by checking profile endpoint
    // This ensures cookies are valid and user is actually authenticated
    const userInfo = localStorage.getItem('userInfo');

    if (userInfo) {
      try {
        // Validate authentication by fetching profile
        // This will fail if cookies are invalid/expired
        const profile = await authService.getProfile();
        if (profile.data?.user) {
          // SECURITY: Update userInfo with minimal data from server
          const user = profile.data.user;
          const minimalUserInfo = {
            id: user.id,
            name: user.name,
            email: user.email,
            role: user.role,
            avatar: user.avatar,
          };
          localStorage.setItem('userInfo', JSON.stringify(minimalUserInfo));
          set({
            token: null,  // Token is in httpOnly cookie, not accessible
            userInfo: minimalUserInfo,
            isAuthenticated: true,
          });
        } else {
          // Invalid response, clear auth state
          localStorage.removeItem('userInfo');
          set({
            token: null,
            userInfo: null,
            isAuthenticated: false,
          });
        }
      } catch (error) {
        // Authentication failed - cookies invalid or expired
        // Clear auth state
        localStorage.removeItem('userInfo');
        set({
          token: null,
          userInfo: null,
          isAuthenticated: false,
        });
      }
    } else {
      // No userInfo in localStorage, user is not authenticated
      set({
        token: null,
        userInfo: null,
        isAuthenticated: false,
      });
    }
  },

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

export default useAuthStore;
