import axios, { AxiosInstance } from 'axios';

export interface DocumentUpload {
  file: File | Blob | Buffer;
  documentType: string;
  metadata?: Record<string, unknown>;
}

export interface DocumentMetadata {
  id: string;
  documentType: string;
  fileName: string;
  fileSize: number;
  uploadedAt: string;
  status: 'processing' | 'completed' | 'failed';
  metadata?: Record<string, unknown>;
}

export class IntakeClient {
  protected client: AxiosInstance;

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

    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 uploadDocument(upload: DocumentUpload): Promise<DocumentMetadata> {
    const formData = new FormData();
    // FormData.append accepts File, Blob, or string, but Buffer needs to be converted
    const file: File | Blob = upload.file instanceof Buffer 
      ? new Blob([new Uint8Array(upload.file)])
      : (upload.file as File | Blob);
    formData.append('file', file);
    formData.append('documentType', upload.documentType);
    if (upload.metadata) {
      formData.append('metadata', JSON.stringify(upload.metadata));
    }

    const response = await this.client.post<DocumentMetadata>('/api/v1/documents/upload', formData, {
      headers: {
        'Content-Type': 'multipart/form-data',
      },
    });

    return response.data;
  }

  async getDocument(documentId: string): Promise<DocumentMetadata> {
    const response = await this.client.get<DocumentMetadata>(`/api/v1/documents/${documentId}`);
    return response.data;
  }

  async listDocuments(filters?: {
    documentType?: string;
    status?: string;
    page?: number;
    pageSize?: number;
  }): Promise<{ documents: DocumentMetadata[]; total: number }> {
    const response = await this.client.get<{ documents: DocumentMetadata[]; total: number }>(
      '/api/v1/documents',
      { params: filters }
    );
    return response.data;
  }

  async deleteDocument(documentId: string): Promise<void> {
    await this.client.delete(`/api/v1/documents/${documentId}`);
  }
}
