import apiService from './apiService';
import API_CONFIG from '../config/api';

// Cast apiService to any to bypass strict typing
const api = apiService as any;

// PPM Table Row Interface (child table)
export interface PPMTableRow {
  name?: string;
  idx?: number;
  docstatus?: number;
  doctype?: string;
  owner?: string;
  parent?: string;
  parentfield?: string;
  parenttype?: string;
  maintenance_name: string;
  working: number | boolean;
  defect_found: number | boolean;
  not_working: number | boolean;
  __islocal?: number;
  __unsaved?: number;
}

// Asset Maintenance Log Interface
export interface AssetMaintenanceLog {
  name: string;
  owner?: string;
  creation?: string;
  modified?: string;
  modified_by?: string;
  docstatus?: number;
  idx?: number;
  
  // Workflow
  workflow_state?: string;
  
  // Asset Information
  asset_maintenance?: string;
  naming_series?: string;
  asset_name?: string;
  custom_asset_type?: string;
  item_code?: string;
  item_name?: string;
  custom_asset_names?: string;
  custom_hospital_name?: string;
  
  // Task Information
  task?: string;
  task_name?: string;
  maintenance_type?: string;
  periodicity?: string;
  custom_template?: string;
  
  // Status & Dates
  maintenance_status?: string;
  due_date?: string;
  completion_date?: string;
  
  // Assignment
  assign_to_name?: string;
  
  // Certificate
  has_certificate?: number | boolean;
  
  // Early Completion
  custom_early_completion?: string; // "Yes" or "No"
  custom_early_completion_reason?: string;
  
  // MOH Approval
  custom_accepted_by_moh?: number | boolean;
  custom_accepted_by_moh_?: number | boolean;
  
  // Overdue
  custom_pm_overdue_reason?: string;
  
  // PPM Table (child table)
  custom_table?: PPMTableRow[];
  
  // Description/Notes
  description?: string;
}

// Response interface for list
export interface AssetMaintenanceListResponse {
  asset_maintenance_logs: AssetMaintenanceLog[];
  total_count: number;
  limit: number;
  offset: number;
  has_more: boolean;
}

// Filters interface
export interface MaintenanceFilters {
  maintenance_status?: string;
  asset_name?: string;
  custom_hospital_name?: string;
  maintenance_type?: string;
  workflow_state?: string;
  periodicity?: string;
  assign_to_name?: string;
  custom_asset_type?: string;
  [key: string]: any;
}

// Create/Update data interface
export interface CreateMaintenanceData {
  // Asset Information
  asset_name?: string;
  custom_asset_type?: string;
  item_code?: string;
  item_name?: string;
  custom_asset_names?: string;
  custom_hospital_name?: string;
  
  // Task Information
  task?: string;
  task_name?: string;
  maintenance_type?: string;
  periodicity?: string;
  custom_template?: string;
  
  // Status & Dates
  maintenance_status?: string;
  due_date?: string;
  completion_date?: string;
  
  // Assignment
  assign_to_name?: string;
  
  // Certificate
  has_certificate?: number | boolean;
  
  // Early Completion
  custom_early_completion?: string; // "Yes" or "No"
  custom_early_completion_reason?: string;
  
  // MOH Approval
  custom_accepted_by_moh?: number | boolean;
  custom_accepted_by_moh_?: number | boolean;
  
  // Overdue
  custom_pm_overdue_reason?: string;
  
  // PPM Table (child table)
  custom_table?: PPMTableRow[];
  
  // Description/Notes
  description?: string;
  
  // Allow additional fields
  [key: string]: any;
}

class AssetMaintenanceService {
  /**
   * Get list of asset maintenance logs with optional filters and pagination
   */
  async getMaintenanceLogs(
    filters?: MaintenanceFilters,
    fields?: string[],
    limit: number = 20,
    offset: number = 0,
    orderBy?: string
  ): Promise<AssetMaintenanceListResponse> {
    const params = new URLSearchParams();
    
    if (filters) {
      params.append('filters', JSON.stringify(filters));
    }
    
    if (fields && fields.length > 0) {
      params.append('fields', JSON.stringify(fields));
    }
    
    params.append('limit', limit.toString());
    params.append('offset', offset.toString());
    
    if (orderBy) {
      params.append('order_by', orderBy);
    }
    
    // Request child tables to be included
    params.append('include_child_tables', 'true');
    
    const endpoint = `${API_CONFIG.ENDPOINTS.GET_ASSET_MAINTENANCE_LOGS}?${params.toString()}`;
    return api.apiCall(endpoint);
  }

  /**
   * Get detailed information about a specific maintenance log
   */
  async getMaintenanceLogDetails(logName: string): Promise<AssetMaintenanceLog> {
    const params = new URLSearchParams();
    params.append('log_name', logName);
    params.append('include_child_tables', 'true');
    
    const endpoint = `${API_CONFIG.ENDPOINTS.GET_ASSET_MAINTENANCE_LOG_DETAILS}?${params.toString()}`;
    return api.apiCall(endpoint);
  }

  /**
   * Create a new maintenance log
   */
  async createMaintenanceLog(logData: CreateMaintenanceData): Promise<{ success: boolean; asset_maintenance_log: AssetMaintenanceLog; message: string; error?: string }> {
    // Prepare data - ensure child table is properly formatted
    const preparedData = this.prepareLogData(logData);
    
    return api.apiCall(API_CONFIG.ENDPOINTS.CREATE_ASSET_MAINTENANCE_LOG, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({ log_data: preparedData })
    });
  }

  /**
   * Update an existing maintenance log
   */
  async updateMaintenanceLog(
    logName: string,
    logData: Partial<CreateMaintenanceData>
  ): Promise<{ success: boolean; asset_maintenance_log: AssetMaintenanceLog; message: string; error?: string }> {
    // Prepare data - ensure child table is properly formatted
    const preparedData = this.prepareLogData(logData);
    
    return api.apiCall(API_CONFIG.ENDPOINTS.UPDATE_ASSET_MAINTENANCE_LOG, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        log_name: logName,
        log_data: preparedData
      })
    });
  }

  /**
   * Delete a maintenance log
   */
  async deleteMaintenanceLog(logName: string): Promise<{ success: boolean; message: string }> {
    return api.apiCall(API_CONFIG.ENDPOINTS.DELETE_ASSET_MAINTENANCE_LOG, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({ log_name: logName })
    });
  }

  /**
   * Update maintenance log status
   */
  async updateMaintenanceStatus(
    logName: string,
    maintenanceStatus?: string,
    workflowState?: string
  ): Promise<{ success: boolean; asset_maintenance_log: AssetMaintenanceLog; message: string }> {
    return api.apiCall(API_CONFIG.ENDPOINTS.UPDATE_MAINTENANCE_STATUS, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        log_name: logName,
        maintenance_status: maintenanceStatus,
        workflow_state: workflowState
      })
    });
  }

  /**
   * Get maintenance logs for a specific asset
   */
  async getMaintenanceLogsByAsset(
    assetName: string,
    filters?: MaintenanceFilters,
    limit: number = 20,
    offset: number = 0
  ): Promise<AssetMaintenanceListResponse> {
    const params = new URLSearchParams();
    params.append('asset_name', assetName);
    
    if (filters) {
      params.append('filters', JSON.stringify(filters));
    }
    
    params.append('limit', limit.toString());
    params.append('offset', offset.toString());
    params.append('include_child_tables', 'true');
    
    const endpoint = `${API_CONFIG.ENDPOINTS.GET_MAINTENANCE_LOGS_BY_ASSET}?${params.toString()}`;
    return api.apiCall(endpoint);
  }

  /**
   * Get overdue maintenance logs
   */
  async getOverdueMaintenanceLogs(
    filters?: MaintenanceFilters,
    limit: number = 20,
    offset: number = 0
  ): Promise<AssetMaintenanceListResponse> {
    const params = new URLSearchParams();
    
    if (filters) {
      params.append('filters', JSON.stringify(filters));
    }
    
    params.append('limit', limit.toString());
    params.append('offset', offset.toString());
    params.append('include_child_tables', 'true');
    
    const endpoint = `${API_CONFIG.ENDPOINTS.GET_OVERDUE_MAINTENANCE_LOGS}?${params.toString()}`;
    return api.apiCall(endpoint);
  }

  /**
   * Add a PPM table row to maintenance log
   */
  async addPPMTableRow(
    logName: string,
    rowData: Partial<PPMTableRow>
  ): Promise<{ success: boolean; custom_table: PPMTableRow[]; message: string }> {
    return api.apiCall(API_CONFIG.ENDPOINTS.ADD_PPM_TABLE_ROW || '/api/method/asset_lite.api.asset_maintenance_api.add_ppm_table_row', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        log_name: logName,
        row_data: this.cleanPPMRow(rowData)
      })
    });
  }

  /**
   * Remove a PPM table row from maintenance log
   */
  async removePPMTableRow(
    logName: string,
    rowName: string
  ): Promise<{ success: boolean; custom_table: PPMTableRow[]; message: string }> {
    return api.apiCall(API_CONFIG.ENDPOINTS.REMOVE_PPM_TABLE_ROW || '/api/method/asset_lite.api.asset_maintenance_api.remove_ppm_table_row', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        log_name: logName,
        row_name: rowName
      })
    });
  }

  /**
   * Update a PPM table row
   */
  async updatePPMTableRow(
    logName: string,
    rowName: string,
    rowData: Partial<PPMTableRow>
  ): Promise<{ success: boolean; custom_table: PPMTableRow[]; message: string }> {
    return api.apiCall(API_CONFIG.ENDPOINTS.UPDATE_PPM_TABLE_ROW || '/api/method/asset_lite.api.asset_maintenance_api.update_ppm_table_row', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        log_name: logName,
        row_name: rowName,
        row_data: this.cleanPPMRow(rowData)
      })
    });
  }

  /**
   * Clean a single PPM row - only include essential fields
   */
  private cleanPPMRow(row: Partial<PPMTableRow>): Record<string, any> {
    return {
      // Only include the name if it exists and is not a temp name
      ...(row.name && !row.name.startsWith('new-') ? { name: row.name } : {}),
      maintenance_name: row.maintenance_name || '',
      working: typeof row.working === 'boolean' ? (row.working ? 1 : 0) : (row.working || 0),
      defect_found: typeof row.defect_found === 'boolean' ? (row.defect_found ? 1 : 0) : (row.defect_found || 0),
      not_working: typeof row.not_working === 'boolean' ? (row.not_working ? 1 : 0) : (row.not_working || 0),
    };
  }

  /**
   * Helper method to prepare log data for API
   * Ensures child tables and boolean fields are properly formatted
   */
  private prepareLogData(logData: Partial<CreateMaintenanceData>): Record<string, any> {
    const prepared: Record<string, any> = {};
    
    // Copy only the fields we want to send, excluding internal React state
    const allowedFields = [
      'asset_name', 'custom_asset_type', 'item_code', 'item_name',
      'custom_asset_names', 'custom_hospital_name', 'task', 'task_name',
      'maintenance_type', 'periodicity', 'custom_template', 'maintenance_status',
      'due_date', 'completion_date', 'assign_to_name', 'has_certificate',
      'custom_early_completion', 'custom_early_completion_reason',
      'custom_accepted_by_moh', 'custom_accepted_by_moh_', 'custom_pm_overdue_reason',
      'description', 'custom_table'
    ];
    
    for (const field of allowedFields) {
      if (logData[field] !== undefined && logData[field] !== null && logData[field] !== '') {
        prepared[field] = logData[field];
      }
    }
    
    // Convert boolean values to integers for Frappe
    if (typeof prepared.has_certificate === 'boolean') {
      prepared.has_certificate = prepared.has_certificate ? 1 : 0;
    }
    if (typeof prepared.custom_accepted_by_moh === 'boolean') {
      prepared.custom_accepted_by_moh = prepared.custom_accepted_by_moh ? 1 : 0;
    }
    if (typeof prepared.custom_accepted_by_moh_ === 'boolean') {
      prepared.custom_accepted_by_moh_ = prepared.custom_accepted_by_moh_ ? 1 : 0;
    }
    
    // Prepare PPM Table rows - clean up each row
    if (prepared.custom_table && Array.isArray(prepared.custom_table)) {
      prepared.custom_table = prepared.custom_table.map((row: any) => this.cleanPPMRow(row));
    }
    
    return prepared;
  }
}

// Create and export singleton instance
const assetMaintenanceService = new AssetMaintenanceService();
export default assetMaintenanceService;