import axios, { AxiosInstance } from 'axios';
import type { eResidencyApplication, ApplicationStatus } from '@the-order/schemas';

export interface SubmitApplicationRequest {
  email: string;
  givenName: string;
  familyName: string;
  dateOfBirth?: string;
  nationality?: string;
  phone?: string;
  address?: {
    street?: string;
    city?: string;
    region?: string;
    postalCode?: string;
    country?: string;
  };
  identityDocument?: {
    type: 'passport' | 'national_id' | 'drivers_license';
    number: string;
    issuingCountry: string;
    expiryDate?: string;
    documentHash?: string;
  };
  selfieLiveness?: {
    imageHash: string;
    livenessScore: number;
    verifiedAt: string;
  };
}

export interface AdjudicateRequest {
  decision: 'approve' | 'reject';
  reason?: string;
  notes?: string;
}

export class EResidencyClient {
  protected client: AxiosInstance;

  constructor(baseURL?: string) {
    const apiBaseURL =
      baseURL ||
      (typeof window !== 'undefined'
        ? process.env.NEXT_PUBLIC_ERESIDENCY_SERVICE_URL || 'http://localhost:4001'
        : 'http://localhost:4001');

    this.client = axios.create({
      baseURL: apiBaseURL,
      headers: {
        'Content-Type': 'application/json',
      },
    });

    // Set up request interceptor for authentication
    this.client.interceptors.request.use(
      (config) => {
        const token = this.getAuthToken();
        if (token) {
          config.headers.Authorization = `Bearer ${token}`;
        }
        return config;
      },
      (error) => Promise.reject(error)
    );
  }

  private getAuthToken(): string | null {
    if (typeof window === 'undefined') return null;
    return localStorage.getItem('auth_token');
  }

  setAuthToken(token: string): void {
    if (typeof window !== 'undefined') {
      localStorage.setItem('auth_token', token);
    }
  }

  clearAuthToken(): void {
    if (typeof window !== 'undefined') {
      localStorage.removeItem('auth_token');
    }
  }

  async submitApplication(request: SubmitApplicationRequest): Promise<eResidencyApplication> {
    const response = await this.client.post<eResidencyApplication>('/applications', request);
    return response.data;
  }

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

  async getReviewQueue(filters?: {
    riskBand?: 'low' | 'medium' | 'high';
    status?: ApplicationStatus;
    assignedTo?: string;
    limit?: number;
    offset?: number;
  }): Promise<{
    applications: eResidencyApplication[];
    total: number;
  }> {
    const params = new URLSearchParams();
    if (filters?.riskBand) params.append('riskBand', filters.riskBand);
    if (filters?.status) params.append('status', filters.status);
    if (filters?.assignedTo) params.append('assignedTo', filters.assignedTo);
    if (filters?.limit) params.append('limit', filters.limit.toString());
    if (filters?.offset) params.append('offset', filters.offset.toString());
    const response = await this.client.get<{
      applications: eResidencyApplication[];
      total: number;
    }>(`/review/queue?${params.toString()}`);
    return response.data;
  }

  async getApplicationForReview(id: string): Promise<eResidencyApplication> {
    const response = await this.client.get<eResidencyApplication>(`/review/applications/${id}`);
    return response.data;
  }

  async adjudicateApplication(id: string, request: AdjudicateRequest): Promise<eResidencyApplication> {
    const response = await this.client.post<eResidencyApplication>(`/review/applications/${id}/adjudicate`, request);
    return response.data;
  }

  async revokeCredential(residentNumber: string, reason: string): Promise<void> {
    await this.client.post('/applications/revoke', { residentNumber, reason });
  }

  async getStatus(): Promise<Array<{
    residentNumber: string;
    status: string;
    issuedAt?: string;
    revokedAt?: string;
  }>> {
    const response = await this.client.get<Array<{
      residentNumber: string;
      status: string;
      issuedAt?: string;
      revokedAt?: string;
    }>>('/status');
    return response.data;
  }
}

