import axios, { AxiosInstance, AxiosResponse } from 'axios';

// Types based on the KMS API
export interface Application {
  app_id: string;
  app_link: string;
  type: string[];
  callback_url: string;
  hmac_key: string;
  token_renewal_duration: number;
  max_token_duration: number;
  owner: {
    type: string;
    name: string;
    owner: string;
  };
  created_at: string;
  updated_at: string;
}

export interface StaticToken {
  id: string;
  app_id: string;
  owner: {
    type: string;
    name: string;
    owner: string;
  };
  type: string;
  created_at: string;
  updated_at: string;
}

export interface CreateApplicationRequest {
  app_id: string;
  app_link: string;
  type: string[];
  callback_url: string;
  token_renewal_duration: string;
  max_token_duration: string;
  owner: {
    type: string;
    name: string;
    owner: string;
  };
}

export interface CreateTokenRequest {
  owner: {
    type: string;
    name: string;
    owner: string;
  };
  permissions: string[];
}

export interface CreateTokenResponse {
  id: string;
  token: string;
  permissions: string[];
  created_at: string;
}

export interface PaginatedResponse<T> {
  data: T[];
  limit: number;
  offset: number;
  count: number;
}

export interface VerifyRequest {
  app_id: string;
  type: string;
  user_id?: string;
  token: string;
  permissions?: string[];
}

export interface VerifyResponse {
  valid: boolean;
  user_id?: string;
  permissions: string[];
  permission_results?: Record<string, boolean>;
  expires_at?: string;
  max_valid_at?: string;
  token_type: string;
  claims?: Record<string, string>;
  error?: string;
}

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

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

    // Add request interceptor to include user email header
    this.api.interceptors.request.use((config) => {
      const user = localStorage.getItem('kms_user');
      if (user) {
        try {
          const userData = JSON.parse(user);
          config.headers['X-User-Email'] = userData.email;
        } catch (error) {
          console.error('Error parsing user data:', error);
        }
      }
      return config;
    });

    // Add response interceptor for error handling
    this.api.interceptors.response.use(
      (response) => response,
      (error) => {
        console.error('API Error:', error);
        return Promise.reject(error);
      }
    );
  }

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

  async readinessCheck(): Promise<any> {
    const response = await this.api.get('/ready');
    return response.data;
  }

  // Applications
  async getApplications(limit: number = 50, offset: number = 0): Promise<PaginatedResponse<Application>> {
    const response = await this.api.get(`/api/applications?limit=${limit}&offset=${offset}`);
    return response.data;
  }

  async getApplication(appId: string): Promise<Application> {
    const response = await this.api.get(`/api/applications/${appId}`);
    return response.data;
  }

  async createApplication(data: CreateApplicationRequest): Promise<Application> {
    const response = await this.api.post('/api/applications', data);
    return response.data;
  }

  async updateApplication(appId: string, data: Partial<CreateApplicationRequest>): Promise<Application> {
    const response = await this.api.put(`/api/applications/${appId}`, data);
    return response.data;
  }

  async deleteApplication(appId: string): Promise<void> {
    await this.api.delete(`/api/applications/${appId}`);
  }

  // Tokens
  async getTokensForApplication(appId: string, limit: number = 50, offset: number = 0): Promise<PaginatedResponse<StaticToken>> {
    const response = await this.api.get(`/api/applications/${appId}/tokens?limit=${limit}&offset=${offset}`);
    return response.data;
  }

  async createToken(appId: string, data: CreateTokenRequest): Promise<CreateTokenResponse> {
    const response = await this.api.post(`/api/applications/${appId}/tokens`, data);
    return response.data;
  }

  async deleteToken(tokenId: string): Promise<void> {
    await this.api.delete(`/api/tokens/${tokenId}`);
  }

  // Token verification
  async verifyToken(data: VerifyRequest): Promise<VerifyResponse> {
    const response = await this.api.post('/api/verify', data);
    return response.data;
  }

  // Authentication
  async login(appId: string, permissions: string[], redirectUri?: string): Promise<any> {
    const response = await this.api.post('/api/login', {
      app_id: appId,
      permissions,
      redirect_uri: redirectUri,
    });
    return response.data;
  }

  async renewToken(appId: string, userId: string, token: string): Promise<any> {
    const response = await this.api.post('/api/renew', {
      app_id: appId,
      user_id: userId,
      token,
    });
    return response.data;
  }
}

export const apiService = new ApiService();
