/**
 * CodeREADr API Client
 * https://secure.codereadr.com/apidocs/README.md
 */

const API_KEY = '3bcb2250e2c9cf4adf4e807f912f907e';
const API_BASE_URL = 'https://secure.codereadr.com/api/';

export interface CodereadrUser {
  id: string;
  username: string;
  email: string;
  status: 'active' | 'inactive';
}

export interface CodereadrDatabase {
  id: string;
  name: string;
  status: 'active' | 'inactive';
  records_count: number;
}

export interface CodereadrService {
  id: string;
  name: string;
  database_id: string;
  user_id: string;
  status: 'active' | 'inactive';
  created_at: string;
}

export interface CodereadrScan {
  id: string;
  service_id: string;
  user_id: string;
  value: string;
  timestamp: string;
  response: string;
  device_id: string;
  location?: {
    latitude: number;
    longitude: number;
  };
}

export interface CodereadrScanResponse {
  valid: boolean;
  message: string;
  response_id: string;
  scan_id: string;
}

export interface CodereadrExportTemplate {
  id: string;
  name: string;
  format: 'csv' | 'xml' | 'json';
}

class CodereadrApi {
  private apiKey: string;
  private baseUrl: string;

  constructor(apiKey: string = API_KEY) {
    this.apiKey = apiKey;
    this.baseUrl = API_BASE_URL;
  }

  private async makeRequest(endpoint: string, method: 'GET' | 'POST' = 'GET', data?: any): Promise<any> {
    const url = `${this.baseUrl}${endpoint}`;
    const params = new URLSearchParams();
    
    // Add API key to all requests
    params.append('api_key', this.apiKey);
    
    // Add data for POST requests
    if (data) {
      Object.keys(data).forEach(key => {
        if (data[key] !== undefined && data[key] !== null) {
          params.append(key, data[key].toString());
        }
      });
    }

    const options: RequestInit = {
      method,
      headers: {
        'Content-Type': 'application/x-www-form-urlencoded',
        'User-Agent': 'BCT-WhiteLabel/1.0'
      }
    };

    if (method === 'POST') {
      options.body = params;
    } else {
      // GET request - append params to URL
      const finalUrl = `${url}?${params.toString()}`;
      const response = await fetch(finalUrl, options);
      return this.handleResponse(response);
    }

    const response = await fetch(url, options);
    return this.handleResponse(response);
  }

  private async handleResponse(response: Response): Promise<any> {
    if (!response.ok) {
      throw new Error(`API Error: ${response.status} ${response.statusText}`);
    }

    const text = await response.text();
    
    try {
      return JSON.parse(text);
    } catch (error) {
      // Some endpoints return CSV or plain text
      return text;
    }
  }

  // Users API
  async createUser(username: string, email: string, password: string): Promise<CodereadrUser> {
    const response = await this.makeRequest('users/create', 'POST', {
      username,
      email,
      password
    });
    return response;
  }

  async getUsers(): Promise<CodereadrUser[]> {
    const response = await this.makeRequest('users');
    return response;
  }

  async getUserById(userId: string): Promise<CodereadrUser> {
    const response = await this.makeRequest(`users/${userId}`);
    return response;
  }

  async updateUser(userId: string, data: Partial<CodereadrUser>): Promise<CodereadrUser> {
    const response = await this.makeRequest(`users/${userId}/update`, 'POST', data);
    return response;
  }

  async deleteUser(userId: string): Promise<boolean> {
    const response = await this.makeRequest(`users/${userId}/delete`, 'POST');
    return response.success;
  }

  // Databases API
  async createDatabase(name: string, description?: string): Promise<CodereadrDatabase> {
    const response = await this.makeRequest('databases/create', 'POST', {
      name,
      description
    });
    return response;
  }

  async getDatabases(): Promise<CodereadrDatabase[]> {
    const response = await this.makeRequest('databases');
    return response;
  }

  async getDatabaseById(databaseId: string): Promise<CodereadrDatabase> {
    const response = await this.makeRequest(`databases/${databaseId}`);
    return response;
  }

  async updateDatabase(databaseId: string, data: Partial<CodereadrDatabase>): Promise<CodereadrDatabase> {
    const response = await this.makeRequest(`databases/${databaseId}/update`, 'POST', data);
    return response;
  }

  async deleteDatabase(databaseId: string): Promise<boolean> {
    const response = await this.makeRequest(`databases/${databaseId}/delete`, 'POST');
    return response.success;
  }

  // Database Records API
  async addDatabaseRecord(databaseId: string, value: string, response: string): Promise<any> {
    const result = await this.makeRequest('database/add', 'POST', {
      database_id: databaseId,
      value,
      response
    });
    return result;
  }

  async updateDatabaseRecord(databaseId: string, value: string, response: string): Promise<any> {
    const result = await this.makeRequest('database/update', 'POST', {
      database_id: databaseId,
      value,
      response
    });
    return result;
  }

  async deleteDatabaseRecord(databaseId: string, value: string): Promise<boolean> {
    const response = await this.makeRequest('database/delete', 'POST', {
      database_id: databaseId,
      value
    });
    return response.success;
  }

  // Services API
  async createService(name: string, databaseId: string, userId: string): Promise<CodereadrService> {
    const response = await this.makeRequest('services/create', 'POST', {
      name,
      database_id: databaseId,
      user_id: userId
    });
    return response;
  }

  async getServices(): Promise<CodereadrService[]> {
    const response = await this.makeRequest('services');
    return response;
  }

  async getServiceById(serviceId: string): Promise<CodereadrService> {
    const response = await this.makeRequest(`services/${serviceId}`);
    return response;
  }

  async updateService(serviceId: string, data: Partial<CodereadrService>): Promise<CodereadrService> {
    const response = await this.makeRequest(`services/${serviceId}/update`, 'POST', data);
    return response;
  }

  async deleteService(serviceId: string): Promise<boolean> {
    const response = await this.makeRequest(`services/${serviceId}/delete`, 'POST');
    return response.success;
  }

  // Scans API
  async getScans(serviceId?: string, userId?: string, limit?: number, offset?: number): Promise<CodereadrScan[]> {
    const params: any = {};
    
    if (serviceId) params.service_id = serviceId;
    if (userId) params.user_id = userId;
    if (limit) params.limit = limit;
    if (offset) params.offset = offset;

    const response = await this.makeRequest('scans', 'GET', params);
    return response;
  }

  async getScanById(scanId: string): Promise<CodereadrScan> {
    const response = await this.makeRequest(`scans/${scanId}`);
    return response;
  }

  // Export scans to CSV/XML/JSON
  async exportScans(templateId: string, format: 'csv' | 'xml' | 'json' = 'csv'): Promise<string> {
    const response = await this.makeRequest('scans/export', 'GET', {
      template: templateId,
      return_type: format
    });
    return response;
  }

  // Validate a barcode against a database
  async validateBarcode(databaseId: string, value: string): Promise<any> {
    const response = await this.makeRequest('database/lookup', 'POST', {
      database_id: databaseId,
      value
    });
    return response;
  }

  // Simulate a scan (for testing/integration)
  async simulateScan(serviceId: string, userId: string, value: string): Promise<CodereadrScanResponse> {
    const response = await this.makeRequest('scans/simulate', 'POST', {
      service_id: serviceId,
      user_id: userId,
      value
    });
    return response;
  }

  // Kiosk mode configuration
  async setKioskMode(serviceId: string, config: any): Promise<any> {
    const response = await this.makeRequest('services/kiosk', 'POST', {
      service_id: serviceId,
      kiosk_mode_config: JSON.stringify(config)
    });
    return response;
  }

  // Get device information
  async getDevices(): Promise<any[]> {
    const response = await this.makeRequest('devices');
    return response;
  }

  // Questions API (for collecting additional data after scans)
  async createQuestion(text: string, type: 'text' | 'number' | 'select' | 'checkbox' | 'date'): Promise<any> {
    const response = await this.makeRequest('questions/create', 'POST', {
      text,
      type
    });
    return response;
  }

  async getQuestions(): Promise<any[]> {
    const response = await this.makeRequest('questions');
    return response;
  }

  async assignQuestionToService(serviceId: string, questionId: string): Promise<any> {
    const response = await this.makeRequest('services/questions/assign', 'POST', {
      service_id: serviceId,
      question_id: questionId
    });
    return response;
  }
}

export default CodereadrApi;
export { CodereadrApi };