// ================================================================
// frontend/src/api/services/pos.ts
// ================================================================
/**
 * POS Service - Complete backend alignment
 *
 * Backend API structure (3-tier architecture):
 * - ATOMIC: configurations.py, transactions.py
 * - OPERATIONS: pos_operations.py
 * - ANALYTICS: analytics.py
 *
 * Last Updated: 2025-10-05
 * Status: ✅ Complete - Zero drift with backend
 */

import { apiClient } from '../client';
import type {
  POSConfiguration,
  POSTransaction,
  POSWebhookLog,
  POSSyncLog,
  POSSystemInfo,
  GetPOSConfigurationsRequest,
  GetPOSConfigurationsResponse,
  CreatePOSConfigurationRequest,
  CreatePOSConfigurationResponse,
  GetPOSConfigurationRequest,
  GetPOSConfigurationResponse,
  UpdatePOSConfigurationRequest,
  UpdatePOSConfigurationResponse,
  DeletePOSConfigurationRequest,
  DeletePOSConfigurationResponse,
  TestPOSConnectionRequest,
  TestPOSConnectionResponse,
  GetSupportedPOSSystemsResponse,
  POSSystem,
} from '../types/pos';

export class POSService {
  private readonly basePath = '/pos';

  // ===================================================================
  // ATOMIC: POS Configuration CRUD
  // Backend: services/pos/app/api/configurations.py
  // ===================================================================

  /**
   * Get POS configurations for a tenant
   */
  async getPOSConfigurations(params: GetPOSConfigurationsRequest): Promise<GetPOSConfigurationsResponse> {
    const { tenant_id, pos_system, is_active } = params;
    
    const queryParams = new URLSearchParams();
    if (pos_system) queryParams.append('pos_system', pos_system);
    if (is_active !== undefined) queryParams.append('is_active', is_active.toString());
    
    const url = `/tenants/${tenant_id}${this.basePath}/configurations${queryParams.toString() ? `?${queryParams.toString()}` : ''}`;
    
    return apiClient.get<GetPOSConfigurationsResponse>(url);
  }

  /**
   * Create a new POS configuration
   */
  async createPOSConfiguration(params: CreatePOSConfigurationRequest): Promise<CreatePOSConfigurationResponse> {
    const { tenant_id, ...configData } = params;
    const url = `/tenants/${tenant_id}${this.basePath}/configurations`;
    
    return apiClient.post<CreatePOSConfigurationResponse>(url, configData);
  }

  /**
   * Get a specific POS configuration
   */
  async getPOSConfiguration(params: GetPOSConfigurationRequest): Promise<GetPOSConfigurationResponse> {
    const { tenant_id, config_id } = params;
    const url = `/tenants/${tenant_id}${this.basePath}/configurations/${config_id}`;
    
    return apiClient.get<GetPOSConfigurationResponse>(url);
  }

  /**
   * Update a POS configuration
   */
  async updatePOSConfiguration(params: UpdatePOSConfigurationRequest): Promise<UpdatePOSConfigurationResponse> {
    const { tenant_id, config_id, ...updateData } = params;
    const url = `/tenants/${tenant_id}${this.basePath}/configurations/${config_id}`;
    
    return apiClient.put<UpdatePOSConfigurationResponse>(url, updateData);
  }

  /**
   * Delete a POS configuration
   */
  async deletePOSConfiguration(params: DeletePOSConfigurationRequest): Promise<DeletePOSConfigurationResponse> {
    const { tenant_id, config_id } = params;
    const url = `/tenants/${tenant_id}${this.basePath}/configurations/${config_id}`;
    
    return apiClient.delete<DeletePOSConfigurationResponse>(url);
  }

  /**
   * Test connection to POS system
   */
  async testPOSConnection(params: TestPOSConnectionRequest): Promise<TestPOSConnectionResponse> {
    const { tenant_id, config_id } = params;
    const url = `/tenants/${tenant_id}${this.basePath}/configurations/${config_id}/test-connection`;
    
    return apiClient.post<TestPOSConnectionResponse>(url);
  }

  // ===================================================================
  // OPERATIONS: Supported Systems
  // Backend: services/pos/app/api/pos_operations.py
  // ===================================================================

  /**
   * Get list of supported POS systems
   */
  async getSupportedPOSSystems(): Promise<GetSupportedPOSSystemsResponse> {
    const url = `${this.basePath}/supported-systems`;
    return apiClient.get<GetSupportedPOSSystemsResponse>(url);
  }

  // ===================================================================
  // ATOMIC: Transactions
  // Backend: services/pos/app/api/transactions.py
  // ===================================================================

  /**
   * Get POS transactions for a tenant (Updated with backend structure)
   */
  async getPOSTransactions(params: {
    tenant_id: string;
    pos_system?: string;
    start_date?: string;
    end_date?: string;
    status?: string;
    is_synced?: boolean;
    limit?: number;
    offset?: number;
  }): Promise<{
    transactions: POSTransaction[];
    total: number;
    has_more: boolean;
    summary: {
      total_amount: number;
      transaction_count: number;
      sync_status: {
        synced: number;
        pending: number;
        failed: number;
      };
    };
  }> {
    const { tenant_id, ...queryParams } = params;
    const searchParams = new URLSearchParams();
    
    Object.entries(queryParams).forEach(([key, value]) => {
      if (value !== undefined) {
        searchParams.append(key, value.toString());
      }
    });
    
    const url = `/tenants/${tenant_id}${this.basePath}/transactions${searchParams.toString() ? `?${searchParams.toString()}` : ''}`;
    
    return apiClient.get(url);
  }

  /**
   * Sync a single transaction to sales service
   */
  async syncSingleTransaction(params: {
    tenant_id: string;
    transaction_id: string;
    force?: boolean;
  }): Promise<{
    message: string;
    transaction_id: string;
    sync_status: string;
    sales_record_id: string;
  }> {
    const { tenant_id, transaction_id, force } = params;
    const queryParams = new URLSearchParams();
    if (force) queryParams.append('force', force.toString());
    
    const url = `/tenants/${tenant_id}${this.basePath}/transactions/${transaction_id}/sync${queryParams.toString() ? `?${queryParams.toString()}` : ''}`;
    
    return apiClient.post(url);
  }

  /**
   * Get sync performance analytics
   */
  async getSyncAnalytics(params: {
    tenant_id: string;
    days?: number;
  }): Promise<{
    period_days: number;
    total_syncs: number;
    successful_syncs: number;
    failed_syncs: number;
    success_rate: number;
    average_duration_minutes: number;
    total_transactions_synced: number;
    total_revenue_synced: number;
    sync_frequency: {
      daily_average: number;
      peak_day?: string;
      peak_count: number;
    };
    error_analysis: {
      common_errors: any[];
      error_trends: any[];
    };
  }> {
    const { tenant_id, days } = params;
    const queryParams = new URLSearchParams();
    if (days) queryParams.append('days', days.toString());
    
    const url = `/tenants/${tenant_id}${this.basePath}/analytics/sync-performance${queryParams.toString() ? `?${queryParams.toString()}` : ''}`;
    
    return apiClient.get(url);
  }

  /**
   * Resync failed transactions
   */
  async resyncFailedTransactions(params: {
    tenant_id: string;
    days_back?: number;
  }): Promise<{
    message: string;
    job_id: string;
    scope: string;
    estimated_transactions: number;
  }> {
    const { tenant_id, days_back } = params;
    const queryParams = new URLSearchParams();
    if (days_back) queryParams.append('days_back', days_back.toString());
    
    const url = `/tenants/${tenant_id}${this.basePath}/data/resync${queryParams.toString() ? `?${queryParams.toString()}` : ''}`;
    
    return apiClient.post(url);
  }

  /**
   * Get a specific POS transaction
   */
  async getPOSTransaction(params: {
    tenant_id: string;
    transaction_id: string;
  }): Promise<POSTransaction> {
    const { tenant_id, transaction_id } = params;
    const url = `/tenants/${tenant_id}${this.basePath}/transactions/${transaction_id}`;

    return apiClient.get(url);
  }

  /**
   * Get POS transactions dashboard summary
   */
  async getPOSTransactionsDashboard(params: {
    tenant_id: string;
  }): Promise<{
    total_transactions_today: number;
    total_transactions_this_week: number;
    total_transactions_this_month: number;
    revenue_today: number;
    revenue_this_week: number;
    revenue_this_month: number;
    average_transaction_value: number;
    status_breakdown: Record<string, number>;
    payment_method_breakdown: Record<string, number>;
    sync_status: {
      synced: number;
      pending: number;
      failed: number;
      last_sync_at?: string;
    };
  }> {
    const { tenant_id } = params;
    const url = `/tenants/${tenant_id}${this.basePath}/operations/transactions-dashboard`;

    return apiClient.get(url);
  }

  // ===================================================================
  // OPERATIONS: Sync Operations
  // Backend: services/pos/app/api/pos_operations.py
  // ===================================================================

  /**
   * Trigger manual sync for a POS configuration
   */
  async triggerManualSync(params: {
    tenant_id: string;
    config_id: string;
    sync_type?: 'full' | 'incremental';
    data_types?: string[];
    from_date?: string;
    to_date?: string;
  }): Promise<{
    sync_id: string;
    message: string;
    status: string;
    sync_type: string;
    data_types: string[];
    estimated_duration: string;
  }> {
    const { tenant_id, config_id, ...syncData } = params;
    const url = `/tenants/${tenant_id}${this.basePath}/configurations/${config_id}/sync`;
    
    return apiClient.post(url, syncData);
  }

  /**
   * Get sync status for a POS configuration
   */
  async getSyncStatus(params: {
    tenant_id: string;
    config_id: string;
    limit?: number;
  }): Promise<{
    current_sync: any;
    last_successful_sync: any;
    recent_syncs: any[];
    sync_health: {
      status: string;
      success_rate: number;
      average_duration_minutes: number;
      last_error?: string;
    };
  }> {
    const { tenant_id, config_id, limit } = params;
    const queryParams = new URLSearchParams();
    if (limit) queryParams.append('limit', limit.toString());
    
    const url = `/tenants/${tenant_id}${this.basePath}/configurations/${config_id}/sync/status${queryParams.toString() ? `?${queryParams.toString()}` : ''}`;
    
    return apiClient.get(url);
  }

  /**
   * Get detailed sync logs for a configuration
   */
  async getDetailedSyncLogs(params: {
    tenant_id: string;
    config_id: string;
    limit?: number;
    offset?: number;
    status?: string;
    sync_type?: string;
    data_type?: string;
  }): Promise<{
    logs: any[];
    total: number;
    has_more: boolean;
  }> {
    const { tenant_id, config_id, ...queryParams } = params;
    const searchParams = new URLSearchParams();
    
    Object.entries(queryParams).forEach(([key, value]) => {
      if (value !== undefined) {
        searchParams.append(key, value.toString());
      }
    });
    
    const url = `/tenants/${tenant_id}${this.basePath}/configurations/${config_id}/sync/logs${searchParams.toString() ? `?${searchParams.toString()}` : ''}`;
    
    return apiClient.get(url);
  }

  /**
   * Get sync logs for a POS configuration
   */
  async getSyncLogs(params: {
    tenant_id: string;
    config_id?: string;
    status?: string;
    limit?: number;
    offset?: number;
  }): Promise<{
    sync_logs: POSSyncLog[];
    total: number;
    has_more: boolean;
  }> {
    const { tenant_id, ...queryParams } = params;
    const searchParams = new URLSearchParams();
    
    Object.entries(queryParams).forEach(([key, value]) => {
      if (value !== undefined) {
        searchParams.append(key, value.toString());
      }
    });
    
    const url = `/tenants/${tenant_id}${this.basePath}/sync-logs${searchParams.toString() ? `?${searchParams.toString()}` : ''}`;
    
    return apiClient.get(url);
  }

  // ===================================================================
  // OPERATIONS: Webhook Management
  // Backend: services/pos/app/api/pos_operations.py
  // ===================================================================

  /**
   * Get webhook logs
   */
  async getWebhookLogs(params: {
    tenant_id: string;
    pos_system?: POSSystem;
    status?: string;
    limit?: number;
    offset?: number;
  }): Promise<{
    webhook_logs: POSWebhookLog[];
    total: number;
    has_more: boolean;
  }> {
    const { tenant_id, ...queryParams } = params;
    const searchParams = new URLSearchParams();
    
    Object.entries(queryParams).forEach(([key, value]) => {
      if (value !== undefined) {
        searchParams.append(key, value.toString());
      }
    });
    
    const url = `/tenants/${tenant_id}${this.basePath}/webhook-logs${searchParams.toString() ? `?${searchParams.toString()}` : ''}`;
    
    return apiClient.get(url);
  }

  /**
   * Get webhook endpoint status for a POS system
   */
  async getWebhookStatus(pos_system: POSSystem): Promise<{
    pos_system: string;
    status: string;
    endpoint: string;
    supported_events: {
      events: string[];
      format: string;
      authentication: string;
    };
    last_received?: string;
    total_received: number;
  }> {
    const url = `/webhooks/${pos_system}/status`;
    return apiClient.get(url);
  }

  /**
   * Process webhook (typically called by POS systems, but useful for testing)
   */
  async processWebhook(params: {
    pos_system: POSSystem;
    payload: any;
    signature?: string;
    headers?: Record<string, string>;
  }): Promise<{
    status: string;
    message?: string;
    success?: boolean;
    received?: boolean;
  }> {
    const { pos_system, payload, signature, headers = {} } = params;
    
    const requestHeaders: Record<string, string> = {
      'Content-Type': 'application/json',
      ...headers,
    };
    
    if (signature) {
      requestHeaders['X-Webhook-Signature'] = signature;
    }
    
    const url = `/webhooks/${pos_system}`;
    
    // Note: This would typically be called by the POS system, not the frontend
    // This method is mainly for testing webhook processing
    return apiClient.post(url, payload);
  }

  // ===================================================================
  // Frontend Utility Methods
  // ===================================================================

  /**
   * Format price for display
   */
  formatPrice(amount: number, currency: string = 'EUR'): string {
    return new Intl.NumberFormat('es-ES', {
      style: 'currency',
      currency: currency,
    }).format(amount);
  }

  /**
   * Get POS system display name
   */
  getPOSSystemDisplayName(posSystem: POSSystem): string {
    const systemNames: Record<POSSystem, string> = {
      square: 'Square POS',
      toast: 'Toast POS',
      lightspeed: 'Lightspeed POS',
    };
    
    return systemNames[posSystem] || posSystem;
  }

  /**
   * Get connection status color for UI
   */
  getConnectionStatusColor(isConnected: boolean, healthStatus?: string): 'green' | 'yellow' | 'red' {
    if (!isConnected) return 'red';
    if (healthStatus === 'healthy') return 'green';
    if (healthStatus === 'unhealthy') return 'red';
    return 'yellow'; // unknown status
  }

  /**
   * Get sync status color for UI
   */
  getSyncStatusColor(status?: string): 'green' | 'yellow' | 'red' {
    switch (status) {
      case 'success':
        return 'green';
      case 'failed':
        return 'red';
      case 'partial':
        return 'yellow';
      default:
        return 'yellow';
    }
  }

  /**
   * Format sync interval for display
   */
  formatSyncInterval(minutes: string): string {
    const mins = parseInt(minutes);
    if (mins < 60) {
      return `${mins} minutos`;
    } else if (mins < 1440) {
      const hours = Math.floor(mins / 60);
      return hours === 1 ? '1 hora' : `${hours} horas`;
    } else {
      const days = Math.floor(mins / 1440);
      return days === 1 ? '1 día' : `${days} días`;
    }
  }

  /**
   * Validate POS credentials based on system type
   */
  validateCredentials(posSystem: POSSystem, credentials: Record<string, any>): {
    isValid: boolean;
    errors: string[];
  } {
    const errors: string[] = [];
    
    switch (posSystem) {
      case 'square':
        if (!credentials.application_id) errors.push('Application ID es requerido');
        if (!credentials.access_token) errors.push('Access Token es requerido');
        if (!credentials.location_id) errors.push('Location ID es requerido');
        break;
        
      case 'toast':
        if (!credentials.api_key) errors.push('API Key es requerido');
        if (!credentials.restaurant_guid) errors.push('Restaurant GUID es requerido');
        if (!credentials.location_id) errors.push('Location ID es requerido');
        break;
        
      case 'lightspeed':
        if (!credentials.api_key) errors.push('API Key es requerido');
        if (!credentials.api_secret) errors.push('API Secret es requerido');
        if (!credentials.account_id) errors.push('Account ID es requerido');
        if (!credentials.shop_id) errors.push('Shop ID es requerido');
        break;
        
      default:
        errors.push('Sistema POS no soportado');
    }
    
    return {
      isValid: errors.length === 0,
      errors,
    };
  }
}

// Export singleton instance
export const posService = new POSService();
export default posService;
