import React, { useState, useMemo, useCallback } from 'react';
import { clsx } from 'clsx';
import { Card, CardHeader, CardBody } from '../../ui';
import { Button } from '../../ui';
import { Badge } from '../../ui';
import { Select } from '../../ui';
import { Input } from '../../ui';
import { Table, TableColumn } from '../../ui';
import {
  ForecastResponse,
} from '../../../api/types/forecasting';

export interface ForecastTableProps {
  className?: string;
  title?: string;
  data?: ForecastResponse[];
  loading?: boolean;
  error?: string | null;
  pageSize?: number;
  onExportCSV?: (data: ForecastResponse[]) => void;
  onBulkAction?: (action: string, selectedItems: ForecastResponse[]) => void;
  onProductClick?: (productName: string) => void;
  showBulkActions?: boolean;
  showFilters?: boolean;
  compact?: boolean;
}

interface FilterState {
  productName: string;
  category: string;
  accuracyRange: 'all' | 'high' | 'medium' | 'low';
  trendDirection: 'increasing' | 'decreasing' | 'stable' | 'all';
  confidenceLevel: number | 'all';
  dateRange: 'today' | 'week' | 'month' | 'quarter' | 'all';
}

interface SortState {
  field: string;
  order: 'asc' | 'desc';
}

const SPANISH_TRENDS: Record<string, string> = {
  'increasing': 'Creciente',
  'decreasing': 'Decreciente',
  'stable': 'Estable',
  'volatile': 'Volátil',
  'seasonal': 'Estacional',
};

const TREND_COLORS: Record<string, string> = {
  'increasing': 'text-[var(--color-success)]',
  'decreasing': 'text-[var(--color-error)]',
  'stable': 'text-[var(--color-info)]',
  'volatile': 'text-yellow-600',
  'seasonal': 'text-purple-600',
};

const TREND_ICONS: Record<string, string> = {
  'increasing': '↗️',
  'decreasing': '↘️',
  'stable': '➡️',
  'volatile': '📈',
  'seasonal': '🔄',
};

const BAKERY_CATEGORIES = [
  { value: 'all', label: 'Todas las categorías' },
  { value: 'pan', label: 'Pan y Bollería' },
  { value: 'dulces', label: 'Dulces y Postres' },
  { value: 'salados', label: 'Salados' },
  { value: 'estacional', label: 'Productos Estacionales' },
  { value: 'bebidas', label: 'Bebidas' },
];

const SPANISH_PRODUCTS = [
  'Croissants',
  'Pan de molde',
  'Roscón de Reyes',
  'Torrijas',
  'Magdalenas',
  'Empanadas',
  'Tarta de Santiago',
  'Mazapán',
  'Pan tostado',
  'Palmeras',
  'Napolitanas',
  'Ensaimadas',
  'Churros',
  'Polvorones',
  'Turrones',
];

const ForecastTable: React.FC<ForecastTableProps> = ({
  className,
  title = 'Predicciones de Demanda',
  data = [],
  loading = false,
  error = null,
  pageSize = 20,
  onExportCSV,
  onBulkAction,
  onProductClick,
  showBulkActions = true,
  showFilters = true,
  compact = false,
}) => {
  const [filters, setFilters] = useState<FilterState>({
    productName: '',
    category: 'all',
    accuracyRange: 'all',
    trendDirection: 'all',
    confidenceLevel: 'all',
    dateRange: 'all',
  });
  
  const [sort, setSort] = useState<SortState>({
    field: 'forecast_date',
    order: 'desc',
  });

  const [selectedRows, setSelectedRows] = useState<React.Key[]>([]);
  const [currentPage, setCurrentPage] = useState(1);

  // Get product category (simplified mapping)
  const getProductCategory = useCallback((productName: string): string => {
    const name = productName.toLowerCase();
    if (name.includes('pan') || name.includes('croissant') || name.includes('magdalena')) return 'pan';
    if (name.includes('roscón') || name.includes('tarta') || name.includes('mazapán') || name.includes('polvorón')) return 'dulces';
    if (name.includes('empanada') || name.includes('churro')) return 'salados';
    if (name.includes('torrija') || name.includes('turrón')) return 'estacional';
    return 'pan';
  }, []);

  // Filter and sort data
  const filteredAndSortedData = useMemo(() => {
    let filtered = [...data];

    // Apply filters
    if (filters.productName) {
      filtered = filtered.filter(item =>
        item.inventory_product_id.toLowerCase().includes(filters.productName.toLowerCase())
      );
    }

    if (filters.category !== 'all') {
      filtered = filtered.filter(item => getProductCategory(item.inventory_product_id) === filters.category);
    }

    if (filters.accuracyRange !== 'all') {
      filtered = filtered.filter(item => {
        const accuracy = item.confidence_level || 0;
        switch (filters.accuracyRange) {
          case 'high': return accuracy >= 0.8;
          case 'medium': return accuracy >= 0.6 && accuracy < 0.8;
          case 'low': return accuracy < 0.6;
          default: return true;
        }
      });
    }

    if (filters.trendDirection !== 'all') {
      filtered = filtered.filter(item => {
        // Determine trend from predicted demand (simplified)
        const trend = item.predicted_demand > 50 ? 'increasing' : item.predicted_demand < 20 ? 'decreasing' : 'stable';
        return trend === filters.trendDirection;
      });
    }

    if (filters.confidenceLevel !== 'all') {
      filtered = filtered.filter(item => item.confidence_level >= filters.confidenceLevel);
    }

    if (filters.dateRange !== 'all') {
      const now = new Date();
      const filterDate = new Date();
      
      switch (filters.dateRange) {
        case 'today':
          filterDate.setHours(0, 0, 0, 0);
          break;
        case 'week':
          filterDate.setDate(now.getDate() - 7);
          break;
        case 'month':
          filterDate.setMonth(now.getMonth() - 1);
          break;
        case 'quarter':
          filterDate.setMonth(now.getMonth() - 3);
          break;
      }
      
      filtered = filtered.filter(item => new Date(item.forecast_date) >= filterDate);
    }

    // Apply sorting
    filtered.sort((a, b) => {
      let aValue: any;
      let bValue: any;

      switch (sort.field) {
        case 'inventory_product_id':
          aValue = a.inventory_product_id;
          bValue = b.inventory_product_id;
          break;
        case 'predicted_demand':
          aValue = a.predicted_demand;
          bValue = b.predicted_demand;
          break;
        case 'confidence_level':
          aValue = a.confidence_level || 0;
          bValue = b.confidence_level || 0;
          break;
        case 'forecast_date':
          aValue = new Date(a.forecast_date);
          bValue = new Date(b.forecast_date);
          break;
        default:
          return 0;
      }

      if (aValue < bValue) return sort.order === 'asc' ? -1 : 1;
      if (aValue > bValue) return sort.order === 'asc' ? 1 : -1;
      return 0;
    });

    return filtered;
  }, [data, filters, sort, getProductCategory]);

  // Paginated data
  const paginatedData = useMemo(() => {
    const startIndex = (currentPage - 1) * pageSize;
    return filteredAndSortedData.slice(startIndex, startIndex + pageSize);
  }, [filteredAndSortedData, currentPage, pageSize]);

  // Handle sort change
  const handleSort = useCallback((field: string, order: 'asc' | 'desc' | null) => {
    if (order === null) {
      setSort({ field: 'forecast_date', order: 'desc' });
    } else {
      setSort({ field, order });
    }
  }, []);

  // Handle filter change
  const handleFilterChange = useCallback((key: keyof FilterState, value: any) => {
    setFilters(prev => ({ ...prev, [key]: value }));
    setCurrentPage(1); // Reset to first page when filtering
  }, []);

  // Handle bulk actions
  const handleBulkAction = useCallback((action: string) => {
    const selectedData = filteredAndSortedData.filter(item => 
      selectedRows.includes(item.id)
    );
    onBulkAction?.(action, selectedData);
  }, [filteredAndSortedData, selectedRows, onBulkAction]);

  // Calculate accuracy percentage and trend
  const getAccuracyInfo = useCallback((item: ForecastResponse) => {
    const accuracy = item.confidence_level || 0;
    const percentage = (accuracy * 100).toFixed(1);
    
    let variant: 'success' | 'warning' | 'danger' = 'success';
    if (accuracy < 0.6) variant = 'danger';
    else if (accuracy < 0.8) variant = 'warning';
    
    return { percentage, variant };
  }, []);

  // Get trend info
  const getTrendInfo = useCallback((item: ForecastResponse) => {
    // Simplified trend calculation
    const trend = item.predicted_demand > 50 ? 'increasing' : item.predicted_demand < 20 ? 'decreasing' : 'stable';
    
    return {
      direction: trend,
      label: SPANISH_TRENDS[trend],
      color: TREND_COLORS[trend],
      icon: TREND_ICONS[trend],
    };
  }, []);

  // Table columns
  const columns: TableColumn<ForecastResponse>[] = useMemo(() => {
    const baseColumns: TableColumn<ForecastResponse>[] = [
      {
        key: 'inventory_product_id',
        title: 'Producto',
        dataIndex: 'inventory_product_id',
        sortable: true,
        width: compact ? 120 : 160,
        render: (value: string, record: ForecastResponse) => (
          <div className="flex items-center gap-2">
            <button
              onClick={() => onProductClick?.(value)}
              className="font-medium text-text-primary hover:text-color-primary transition-colors duration-150"
            >
              {value}
            </button>
            <Badge variant="ghost" size="sm">
              {getProductCategory(value)}
            </Badge>
          </div>
        ),
      },
      {
        key: 'predicted_demand',
        title: 'Demanda Predicha',
        dataIndex: 'predicted_demand',
        sortable: true,
        align: 'right' as const,
        width: compact ? 100 : 120,
        render: (value: number) => (
          <div className="font-semibold text-[var(--color-success)]">
            {value.toFixed(0)}
          </div>
        ),
      },
      {
        key: 'confidence_level',
        title: 'Confianza',
        dataIndex: 'confidence_level',
        sortable: true,
        align: 'center' as const,
        width: 80,
        render: (value: number | undefined, record: ForecastResponse) => {
          const { percentage, variant } = getAccuracyInfo(record);
          return (
            <Badge variant={variant} size="sm">
              {percentage}%
            </Badge>
          );
        },
      },
      {
        key: 'trend',
        title: 'Tendencia',
        align: 'center' as const,
        width: compact ? 80 : 100,
        render: (_, record: ForecastResponse) => {
          const trend = getTrendInfo(record);
          return (
            <div className="flex items-center justify-center gap-1">
              <span className="text-lg">{trend.icon}</span>
              <span className={clsx('text-xs font-medium', trend.color)}>
                {compact ? '' : trend.label}
              </span>
            </div>
          );
        },
      },
      {
        key: 'confidence_interval',
        title: 'Intervalo de Confianza',
        align: 'center' as const,
        width: compact ? 120 : 140,
        render: (_, record: ForecastResponse) => (
          <div className="text-sm text-text-secondary">
            {record.confidence_lower.toFixed(0)} - {record.confidence_upper.toFixed(0)}
            <div className="text-xs text-text-tertiary">
              ({(record.confidence_level * 100).toFixed(0)}%)
            </div>
          </div>
        ),
      },
    ];

    if (!compact) {
      baseColumns.push(
        {
          key: 'forecast_date',
          title: 'Fecha de Predicción',
          dataIndex: 'forecast_date',
          sortable: true,
          width: 120,
          render: (value: string) => (
            <div className="text-sm">
              {new Date(value).toLocaleDateString('es-ES', {
                day: 'numeric',
                month: 'short',
                year: '2-digit',
              })}
            </div>
          ),
        },
        {
          key: 'model_version',
          title: 'Modelo',
          dataIndex: 'model_version',
          width: 80,
          render: (value: string) => (
            <Badge variant="outlined" size="sm">
              v{value}
            </Badge>
          ),
        }
      );
    }

    return baseColumns;
  }, [compact, onProductClick, getProductCategory, getAccuracyInfo, getTrendInfo]);

  // Loading state
  if (loading) {
    return (
      <Card className={className}>
        <CardHeader>
          <h3 className="text-lg font-semibold text-text-primary">{title}</h3>
        </CardHeader>
        <CardBody>
          <div className="flex items-center justify-center h-64">
            <div className="flex items-center space-x-2">
              <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-color-primary"></div>
              <span className="text-text-secondary">Cargando predicciones...</span>
            </div>
          </div>
        </CardBody>
      </Card>
    );
  }

  // Error state
  if (error) {
    return (
      <Card className={className} variant="outlined">
        <CardHeader>
          <h3 className="text-lg font-semibold text-text-primary">{title}</h3>
        </CardHeader>
        <CardBody>
          <div className="flex items-center justify-center h-64">
            <div className="text-center">
              <div className="text-red-500 mb-2">
                <svg className="w-12 h-12 mx-auto" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                  <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1} d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
                </svg>
              </div>
              <p className="text-text-secondary">{error}</p>
            </div>
          </div>
        </CardBody>
      </Card>
    );
  }

  return (
    <Card className={className}>
      <CardHeader>
        <div className="flex items-center justify-between flex-wrap gap-4">
          <div className="flex items-center gap-3">
            <h3 className="text-lg font-semibold text-text-primary">{title}</h3>
            <Badge variant="ghost">
              {filteredAndSortedData.length} predicciones
            </Badge>
          </div>
          
          <div className="flex items-center gap-2">
            {onExportCSV && (
              <Button
                variant="ghost"
                size="sm"
                onClick={() => onExportCSV(filteredAndSortedData)}
              >
                📊 Exportar CSV
              </Button>
            )}
            
            {showBulkActions && selectedRows.length > 0 && (
              <div className="flex gap-1">
                <Button
                  variant="ghost"
                  size="sm"
                  onClick={() => handleBulkAction('production_plan')}
                >
                  📋 Plan de Producción
                </Button>
                <Button
                  variant="ghost"
                  size="sm"
                  onClick={() => handleBulkAction('inventory_alert')}
                >
                  🚨 Alertas de Inventario
                </Button>
              </div>
            )}
          </div>
        </div>
      </CardHeader>

      {showFilters && (
        <div className="px-6 py-4 border-b border-border-primary bg-bg-secondary">
          <div className="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-6 gap-4">
            <Input
              placeholder="Buscar producto..."
              value={filters.productName}
              onChange={(e) => handleFilterChange('productName', e.target.value)}
              className="text-sm"
            />
            
            <Select
              value={filters.category}
              onChange={(value) => handleFilterChange('category', value)}
              className="text-sm"
            >
              {BAKERY_CATEGORIES.map(cat => (
                <option key={cat.value} value={cat.value}>{cat.label}</option>
              ))}
            </Select>

            <Select
              value={filters.accuracyRange}
              onChange={(value) => handleFilterChange('accuracyRange', value)}
              className="text-sm"
            >
              <option value="all">Toda precisión</option>
              <option value="high">Alta (&gt;80%)</option>
              <option value="medium">Media (60-80%)</option>
              <option value="low">Baja (&lt;60%)</option>
            </Select>

            <Select
              value={filters.trendDirection}
              onChange={(value) => handleFilterChange('trendDirection', value)}
              className="text-sm"
            >
              <option value="all">Todas las tendencias</option>
              {Object.entries(SPANISH_TRENDS).map(([key, label]) => (
                <option key={key} value={key}>{label}</option>
              ))}
            </Select>

            <Select
              value={filters.confidenceLevel}
              onChange={(value) => handleFilterChange('confidenceLevel', value === 'all' ? 'all' : parseFloat(value))}
              className="text-sm"
            >
              <option value="all">Toda confianza</option>
              <option value="0.9">Alta (&gt;90%)</option>
              <option value="0.8">Media (&gt;80%)</option>
              <option value="0.7">Baja (&gt;70%)</option>
            </Select>

            <Select
              value={filters.dateRange}
              onChange={(value) => handleFilterChange('dateRange', value)}
              className="text-sm"
            >
              <option value="all">Todo el tiempo</option>
              <option value="today">Hoy</option>
              <option value="week">Última semana</option>
              <option value="month">Último mes</option>
              <option value="quarter">Último trimestre</option>
            </Select>
          </div>
        </div>
      )}

      <CardBody padding="none">
        <Table
          columns={columns}
          data={paginatedData}
          rowSelection={showBulkActions ? {
            selectedRowKeys: selectedRows,
            onSelectAll: (selected, selectedRows, changeRows) => {
              setSelectedRows(selected ? selectedRows.map(row => row.id) : []);
            },
            onSelect: (record, selected) => {
              setSelectedRows(prev => 
                selected 
                  ? [...prev, record.id]
                  : prev.filter(key => key !== record.id)
              );
            },
          } : undefined}
          pagination={{
            current: currentPage,
            pageSize,
            total: filteredAndSortedData.length,
            showSizeChanger: true,
            showTotal: (total, range) => 
              `${range[0]}-${range[1]} de ${total} predicciones`,
            onChange: (page, size) => {
              setCurrentPage(page);
            },
          }}
          sort={{
            field: sort.field,
            order: sort.order,
          }}
          onSort={handleSort}
          size={compact ? 'sm' : 'md'}
          hover={true}
          expandable={!compact ? {
            expandedRowRender: (record) => (
              <div className="p-4 bg-bg-tertiary">
                <div className="grid grid-cols-2 md:grid-cols-4 gap-4 text-sm">
                  <div>
                    <div className="font-medium text-text-primary mb-1">ID de Predicción</div>
                    <div className="text-text-secondary font-mono">{record.id}</div>
                  </div>
                  <div>
                    <div className="font-medium text-text-primary mb-1">Fecha de Creación</div>
                    <div className="text-text-secondary">
                      {new Date(record.created_at).toLocaleString('es-ES')}
                    </div>
                  </div>
                  <div>
                    <div className="font-medium text-text-primary mb-1">Factores Externos</div>
                    <div className="text-text-secondary">
                      {Object.entries(record.external_factors_impact).length > 0 
                        ? Object.keys(record.external_factors_impact).join(', ')
                        : 'Ninguno'
                      }
                    </div>
                  </div>
                  <div>
                    <div className="font-medium text-text-primary mb-1">Componente Estacional</div>
                    <div className="text-text-secondary">
                      {record.seasonal_component 
                        ? (record.seasonal_component * 100).toFixed(1) + '%'
                        : 'N/A'
                      }
                    </div>
                  </div>
                </div>
              </div>
            ),
          } : undefined}
        />
      </CardBody>
    </Card>
  );
};

export default ForecastTable;