import axios, { AxiosInstance, AxiosResponse } from 'axios';
import {
  User,
  CreateUserRequest,
  UpdateUserRequest,
  ListUsersRequest,
  ListUsersResponse,
  ExistsByEmailResponse,
} from '../types/user';

class UserService {
  private api: AxiosInstance;
  private baseURL: string;

  constructor() {
    this.baseURL = process.env.REACT_APP_USER_API_URL || 'http://localhost:8090';
    
    this.api = axios.create({
      baseURL: this.baseURL,
      timeout: 30000,
      headers: {
        'Content-Type': 'application/json',
      },
    });

    // Add request interceptor for authentication
    this.api.interceptors.request.use((config) => {
      // For development, use header-based authentication
      // In production, this might use JWT tokens or other auth mechanisms
      const userEmail = 'admin@example.com'; // This would come from auth context
      config.headers['X-User-Email'] = userEmail;
      return config;
    });

    // Add response interceptor for error handling
    this.api.interceptors.response.use(
      (response: AxiosResponse) => response,
      (error) => {
        console.error('API Error:', error);
        if (error.response?.data?.error) {
          throw new Error(error.response.data.error);
        }
        throw error;
      }
    );
  }

  async createUser(userData: CreateUserRequest): Promise<User> {
    const response = await this.api.post<User>('/api/users', userData);
    return response.data;
  }

  async getUserById(id: string): Promise<User> {
    const response = await this.api.get<User>(`/api/users/${id}`);
    return response.data;
  }

  async getUserByEmail(email: string): Promise<User> {
    const response = await this.api.get<User>(`/api/users/email/${encodeURIComponent(email)}`);
    return response.data;
  }

  async updateUser(id: string, userData: UpdateUserRequest): Promise<User> {
    const response = await this.api.put<User>(`/api/users/${id}`, userData);
    return response.data;
  }

  async deleteUser(id: string): Promise<void> {
    await this.api.delete(`/api/users/${id}`);
  }

  async listUsers(request: ListUsersRequest = {}): Promise<ListUsersResponse> {
    const params = new URLSearchParams();
    
    if (request.status) params.append('status', request.status);
    if (request.role) params.append('role', request.role);
    if (request.search) params.append('search', request.search);
    if (request.limit) params.append('limit', request.limit.toString());
    if (request.offset) params.append('offset', request.offset.toString());
    if (request.order_by) params.append('order_by', request.order_by);
    if (request.order_dir) params.append('order_dir', request.order_dir);

    const response = await this.api.get<ListUsersResponse>(`/api/users?${params.toString()}`);
    return response.data;
  }

  async existsByEmail(email: string): Promise<ExistsByEmailResponse> {
    const response = await this.api.get<ExistsByEmailResponse>(`/api/users/exists/${encodeURIComponent(email)}`);
    return response.data;
  }

  async health(): Promise<Record<string, any>> {
    const response = await this.api.get<Record<string, any>>('/health');
    return response.data;
  }

  // Utility method to check service availability
  async isServiceAvailable(): Promise<boolean> {
    try {
      await this.health();
      return true;
    } catch (error) {
      console.error('User service is not available:', error);
      return false;
    }
  }
}

export const userService = new UserService();