import { api } from '@/lib/api';

export interface LoginRequest {
  email: string;
  password: string;
}

export interface RegisterRequest {
  firstName: string;
  lastName: string;
  email: string;
  password: string;
  password_confirmation: string;
  phone?: string;
}

export interface ForgotPasswordRequest {
  email: string;
}

export interface ResetPasswordRequest {
  token: string;
  email: string;
  password: string;
  password_confirmation: string;
}

export interface AuthResponse {
  token: string;
  user: {
    id: number;
    name: string;
    email: string;
    phone?: string;
    email_verified_at?: string;
    created_at: string;
    updated_at: string;
  };
}

export interface ApiError {
  message: string;
  errors?: Record<string, string[]>;
}

class AuthService {
  private readonly TOKEN_KEY = 'auth_token';
  private readonly USER_KEY = 'auth_user';

  /**
   * Login user with email and password
   */
  async login(credentials: LoginRequest): Promise<AuthResponse> {
    try {
      const response = await api.post<AuthResponse>('/login', credentials);
      
      if (response.token) {
        this.setToken(response.token);
        this.setUser(response.user);
      }
      
      return response;
    } catch (error) {
      console.error('Login error:', error);
      throw this.handleAuthError(error);
    }
  }

  /**
   * Register new user
   */
  async register(userData: RegisterRequest): Promise<AuthResponse> {
    try {
      // Transform the data to match Laravel expectations
      const requestData = {
        name: `${userData.firstName} ${userData.lastName}`,
        email: userData.email,
        password: userData.password,
        password_confirmation: userData.password_confirmation,
        phone: userData.phone,
      };

      const response = await api.post<AuthResponse>('/register', requestData);
      
      if (response.token) {
        this.setToken(response.token);
        this.setUser(response.user);
      }
      
      return response;
    } catch (error) {
      console.error('Registration error:', error);
      throw this.handleAuthError(error);
    }
  }

  /**
   * Logout user
   */
  async logout(): Promise<void> {
    try {
      // Call API to invalidate token
      await api.post('/logout');
    } catch (error) {
      console.error('Logout API error:', error);
      // Continue with local logout even if API fails
    } finally {
      this.clearAuth();
    }
  }

  /**
   * Request password reset link
   */
  async forgotPassword(data: ForgotPasswordRequest): Promise<{ success: boolean; message: string }> {
    try {
      const response = await api.post<{ success: boolean; status: string }>('/forgot-password', data);
      return {
        success: response.success,
        message: response.status || 'Password reset link sent to your email'
      };
    } catch (error) {
      console.error('Forgot password error:', error);
      throw this.handleAuthError(error);
    }
  }

  /**
   * Reset password with token
   */
  async resetPassword(data: ResetPasswordRequest): Promise<{ success: boolean; message: string }> {
    try {
      const response = await api.post<{ success: boolean; status: string }>('/reset-password', data);
      return {
        success: response.success,
        message: response.status || 'Password has been reset successfully'
      };
    } catch (error) {
      console.error('Reset password error:', error);
      throw this.handleAuthError(error);
    }
  }

  /**
   * Get stored authentication token
   */
  getToken(): string | null {
    if (typeof window === 'undefined') return null;
    return localStorage.getItem(this.TOKEN_KEY);
  }

  /**
   * Get stored user data
   */
  getUser(): AuthResponse['user'] | null {
    if (typeof window === 'undefined') return null;
    const userData = localStorage.getItem(this.USER_KEY);
    return userData ? JSON.parse(userData) : null;
  }

  /**
   * Check if user is authenticated
   */
  isAuthenticated(): boolean {
    return this.getToken() !== null;
  }

  /**
   * Store authentication token
   */
  private setToken(token: string): void {
    if (typeof window === 'undefined') return;
    localStorage.setItem(this.TOKEN_KEY, token);
  }

  /**
   * Store user data
   */
  private setUser(user: AuthResponse['user']): void {
    if (typeof window === 'undefined') return;
    localStorage.setItem(this.USER_KEY, JSON.stringify(user));
  }

  /**
   * Clear all authentication data
   */
  private clearAuth(): void {
    if (typeof window === 'undefined') return;
    localStorage.removeItem(this.TOKEN_KEY);
    localStorage.removeItem(this.USER_KEY);
  }

  /**
   * Handle authentication errors
   */
  private handleAuthError(error: unknown): Error {
    interface ErrorResponse {
      response?: {
        status?: number;
        data?: {
          errors?: Record<string, string[]>;
          message?: string;
        };
      };
      message?: string;
    }

    const err = error as ErrorResponse;

    if (err?.response?.status === 422 && err?.response?.data?.errors) {
      // Laravel validation errors
      const validationErrors = err.response.data.errors;
      const firstError = Object.values(validationErrors)[0];
      return new Error(firstError?.[0] || 'Validation failed');
    }
    
    if (err?.response?.status === 401) {
      return new Error('Invalid credentials');
    }
    
    if (err?.response?.data?.message) {
      return new Error(err.response.data.message);
    }
    
    if (err?.message) {
      return new Error(err.message);
    }
    
    return new Error('An unexpected error occurred');
  }
}

export const authService = new AuthService();