import React, { useState, useMemo } from 'react';
import { useNavigate } from 'react-router-dom';
import { Brain, TrendingUp, AlertCircle, Play, RotateCcw, Eye, Loader, CheckCircle } from 'lucide-react';
import { Button, Badge, Modal, Table, Select, StatsGrid, StatusCard, SearchAndFilter, type FilterConfig, Card, EmptyState } from '../../../../components/ui';
import { PageHeader } from '../../../../components/layout';
import { showToast } from '../../../../utils/toast';
import { useCurrentTenant } from '../../../../stores/tenant.store';
import { useIngredients } from '../../../../api/hooks/inventory';
import {
  useModels,
  useActiveModel,
  useTrainSingleProduct,
  useModelMetrics,
  useModelPerformance,
  useTenantTrainingStatistics
} from '../../../../api/hooks/training';
import { ModelDetailsModal, RetrainModelModal } from '../../../../components/domain/forecasting';
import type { IngredientResponse } from '../../../../api/types/inventory';
import type { TrainedModelResponse, SingleProductTrainingRequest } from '../../../../api/types/training';

// Actual API response structure (different from expected paginated response)
interface ModelsApiResponse {
  tenant_id: string;
  models: TrainedModelResponse[];
  total_returned: number;
  active_only: boolean;
  pagination: any;
  enhanced_features: boolean;
  repository_integration: boolean;
}

interface ModelStatus {
  ingredient: IngredientResponse;
  hasModel: boolean;
  model?: TrainedModelResponse;
  isTraining: boolean;
  trainingJobId?: string;
  lastTrainingDate?: string;
  accuracy?: number;
  status: 'no_model' | 'active' | 'training' | 'error';
}

const ModelsConfigPage: React.FC = () => {
  const navigate = useNavigate();
  const currentTenant = useCurrentTenant();
  const tenantId = currentTenant?.id || '';

  const [selectedIngredient, setSelectedIngredient] = useState<IngredientResponse | null>(null);
  const [selectedModel, setSelectedModel] = useState<TrainedModelResponse | null>(null);
  const [showTrainingModal, setShowTrainingModal] = useState(false);
  const [showRetrainModal, setShowRetrainModal] = useState(false);
  const [showModelDetailsModal, setShowModelDetailsModal] = useState(false);
  const [trainingSettings, setTrainingSettings] = useState<Partial<SingleProductTrainingRequest>>({
    seasonality_mode: 'additive',
    daily_seasonality: true,
    weekly_seasonality: true,
    yearly_seasonality: false,
  });

  // API hooks
  const { data: ingredients = [], isLoading: ingredientsLoading } = useIngredients(tenantId);
  const { data: modelsData, isLoading: modelsLoading, error: modelsError } = useModels(tenantId);
  const { data: statistics, error: statsError } = useTenantTrainingStatistics(tenantId);
  const trainMutation = useTrainSingleProduct();

  // Debug: Log the models data structure
  React.useEffect(() => {
    console.log('Models data structure:', {
      modelsData,
      modelsLoading,
      modelsError,
      ingredients: ingredients.length
    });
  }, [modelsData, modelsLoading, modelsError, ingredients]);

  // Build model status for each ingredient
  const modelStatuses = useMemo<ModelStatus[]>(() => {
    // Handle different possible data structures from the API response
    let models: TrainedModelResponse[] = [];

    // The API actually returns { models: [...], tenant_id: ..., total_returned: ... }
    const apiResponse = modelsData as any as ModelsApiResponse;
    if (apiResponse?.models && Array.isArray(apiResponse.models)) {
      models = apiResponse.models;
    } else if (modelsData?.data && Array.isArray(modelsData.data)) {
      models = modelsData.data;
    } else if (modelsData && Array.isArray(modelsData)) {
      models = modelsData as any;
    }

    console.log('Processing models:', {
      modelsData,
      extractedModels: models,
      modelsCount: models.length,
      ingredientsCount: ingredients.length
    });

    return ingredients.map((ingredient: IngredientResponse) => {
      const model = models.find((m: any) => {
        // Focus only on ID-based matching
        return m.inventory_product_id === ingredient.id ||
               String(m.inventory_product_id) === String(ingredient.id);
      });

      const isTraining = false; // We'll track this separately for active training jobs

      console.log(`Ingredient ${ingredient.name} (${ingredient.id}):`, {
        hasModel: !!model,
        model: model ? {
          id: model.model_id,
          created: model.created_at,
          inventory_product_id: model.inventory_product_id
        } : null
      });

      return {
        ingredient,
        hasModel: !!model,
        model,
        isTraining,
        lastTrainingDate: model?.created_at || undefined,
        accuracy: model ? 
                 (model.training_metrics?.mape !== undefined ? (100 - model.training_metrics.mape) : 
                 (model as any).mape !== undefined ? (100 - (model as any).mape) : 
                 undefined) : undefined,
        status: model
          ? (isTraining ? 'training' : 'active')
          : 'no_model'
      };
    });
  }, [ingredients, modelsData]);

  // Calculate orphaned models (models for ingredients that no longer exist)
  const orphanedModels = useMemo(() => {
    const apiResponse = modelsData as any as ModelsApiResponse;
    const models = apiResponse?.models || [];
    const ingredientIds = new Set(ingredients.map(ing => ing.id));

    return models.filter((model: any) => !ingredientIds.has(model.inventory_product_id));
  }, [modelsData, ingredients]);

  // Filter and search
  const [searchTerm, setSearchTerm] = useState('');
  const [statusFilter, setStatusFilter] = useState<string>('all');

  const filteredStatuses = useMemo(() => {
    return modelStatuses.filter(status => {
      const matchesSearch = status.ingredient.name.toLowerCase().includes(searchTerm.toLowerCase());
      const matchesStatus = statusFilter === 'all' || status.status === statusFilter;
      return matchesSearch && matchesStatus;
    });
  }, [modelStatuses, searchTerm, statusFilter]);

  const handleTrainModel = async () => {
    if (!selectedIngredient) return;

    try {
      await trainMutation.mutateAsync({
        tenantId,
        inventoryProductId: selectedIngredient.id,
        request: trainingSettings
      });

      showToast.success(`Entrenamiento iniciado para ${selectedIngredient.name}`);
      setShowTrainingModal(false);
    } catch (error) {
      showToast.error('Error al iniciar el entrenamiento');
    }
  };

  const handleViewModelDetails = async (ingredient: IngredientResponse) => {
    setSelectedIngredient(ingredient);
    
    // Find the model for this ingredient
    const model = modelStatuses.find(status => status.ingredient.id === ingredient.id)?.model;
    if (model) {
      setSelectedModel(model);
    }
    
    setShowModelDetailsModal(true);
  };

  const handleStartTraining = (ingredient: IngredientResponse) => {
    setSelectedIngredient(ingredient);
    setShowTrainingModal(true);
  };

  const handleStartRetraining = (ingredient: IngredientResponse) => {
    setSelectedIngredient(ingredient);

    // Find and set the model for this ingredient
    const model = modelStatuses.find(status => status.ingredient.id === ingredient.id)?.model;
    if (model) {
      setSelectedModel(model);
    }

    setShowRetrainModal(true);
  };

  const handleRetrain = async (settings: SingleProductTrainingRequest) => {
    if (!selectedIngredient) return;

    try {
      await trainMutation.mutateAsync({
        tenantId,
        inventoryProductId: selectedIngredient.id,
        request: settings
      });

      showToast.success(`Reentrenamiento iniciado para ${selectedIngredient.name}`);
      setShowRetrainModal(false);
      setSelectedIngredient(null);
      setSelectedModel(null);
    } catch (error) {
      showToast.error('Error al reentrenar el modelo');
    }
  };



  if (ingredientsLoading || modelsLoading) {
    return (
      <div className="p-6 space-y-6">
        <PageHeader
          title="Configuración de Modelos IA"
          description="Gestiona el entrenamiento y configuración de modelos de predicción para cada ingrediente"
        />
        <div className="flex items-center justify-center h-64">
          <Loader className="w-8 h-8 animate-spin" />
          <span className="ml-2">
            {ingredientsLoading ? 'Cargando ingredientes...' : 'Cargando modelos...'}
          </span>
        </div>
      </div>
    );
  }

  if (modelsError) {
    console.error('Error loading models:', modelsError);
  }

  return (
    <div className="space-y-6">
      <PageHeader
        title="Configuración de Modelos IA"
        description="Gestiona el entrenamiento y configuración de modelos de predicción para cada ingrediente"
      />

      {/* Statistics Cards */}
      <StatsGrid
        stats={[
          {
            title: 'Ingredientes con Modelo',
            value: modelStatuses.filter(s => s.hasModel).length,
            icon: Brain,
            variant: 'default',
          },
          {
            title: 'Sin Modelo',
            value: modelStatuses.filter(s => s.status === 'no_model').length,
            icon: AlertCircle,
            variant: 'warning',
          },
          {
            title: 'Modelos Activos',
            value: modelStatuses.filter(s => s.status === 'active').length,
            icon: CheckCircle,
            variant: 'success',
          },
          {
            title: 'Precisión Promedio',
            value: statsError ? 'N/A' : (statistics?.models?.average_accuracy !== undefined && statistics?.models?.average_accuracy !== null ? `${Number(statistics.models.average_accuracy).toFixed(1)}%` : 'N/A'),
            icon: TrendingUp,
            variant: 'success',
          },
          {
            title: 'Total Modelos',
            value: modelStatuses.length,
            icon: Brain,
            variant: 'info',
          },
          {
            title: 'Modelos Huérfanos',
            value: orphanedModels.length,
            icon: AlertCircle,
            variant: 'error',
          },
        ]}
        columns={3}
      />

      {/* Search and Filter Controls */}
      <SearchAndFilter
        searchValue={searchTerm}
        onSearchChange={setSearchTerm}
        searchPlaceholder="Buscar ingrediente..."
        filters={[
          {
            key: 'status',
            label: 'Estado',
            type: 'dropdown',
            value: statusFilter,
            onChange: (value) => setStatusFilter(value as string),
            placeholder: 'Todos los estados',
            options: [
              { value: 'no_model', label: 'Sin modelo' },
              { value: 'active', label: 'Activo' },
              { value: 'training', label: 'Entrenando' },
              { value: 'error', label: 'Error' }
            ]
          }
        ] as FilterConfig[]}
      />

      {/* Models Grid */}
      {filteredStatuses.length === 0 ? (
        <EmptyState
          icon={Brain}
          title="No se encontraron ingredientes"
          description="No hay ingredientes que coincidan con los filtros aplicados."
          className="col-span-full"
        />
      ) : (
        <div className="grid gap-4 md:grid-cols-2 lg:grid-cols-3">
        {(
          filteredStatuses.map((status) => {
            // Get status configuration for the StatusCard
            const statusConfig = {
              color: status.status === 'active' 
                ? '#10B981' // green for active
                : status.status === 'no_model' 
                ? '#6B7280' // gray for no model
                : status.status === 'training' 
                ? '#F59E0B' // amber for training
                : '#EF4444', // red for error
              text: status.status === 'active' 
                ? 'Activo' 
                : status.status === 'no_model' 
                ? 'Sin Modelo' 
                : status.status === 'training' 
                ? 'Entrenando' 
                : 'Error',
              icon: status.status === 'active' 
                ? CheckCircle 
                : status.status === 'no_model' 
                ? AlertCircle 
                : status.status === 'training' 
                ? Loader 
                : AlertCircle,
              isCritical: status.status === 'error',
              isHighlight: status.status === 'training'
            };

            return (
              <StatusCard
                key={status.ingredient.id}
                id={status.ingredient.id}
                statusIndicator={statusConfig}
                title={status.ingredient.name}
                subtitle={status.ingredient.category || undefined}
                primaryValue={status.accuracy ? status.accuracy.toFixed(1) : 'N/A'}
                primaryValueLabel="Precisión"
                secondaryInfo={status.lastTrainingDate ? {
                  label: 'Último entrenamiento',
                  value: new Date(status.lastTrainingDate).toLocaleDateString('es-ES')
                } : undefined}
                onClick={() => {
                  if (status.hasModel) {
                    handleViewModelDetails(status.ingredient);
                  } else {
                    handleStartTraining(status.ingredient);
                  }
                }}
                actions={
                  (() => {
                    if (status.hasModel) {
                      // For models that exist: prioritize retraining action as primary (text button)
                      // and details as secondary (icon button)
                      return [
                        {
                          label: 'Reentrenar',
                          icon: RotateCcw,
                          onClick: () => handleStartRetraining(status.ingredient),
                          priority: 'primary' as const
                        },
                        {
                          label: 'Ver Detalles',
                          icon: Eye,
                          onClick: () => handleViewModelDetails(status.ingredient),
                          priority: 'secondary' as const
                        }
                      ];
                    } else {
                      // For models that don't exist: only train action
                      return [
                        {
                          label: 'Entrenar',
                          icon: Play,
                          onClick: () => handleStartTraining(status.ingredient),
                          priority: 'primary' as const
                        }
                      ];
                    }
                  })()
                }
              />
            );
          })
        )}
        </div>
      )}

      {/* Training Modal */}
      <Modal
        isOpen={showTrainingModal}
        onClose={() => setShowTrainingModal(false)}
        title={`Entrenar Modelo - ${selectedIngredient?.name}`}
        size="lg"
      >
        <div className="space-y-6">
          <div className="p-4 bg-blue-50 rounded-lg">
            <h4 className="font-medium text-blue-900 mb-2">Configuración de Entrenamiento</h4>
            <p className="text-sm text-blue-700">
              Configure los parámetros para el entrenamiento del modelo de predicción de demanda.
            </p>
          </div>

          <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
            <div>
              <label className="block text-sm font-medium mb-2">Modo de Estacionalidad</label>
              <Select
                value={trainingSettings.seasonality_mode || 'additive'}
                onChange={(value) => setTrainingSettings(prev => ({ ...prev, seasonality_mode: value as any }))}
                options={[
                  { value: 'additive', label: 'Aditivo' },
                  { value: 'multiplicative', label: 'Multiplicativo' }
                ]}
              />
            </div>

            <div className="space-y-4">
              <h4 className="font-medium text-sm">Patrones Estacionales</h4>

              <label className="flex items-center space-x-2">
                <input
                  type="checkbox"
                  checked={trainingSettings.daily_seasonality || false}
                  onChange={(e) => setTrainingSettings(prev => ({ ...prev, daily_seasonality: e.target.checked }))}
                  className="rounded border-[var(--border-primary)]"
                />
                <span className="text-sm">Estacionalidad diaria</span>
              </label>

              <label className="flex items-center space-x-2">
                <input
                  type="checkbox"
                  checked={trainingSettings.weekly_seasonality || false}
                  onChange={(e) => setTrainingSettings(prev => ({ ...prev, weekly_seasonality: e.target.checked }))}
                  className="rounded border-[var(--border-primary)]"
                />
                <span className="text-sm">Estacionalidad semanal</span>
              </label>

              <label className="flex items-center space-x-2">
                <input
                  type="checkbox"
                  checked={trainingSettings.yearly_seasonality || false}
                  onChange={(e) => setTrainingSettings(prev => ({ ...prev, yearly_seasonality: e.target.checked }))}
                  className="rounded border-[var(--border-primary)]"
                />
                <span className="text-sm">Estacionalidad anual</span>
              </label>
            </div>
          </div>

          <div className="flex justify-end space-x-3 pt-4 border-t">
            <Button variant="outline" onClick={() => setShowTrainingModal(false)}>
              Cancelar
            </Button>
            <Button
              onClick={handleTrainModel}
              isLoading={trainMutation.isPending}
              leftIcon={<Play className="w-4 h-4" />}
            >
              Iniciar Entrenamiento
            </Button>
          </div>
        </div>
      </Modal>

      {/* Model Details Modal */}
      {selectedModel && (
        <ModelDetailsModal
          isOpen={showModelDetailsModal}
          onClose={() => setShowModelDetailsModal(false)}
          model={selectedModel}
          onRetrain={handleRetrain}
          onViewPredictions={(modelId) => {
            // Navigate to forecast history page filtered by this model
            navigate(`/app/operations/forecasting?model_id=${modelId}&view=history`);
            setShowModelDetailsModal(false);
          }}
        />
      )}

      {/* Retrain Model Modal */}
      {selectedIngredient && (
        <RetrainModelModal
          isOpen={showRetrainModal}
          onClose={() => {
            setShowRetrainModal(false);
            setSelectedIngredient(null);
            setSelectedModel(null);
          }}
          ingredient={selectedIngredient}
          currentModel={selectedModel}
          onRetrain={handleRetrain}
          isLoading={trainMutation.isPending}
        />
      )}
    </div>
  );
};

export default ModelsConfigPage;
