/**
 * Smart Action Handlers - Complete Implementation
 * Handles execution of all smart action types from enriched alerts
 *
 * NO PLACEHOLDERS - All action types fully implemented
 */

import { useNavigate } from 'react-router-dom';
import { SmartAction as ImportedSmartAction, SmartActionType } from '../api/types/events';
import { useTenantStore } from '../stores/tenant.store';
import { getTenantCurrencySymbol } from '../hooks/useTenantCurrency';

// ============================================================
// Types (using imported types from events.ts)
// ============================================================

// Legacy interface for backwards compatibility with existing handler code
export interface SmartAction {
  label?: string;
  label_key?: string;
  action_type: string;
  type?: string; // For backward compatibility
  variant?: 'primary' | 'secondary' | 'ghost' | 'danger';
  metadata?: Record<string, any>;
  disabled?: boolean;
  disabled_reason?: string;
  estimated_time_minutes?: number;
  consequence?: string;
}

// Re-export types from events.ts
export { SmartActionType };

// ============================================================
// Smart Action Handler Class
// ============================================================

export class SmartActionHandler {
  private navigate: ReturnType<typeof useNavigate> | null = null;
  private onSuccess?: (alertId?: string) => void;
  private onError?: (error: string) => void;

  constructor(
    navigate?: ReturnType<typeof useNavigate>,
    callbacks?: {
      onSuccess?: (alertId?: string) => void;
      onError?: (error: string) => void;
    }
  ) {
    this.navigate = navigate || null;
    this.onSuccess = callbacks?.onSuccess;
    this.onError = callbacks?.onError;
  }

  async handleAction(action: SmartAction, alertId?: string): Promise<boolean> {
    try {
      let result = false;

      // Support both legacy (type) and new (action_type) field names
      const actionType = action.action_type || action.type;

      switch (actionType) {
        case SmartActionType.APPROVE_PO:
          result = await this.handleApprovePO(action);
          break;

        case SmartActionType.REJECT_PO:
          result = await this.handleRejectPO(action);
          break;

        case SmartActionType.MODIFY_PO:
          result = this.handleModifyPO(action);
          break;

        case SmartActionType.VIEW_PO_DETAILS:
          result = this.handleViewPODetails(action);
          break;

        case SmartActionType.CALL_SUPPLIER:
          result = this.handleCallSupplier(action);
          break;

        case SmartActionType.NAVIGATE:
          result = this.handleNavigate(action);
          break;

        case SmartActionType.ADJUST_PRODUCTION:
          result = this.handleAdjustProduction(action);
          break;

        case SmartActionType.START_PRODUCTION_BATCH:
          result = await this.handleStartProductionBatch(action);
          break;

        case SmartActionType.NOTIFY_CUSTOMER:
          result = await this.handleNotifyCustomer(action);
          break;

        case SmartActionType.CANCEL_AUTO_ACTION:
          result = await this.handleCancelAutoAction(action);
          break;

        case SmartActionType.MARK_DELIVERY_RECEIVED:
          result = await this.handleMarkDeliveryReceived(action);
          break;

        case SmartActionType.COMPLETE_STOCK_RECEIPT:
          result = await this.handleCompleteStockReceipt(action);
          break;

        case SmartActionType.OPEN_REASONING:
          result = this.handleOpenReasoning(action);
          break;

        case SmartActionType.SNOOZE:
          result = await this.handleSnooze(action, alertId);
          break;

        case SmartActionType.DISMISS:
          result = await this.handleDismiss(action, alertId);
          break;

        case SmartActionType.MARK_READ:
          result = await this.handleMarkRead(action, alertId);
          break;

        default:
          console.warn('Unknown action type:', actionType);
          this.onError?.(`Unknown action type: ${actionType}`);
          return false;
      }

      if (result && this.onSuccess) {
        this.onSuccess(alertId);
      }

      return result;
    } catch (error) {
      console.error('Error handling action:', error);
      this.onError?.(error instanceof Error ? error.message : 'Unknown error');
      return false;
    }
  }

  // ============================================================
  // Action Handlers
  // ============================================================

  /**
   * 1. APPROVE_PO - Approve a purchase order
   */
  private async handleApprovePO(action: SmartAction): Promise<boolean> {
    const { po_id, tenant_id, amount } = action.metadata || {};

    if (!po_id || !tenant_id) {
      console.error('Missing PO ID or tenant ID');
      this.onError?.('Missing required data for PO approval');
      return false;
    }

    try {
      const response = await fetch(
        `/api/v1/tenants/${tenant_id}/procurement/purchase-orders/${po_id}/approve`,
        {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
            Authorization: `Bearer ${localStorage.getItem('token') || ''}`,
          },
          body: JSON.stringify({
            action: 'approve',
            approved_by: 'current_user',
            notes: `Approved via alert action${amount ? ` (${getTenantCurrencySymbol(useTenantStore.getState().currentTenant?.currency)}${amount})` : ''}`,
          }),
        }
      );

      if (response.ok) {
        // Dispatch success event for real-time updates
        window.dispatchEvent(
          new CustomEvent('po:approved', {
            detail: { po_id, amount },
          })
        );
        return true;
      } else {
        const error = await response.text();
        console.error('Failed to approve PO:', error);
        this.onError?.(`Failed to approve PO: ${error}`);
        return false;
      }
    } catch (error) {
      console.error('Error approving PO:', error);
      this.onError?.(error instanceof Error ? error.message : 'Network error');
      return false;
    }
  }

  /**
   * 2. REJECT_PO - Reject a purchase order
   */
  private async handleRejectPO(action: SmartAction): Promise<boolean> {
    const { po_id, tenant_id, reason } = action.metadata || {};

    if (!po_id || !tenant_id) {
      console.error('Missing PO ID or tenant ID');
      this.onError?.('Missing required data for PO rejection');
      return false;
    }

    try {
      const response = await fetch(
        `/api/v1/tenants/${tenant_id}/procurement/purchase-orders/${po_id}/approve`,
        {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
            Authorization: `Bearer ${localStorage.getItem('token') || ''}`,
          },
          body: JSON.stringify({
            action: 'reject',
            approved_by: 'current_user',
            notes: reason || 'Rejected via alert action',
          }),
        }
      );

      if (response.ok) {
        window.dispatchEvent(
          new CustomEvent('po:rejected', {
            detail: { po_id },
          })
        );
        return true;
      } else {
        const error = await response.text();
        console.error('Failed to reject PO:', error);
        this.onError?.(`Failed to reject PO: ${error}`);
        return false;
      }
    } catch (error) {
      console.error('Error rejecting PO:', error);
      this.onError?.(error instanceof Error ? error.message : 'Network error');
      return false;
    }
  }

  /**
   * 3. MODIFY_PO - Open PO in edit mode
   */
  private handleModifyPO(action: SmartAction): boolean {
    const { po_id } = action.metadata || {};

    if (!po_id) {
      console.error('Missing PO ID');
      this.onError?.('Missing PO ID for modification');
      return false;
    }

    // Emit event to open PO modal in edit mode
    window.dispatchEvent(
      new CustomEvent('po:open-edit', {
        detail: { po_id, mode: 'edit' },
      })
    );

    return true;
  }

  /**
   * 3.5. VIEW_PO_DETAILS - Open PO in view mode
   */
  private handleViewPODetails(action: SmartAction): boolean {
    const { po_id, tenant_id } = action.metadata || {};

    if (!po_id) {
      console.error('Missing PO ID');
      this.onError?.('Missing PO ID for viewing details');
      return false;
    }

    // Emit event to open PO modal in view mode
    window.dispatchEvent(
      new CustomEvent('po:open-details', {
        detail: { po_id, tenant_id, mode: 'view' },
      })
    );

    return true;
  }

  /**
   * 4. CALL_SUPPLIER - Initiate phone call
   */
  private handleCallSupplier(action: SmartAction): boolean {
    const { phone, name } = action.metadata || {};

    if (!phone) {
      console.error('Missing phone number');
      this.onError?.('Missing supplier phone number');
      return false;
    }

    // Format phone number for tel: protocol (remove spaces, dashes)
    const cleanPhone = phone.replace(/[\s\-()]/g, '');

    // On mobile devices, this will trigger the phone dialer
    // On desktop, it will use the system's default phone app
    window.location.href = `tel:${cleanPhone}`;

    return true;
  }

  /**
   * 5. NAVIGATE - Navigate to a page
   */
  private handleNavigate(action: SmartAction): boolean {
    const { path, state } = action.metadata || {};

    if (!path) {
      console.error('Missing navigation path');
      this.onError?.('Missing navigation path');
      return false;
    }

    if (this.navigate) {
      this.navigate(path, { state });
      return true;
    }

    // Fallback: Use window.location
    window.location.href = path;
    return true;
  }

  /**
   * 6. ADJUST_PRODUCTION - Navigate to batch edit with suggested quantity
   */
  private handleAdjustProduction(action: SmartAction): boolean {
    const { batch_id, suggested_quantity } = action.metadata || {};

    if (!batch_id) {
      console.error('Missing batch ID');
      this.onError?.('Missing batch ID for adjustment');
      return false;
    }

    const path = `/app/operations/production/batches/${batch_id}/edit`;
    const state = suggested_quantity ? { suggested_quantity } : undefined;

    if (this.navigate) {
      this.navigate(path, { state });
      return true;
    }

    window.location.href = path;
    return true;
  }

  /**
   * 7. START_PRODUCTION_BATCH - Start a production batch
   */
  private async handleStartProductionBatch(action: SmartAction): Promise<boolean> {
    const { batch_id, tenant_id } = action.metadata || {};

    if (!batch_id || !tenant_id) {
      console.error('Missing batch ID or tenant ID');
      this.onError?.('Missing required data to start batch');
      return false;
    }

    try {
      const response = await fetch(
        `/api/v1/tenants/${tenant_id}/production/batches/${batch_id}/start`,
        {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
            Authorization: `Bearer ${localStorage.getItem('token') || ''}`,
          },
          body: JSON.stringify({
            started_at: new Date().toISOString(),
            started_by: 'current_user',
          }),
        }
      );

      if (response.ok) {
        window.dispatchEvent(
          new CustomEvent('batch:started', {
            detail: { batch_id },
          })
        );
        return true;
      } else {
        const error = await response.text();
        console.error('Failed to start batch:', error);
        this.onError?.(`Failed to start batch: ${error}`);
        return false;
      }
    } catch (error) {
      console.error('Error starting batch:', error);
      this.onError?.(error instanceof Error ? error.message : 'Network error');
      return false;
    }
  }

  /**
   * 8. NOTIFY_CUSTOMER - Navigate to customer notification page
   */
  private async handleNotifyCustomer(action: SmartAction): Promise<boolean> {
    const { customer_name, customer_id, message } = action.metadata || {};

    if (!customer_id) {
      console.error('Missing customer ID');
      this.onError?.('Missing customer ID for notification');
      return false;
    }

    // Navigate to communications page with pre-filled message
    if (this.navigate) {
      this.navigate(`/app/communications`, {
        state: {
          customer_id,
          customer_name,
          pre_message: message,
        },
      });
      return true;
    }

    return false;
  }

  /**
   * 9. CANCEL_AUTO_ACTION - Cancel pending auto-action
   */
  private async handleCancelAutoAction(action: SmartAction): Promise<boolean> {
    const { alert_id, tenant_id, action_type } = action.metadata || {};

    if (!alert_id || !tenant_id) {
      console.error('Missing alert ID or tenant ID');
      this.onError?.('Missing required data to cancel auto-action');
      return false;
    }

    try {
      const response = await fetch(
        `/api/v1/tenants/${tenant_id}/alerts/${alert_id}/cancel-auto-action`,
        {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
            Authorization: `Bearer ${localStorage.getItem('token') || ''}`,
          },
          body: JSON.stringify({
            action_type,
            cancelled_by: 'current_user',
          }),
        }
      );

      if (response.ok) {
        window.dispatchEvent(
          new CustomEvent('auto-action:cancelled', {
            detail: { alert_id, action_type },
          })
        );
        return true;
      } else {
        const error = await response.text();
        console.error('Failed to cancel auto-action:', error);
        this.onError?.(`Failed to cancel auto-action: ${error}`);
        return false;
      }
    } catch (error) {
      console.error('Failed to cancel auto-action:', error);
      this.onError?.(error instanceof Error ? error.message : 'Network error');
      return false;
    }
  }

  /**
   * 10. MARK_DELIVERY_RECEIVED - Mark delivery as received and open stock receipt modal
   */
  private async handleMarkDeliveryReceived(action: SmartAction): Promise<boolean> {
    const { po_id, delivery_id, tenant_id } = action.metadata || {};

    if (!po_id || !tenant_id) {
      console.error('Missing PO ID or tenant ID');
      this.onError?.('Missing required data for delivery receipt');
      return false;
    }

    // Emit event to open stock receipt modal
    window.dispatchEvent(
      new CustomEvent('delivery:mark-received', {
        detail: {
          po_id,
          delivery_id,
          tenant_id,
        },
      })
    );

    return true;
  }

  /**
   * 11. COMPLETE_STOCK_RECEIPT - Open stock receipt modal for completion
   */
  private async handleCompleteStockReceipt(action: SmartAction): Promise<boolean> {
    const { receipt_id, po_id, tenant_id } = action.metadata || {};

    if ((!receipt_id && !po_id) || !tenant_id) {
      console.error('Missing receipt ID/PO ID or tenant ID');
      this.onError?.('Missing required data for stock receipt');
      return false;
    }

    // Emit event to open stock receipt modal
    window.dispatchEvent(
      new CustomEvent('stock-receipt:open', {
        detail: {
          receipt_id,
          po_id,
          tenant_id,
          mode: receipt_id ? 'edit' : 'create',
        },
      })
    );

    return true;
  }

  /**
   * 12. OPEN_REASONING - Show AI reasoning details
   */
  private handleOpenReasoning(action: SmartAction): boolean {
    const { action_id, po_id, batch_id, reasoning } = action.metadata || {};

    // Always emit event to show reasoning modal inline (don't navigate away)
    // This keeps the user on the dashboard while showing reasoning details
    window.dispatchEvent(
      new CustomEvent('reasoning:show', {
        detail: { action_id, po_id, batch_id, reasoning },
      })
    );

    return true;
  }

  /**
   * 13. SNOOZE - Snooze alert for specified duration
   */
  private async handleSnooze(action: SmartAction, alertId?: string): Promise<boolean> {
    const { duration_hours, alert_id } = action.metadata || {};
    const finalAlertId = alert_id || alertId;

    if (!finalAlertId) {
      console.error('Missing alert ID');
      this.onError?.('Missing alert ID for snooze');
      return false;
    }

    // Emit event to snooze alert
    window.dispatchEvent(
      new CustomEvent('alert:snooze', {
        detail: {
          alert_id: finalAlertId,
          duration_hours: duration_hours || 4, // Default 4 hours
          snoozed_at: new Date().toISOString(),
        },
      })
    );

    return true;
  }

  /**
   * 14. DISMISS - Dismiss alert
   */
  private async handleDismiss(action: SmartAction, alertId?: string): Promise<boolean> {
    const { alert_id } = action.metadata || {};
    const finalAlertId = alert_id || alertId;

    if (!finalAlertId) {
      console.error('Missing alert ID');
      this.onError?.('Missing alert ID for dismiss');
      return false;
    }

    window.dispatchEvent(
      new CustomEvent('alert:dismiss', {
        detail: {
          alert_id: finalAlertId,
          dismissed_at: new Date().toISOString(),
        },
      })
    );

    return true;
  }

  /**
   * 15. MARK_READ - Mark alert as read
   */
  private async handleMarkRead(action: SmartAction, alertId?: string): Promise<boolean> {
    const { alert_id } = action.metadata || {};
    const finalAlertId = alert_id || alertId;

    if (!finalAlertId) {
      console.error('Missing alert ID');
      this.onError?.('Missing alert ID for mark read');
      return false;
    }

    window.dispatchEvent(
      new CustomEvent('alert:mark-read', {
        detail: {
          alert_id: finalAlertId,
          read_at: new Date().toISOString(),
        },
      })
    );

    return true;
  }
}

// ============================================================
// React Hooks
// ============================================================

/**
 * Hook to get action handler with navigation and callbacks
 */
export function useSmartActionHandler(callbacks?: {
  onSuccess?: (alertId?: string) => void;
  onError?: (error: string) => void;
}) {
  const navigate = useNavigate();
  return new SmartActionHandler(navigate, callbacks);
}

/**
 * Get action handler without navigation (for use outside React components)
 */
export function getSmartActionHandler() {
  return new SmartActionHandler();
}

// ============================================================
// Utility Functions
// ============================================================

/**
 * Map smart action variant to Button component variant
 *
 * Smart actions use: primary, secondary, tertiary, danger
 * Button component supports: primary, secondary, outline, ghost, danger, success, warning, gradient
 */
export function mapActionVariantToButton(
  actionVariant?: string
): 'primary' | 'secondary' | 'outline' | 'ghost' | 'danger' | 'success' | 'warning' | 'gradient' {
  switch (actionVariant) {
    case 'primary':
      return 'primary';
    case 'secondary':
      return 'secondary';
    case 'tertiary':
      return 'outline'; // Map tertiary to outline for subtle actions
    case 'danger':
      return 'danger';
    default:
      return 'outline'; // Default to outline for unknown variants
  }
}

/**
 * Get button variant class name (for use with UI libraries)
 */
export function getActionButtonClass(variant: string): string {
  const baseClasses = 'px-4 py-2 rounded-md font-medium transition-colors';

  switch (variant) {
    case 'primary':
      return `${baseClasses} bg-primary text-white hover:bg-primary-dark`;
    case 'secondary':
      return `${baseClasses} bg-secondary text-secondary-foreground hover:bg-secondary-dark`;
    case 'ghost':
      return `${baseClasses} border border-border text-foreground hover:bg-accent`;
    case 'danger':
      return `${baseClasses} bg-error text-white hover:bg-error-dark`;
    default:
      return `${baseClasses} bg-accent text-accent-foreground hover:bg-accent-dark`;
  }
}
