import api, { ApiResponse, ApiErrorResponse } from './api';
import { AxiosError } from 'axios';

// Types
export interface RegisterRequest {
  firstName: string;
  lastName?: string;
  email: string;
  password: string;
  role: 'USER' | 'AGENT';
  agentTypeId?: string;
}

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

export interface AuthUser {
  id: string;
  email: string;
  role: string;
  firstName?: string;
  lastName?: string;
  avatar?: string;
}

export interface AuthResponse {
  user: AuthUser;
  accessToken: string;
  refreshToken: string;
}

export interface ForgotPasswordRequest {
  email: string;
}

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

export interface VerifyEmailRequest {
  token: string;
}

export interface ChangeEmailRequest {
  newEmail: string;
  password: string;
}

export interface MessageResponse {
  message: string;
}

// Auth Service
class AuthService {
  private basePath = '/auth';

  async register(data: RegisterRequest): Promise<ApiResponse<AuthResponse>> {
    const response = await api.post<ApiResponse<AuthResponse>>(
      `${this.basePath}/register`,
      data
    );
    return response.data;
  }

  async login(data: LoginRequest): Promise<ApiResponse<AuthResponse>> {
    const response = await api.post<ApiResponse<AuthResponse>>(
      `${this.basePath}/login`,
      data
    );
    return response.data;
  }

  async forgotPassword(data: ForgotPasswordRequest): Promise<ApiResponse<MessageResponse>> {
    const response = await api.post<ApiResponse<MessageResponse>>(
      `${this.basePath}/forgot-password`,
      data
    );
    return response.data;
  }

  async resetPassword(data: ResetPasswordRequest): Promise<ApiResponse<MessageResponse>> {
    const response = await api.post<ApiResponse<MessageResponse>>(
      `${this.basePath}/reset-password`,
      data
    );
    return response.data;
  }

  async verifyEmail(data: VerifyEmailRequest): Promise<ApiResponse<MessageResponse>> {
    const response = await api.post<ApiResponse<MessageResponse>>(
      `${this.basePath}/verify-email`,
      data
    );
    return response.data;
  }

  async resendVerification(): Promise<ApiResponse<MessageResponse>> {
    const response = await api.post<ApiResponse<MessageResponse>>(
      `${this.basePath}/resend-verification`
    );
    return response.data;
  }

  async requestEmailChange(data: ChangeEmailRequest): Promise<ApiResponse<MessageResponse>> {
    const response = await api.post<ApiResponse<MessageResponse>>(
      `${this.basePath}/change-email`,
      data
    );
    return response.data;
  }

  async getCurrentUser(): Promise<ApiResponse<AuthUser>> {
    const response = await api.get<ApiResponse<AuthUser>>(`${this.basePath}/me`);
    return response.data;
  }

  async refreshToken(refreshToken: string): Promise<ApiResponse<{ accessToken: string; refreshToken: string }>> {
    const response = await api.post<ApiResponse<{ accessToken: string; refreshToken: string }>>(
      `${this.basePath}/refresh`,
      { refreshToken }
    );
    return response.data;
  }

  async logout(): Promise<ApiResponse<MessageResponse>> {
    const response = await api.post<ApiResponse<MessageResponse>>(`${this.basePath}/logout`);
    return response.data;
  }

  // Helper to extract error message from API error
  static getErrorMessage(error: unknown): string {
    if (error instanceof AxiosError) {
      const apiError = error.response?.data as ApiErrorResponse;
      if (apiError?.message) {
        return Array.isArray(apiError.message)
          ? apiError.message.join(', ')
          : apiError.message;
      }
    }
    if (error instanceof Error) {
      return error.message;
    }
    return 'An unexpected error occurred';
  }

  // Helper to extract field errors
  static getFieldErrors(error: unknown): Array<{ field: string; errors: string[] }> {
    if (error instanceof AxiosError) {
      const apiError = error.response?.data as ApiErrorResponse;
      return apiError?.errors || [];
    }
    return [];
  }
}

export const authService = new AuthService();
export { AuthService };
