import React, { useMemo } from 'react';
import { clsx } from 'clsx';
import { Badge } from '../../ui';
import DashboardCard from './DashboardCard';

export interface KPIValue {
  current: number;
  previous?: number;
  target?: number;
  format: 'currency' | 'number' | 'percentage';
  prefix?: string;
  suffix?: string;
}

export interface KPITrend {
  direction: 'up' | 'down' | 'stable';
  value: number;
  isPositive: boolean;
  comparisonPeriod: string;
  description?: string;
}

export interface KPIThreshold {
  excellent: number;
  good: number;
  warning: number;
  critical: number;
}

export interface SparklineDataPoint {
  date: string;
  value: number;
  label?: string;
}

export interface KPIWidgetProps {
  title: string;
  subtitle?: string;
  value: KPIValue;
  trend?: KPITrend;
  
  // Visual configuration
  icon?: React.ReactNode;
  color?: 'blue' | 'green' | 'orange' | 'red' | 'purple' | 'indigo' | 'teal';
  variant?: 'default' | 'compact' | 'detailed' | 'chart';
  
  // Chart data
  sparklineData?: SparklineDataPoint[];
  showSparkline?: boolean;
  
  // Thresholds and status
  thresholds?: KPIThreshold;
  status?: 'excellent' | 'good' | 'warning' | 'critical' | 'neutral';
  
  // Comparison and context
  comparisonLabel?: string;
  contextInfo?: string;
  
  // Interactive features
  isLoading?: boolean;
  onRefresh?: () => void;
  onClick?: () => void;
  
  // Accessibility and styling
  className?: string;
  'aria-label'?: string;
}

// Predefined bakery KPI configurations
export const BAKERY_KPI_CONFIGS = {
  dailyRevenue: {
    title: 'Ingresos Hoy',
    subtitle: 'Ventas del día actual',
    icon: (
      <svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
        <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 8c-1.657 0-3 .895-3 2s1.343 2 3 2 3 .895 3 2-1.343 2-3 2m0-8c1.11 0 2.08.402 2.599 1M12 8V7m0 1v8m0 0v1m0-1c-1.11 0-2.08-.402-2.599-1M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
      </svg>
    ),
    color: 'green' as const,
    format: 'currency' as const
  },
  orderCount: {
    title: 'Pedidos',
    subtitle: 'Órdenes procesadas hoy',
    icon: (
      <svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
        <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5H7a2 2 0 00-2 2v10a2 2 0 002 2h8a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2" />
      </svg>
    ),
    color: 'blue' as const,
    format: 'number' as const
  },
  productivity: {
    title: 'Productividad',
    subtitle: 'Unidades producidas por hora',
    icon: (
      <svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
        <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M13 10V3L4 14h7v7l9-11h-7z" />
      </svg>
    ),
    color: 'orange' as const,
    format: 'number' as const,
    suffix: '/h'
  },
  stockLevel: {
    title: 'Nivel Stock',
    subtitle: 'Porcentaje de stock disponible',
    icon: (
      <svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
        <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M20 7l-8-4-8 4m16 0l-8 4m8-4v10l-8 4m0-10L4 7m8 4v10M4 7v10l8 4" />
      </svg>
    ),
    color: 'purple' as const,
    format: 'percentage' as const
  }
};

const formatValue = (value: number, format: KPIValue['format'], prefix?: string, suffix?: string): string => {
  let formatted: string;
  
  switch (format) {
    case 'currency':
      formatted = new Intl.NumberFormat('es-ES', {
        style: 'currency',
        currency: 'EUR',
        minimumFractionDigits: 0,
        maximumFractionDigits: 2
      }).format(value);
      break;
    
    case 'percentage':
      formatted = new Intl.NumberFormat('es-ES', {
        style: 'percent',
        minimumFractionDigits: 0,
        maximumFractionDigits: 1
      }).format(value / 100);
      break;
    
    case 'number':
    default:
      formatted = new Intl.NumberFormat('es-ES').format(value);
      break;
  }
  
  return `${prefix || ''}${formatted}${suffix || ''}`;
};

const calculateTrend = (current: number, previous: number): KPITrend => {
  // Handle undefined or null values
  if (current == null || previous == null || 
      typeof current !== 'number' || typeof previous !== 'number' ||
      isNaN(current) || isNaN(previous)) {
    return {
      direction: 'stable',
      value: 0,
      isPositive: true,
      comparisonPeriod: 'vs período anterior'
    };
  }

  const change = current - previous;
  const percentChange = previous !== 0 ? (change / previous) * 100 : 0;
  
  return {
    direction: change > 0 ? 'up' : change < 0 ? 'down' : 'stable',
    value: Math.abs(percentChange),
    isPositive: change >= 0,
    comparisonPeriod: 'vs período anterior'
  };
};

const getStatusColor = (status: KPIWidgetProps['status']) => {
  switch (status) {
    case 'excellent':
      return {
        bg: 'bg-[var(--color-success)]/10',
        text: 'text-[var(--color-success)]',
        border: 'border-[var(--color-success)]/20',
        icon: 'text-[var(--color-success)]'
      };
    case 'good':
      return {
        bg: 'bg-[var(--color-info)]/10',
        text: 'text-[var(--color-info)]',
        border: 'border-[var(--color-info)]/20',
        icon: 'text-[var(--color-info)]'
      };
    case 'warning':
      return {
        bg: 'bg-[var(--color-warning)]/10',
        text: 'text-[var(--color-warning)]',
        border: 'border-[var(--color-warning)]/20',
        icon: 'text-[var(--color-warning)]'
      };
    case 'critical':
      return {
        bg: 'bg-[var(--color-error)]/10',
        text: 'text-[var(--color-error)]',
        border: 'border-[var(--color-error)]/20',
        icon: 'text-[var(--color-error)]'
      };
    default:
      return {
        bg: 'bg-[var(--bg-tertiary)]',
        text: 'text-[var(--text-secondary)]',
        border: 'border-[var(--border-primary)]',
        icon: 'text-[var(--text-tertiary)]'
      };
  }
};

const SimpleSparkline: React.FC<{ data: SparklineDataPoint[]; color: string }> = ({ data, color }) => {
  const max = Math.max(...data.map(d => d.value));
  const min = Math.min(...data.map(d => d.value));
  const range = max - min;
  
  const points = data.map((point, index) => {
    const x = (index / (data.length - 1)) * 100;
    const y = range === 0 ? 50 : ((max - point.value) / range) * 100;
    return `${x},${y}`;
  }).join(' ');
  
  const colorClasses = {
    blue: 'stroke-[var(--color-info)]',
    green: 'stroke-[var(--color-success)]',
    orange: 'stroke-[var(--color-primary)]',
    red: 'stroke-[var(--color-error)]',
    purple: 'stroke-[var(--color-info)]',
    indigo: 'stroke-[var(--color-info)]',
    teal: 'stroke-[var(--color-success)]'
  };
  
  return (
    <div className="w-full h-12 mt-2">
      <svg
        width="100%"
        height="100%"
        viewBox="0 0 100 100"
        preserveAspectRatio="none"
        className="overflow-visible"
      >
        <polyline
          points={points}
          fill="none"
          strokeWidth="2"
          className={clsx(colorClasses[color as keyof typeof colorClasses] || colorClasses.blue)}
        />
      </svg>
    </div>
  );
};

const KPIWidget: React.FC<KPIWidgetProps> = ({
  title,
  subtitle,
  value,
  trend,
  icon,
  color = 'blue',
  variant = 'default',
  sparklineData,
  showSparkline = false,
  thresholds,
  status,
  comparisonLabel,
  contextInfo,
  isLoading = false,
  onRefresh,
  onClick,
  className,
  'aria-label': ariaLabel
}) => {
  // Calculate trend if not provided
  const calculatedTrend = useMemo(() => {
    if (trend) return trend;
    if (value.previous !== undefined) {
      return calculateTrend(value.current, value.previous);
    }
    return null;
  }, [trend, value.current, value.previous]);

  // Determine status based on thresholds
  const calculatedStatus = useMemo(() => {
    if (status) return status;
    if (!thresholds) return 'neutral';
    
    const { current } = value;
    if (current >= thresholds.excellent) return 'excellent';
    if (current >= thresholds.good) return 'good';
    if (current >= thresholds.warning) return 'warning';
    return 'critical';
  }, [status, thresholds, value.current]);

  const statusStyles = getStatusColor(calculatedStatus);
  const formattedValue = formatValue(value.current, value.format, value.prefix, value.suffix);
  const formattedTarget = value.target ? formatValue(value.target, value.format, value.prefix, value.suffix) : null;

  const colorClasses = {
    blue: 'text-[var(--color-info)]',
    green: 'text-[var(--color-success)]',
    orange: 'text-[var(--color-primary)]',
    red: 'text-[var(--color-error)]',
    purple: 'text-[var(--color-info)]',
    indigo: 'text-[var(--color-info)]',
    teal: 'text-[var(--color-success)]'
  };

  const renderTrendIcon = (direction: KPITrend['direction']) => {
    const iconClass = calculatedTrend?.isPositive ? 'text-[var(--color-success)]' : 'text-[var(--color-error)]';
    
    switch (direction) {
      case 'up':
        return (
          <svg className={clsx('w-4 h-4', iconClass)} fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M7 17l9.2-9.2M17 17V7H7" />
          </svg>
        );
      case 'down':
        return (
          <svg className={clsx('w-4 h-4', iconClass)} fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M17 7l-9.2 9.2M7 7v10h10" />
          </svg>
        );
      default:
        return (
          <svg className="w-4 h-4 text-[var(--text-tertiary)]" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M20 12H4" />
          </svg>
        );
    }
  };

  const renderCompactVariant = () => (
    <div className="flex items-center justify-between">
      <div className="flex items-center space-x-3">
        {icon && (
          <div className={clsx('p-2 rounded-lg', statusStyles.bg)}>
            <div className={clsx('w-5 h-5', statusStyles.icon)}>
              {icon}
            </div>
          </div>
        )}
        <div>
          <p className="text-sm font-medium text-[var(--text-primary)]">{title}</p>
          <p className="text-2xl font-bold text-[var(--text-primary)]">{formattedValue}</p>
        </div>
      </div>
      {calculatedTrend && (
        <div className="flex items-center space-x-1">
          {renderTrendIcon(calculatedTrend.direction)}
          <span className={clsx(
            'text-sm font-medium',
            calculatedTrend.isPositive ? 'text-[var(--color-success)]' : 'text-[var(--color-error)]'
          )}>
            {(calculatedTrend.value || 0).toFixed(1)}%
          </span>
        </div>
      )}
    </div>
  );

  const renderDetailedVariant = () => (
    <div className="space-y-4">
      {/* Header */}
      <div className="flex items-center justify-between">
        <div className="flex items-center space-x-3">
          {icon && (
            <div className={clsx('p-3 rounded-xl', statusStyles.bg)}>
              <div className={clsx('w-6 h-6', statusStyles.icon)}>
                {icon}
              </div>
            </div>
          )}
          <div>
            <h3 className="text-lg font-semibold text-[var(--text-primary)]">{title}</h3>
            {subtitle && (
              <p className="text-sm text-[var(--text-secondary)]">{subtitle}</p>
            )}
          </div>
        </div>
        {calculatedStatus !== 'neutral' && (
          <Badge variant={calculatedStatus === 'excellent' ? 'success' : calculatedStatus === 'critical' ? 'error' : 'warning'}>
            {calculatedStatus === 'excellent' ? 'Excelente' : 
             calculatedStatus === 'good' ? 'Bueno' : 
             calculatedStatus === 'warning' ? 'Atención' : 'Crítico'}
          </Badge>
        )}
      </div>

      {/* Value and trend */}
      <div className="space-y-2">
        <div className="flex items-baseline space-x-3">
          <span className="text-3xl font-bold text-[var(--text-primary)]">{formattedValue}</span>
          {calculatedTrend && (
            <div className="flex items-center space-x-1">
              {renderTrendIcon(calculatedTrend.direction)}
              <span className={clsx(
                'text-sm font-medium',
                calculatedTrend.isPositive ? 'text-[var(--color-success)]' : 'text-[var(--color-error)]'
              )}>
                {(calculatedTrend.value || 0).toFixed(1)}%
              </span>
              <span className="text-sm text-[var(--text-tertiary)]">
                {calculatedTrend.comparisonPeriod}
              </span>
            </div>
          )}
        </div>

        {formattedTarget && (
          <p className="text-sm text-[var(--text-secondary)]">
            Objetivo: <span className="font-medium">{formattedTarget}</span>
          </p>
        )}

        {contextInfo && (
          <p className="text-sm text-[var(--text-tertiary)]">{contextInfo}</p>
        )}
      </div>

      {/* Sparkline chart */}
      {showSparkline && sparklineData && sparklineData.length > 0 && (
        <div className="mt-4">
          <p className="text-xs text-[var(--text-tertiary)] mb-2">Tendencia últimos 7 días</p>
          <SimpleSparkline data={sparklineData} color={color} />
        </div>
      )}
    </div>
  );

  const renderDefaultVariant = () => (
    <div className="space-y-4">
      <div className="flex items-center justify-between">
        <div className="flex items-center space-x-3">
          {icon && (
            <div className={clsx('w-8 h-8', colorClasses[color])}>
              {icon}
            </div>
          )}
          <div>
            <h3 className="font-medium text-[var(--text-primary)]">{title}</h3>
            {subtitle && (
              <p className="text-sm text-[var(--text-secondary)]">{subtitle}</p>
            )}
          </div>
        </div>
      </div>

      <div className="space-y-2">
        <div className="flex items-baseline space-x-2">
          <span className="text-2xl font-bold text-[var(--text-primary)]">{formattedValue}</span>
          {calculatedTrend && (
            <div className="flex items-center space-x-1">
              {renderTrendIcon(calculatedTrend.direction)}
              <span className={clsx(
                'text-sm',
                calculatedTrend.isPositive ? 'text-[var(--color-success)]' : 'text-[var(--color-error)]'
              )}>
                {(calculatedTrend.value || 0).toFixed(1)}%
              </span>
            </div>
          )}
        </div>

        {comparisonLabel && (
          <p className="text-sm text-[var(--text-tertiary)]">{comparisonLabel}</p>
        )}
      </div>
    </div>
  );

  const renderContent = () => {
    switch (variant) {
      case 'compact':
        return renderCompactVariant();
      case 'detailed':
        return renderDetailedVariant();
      case 'chart':
        return renderDetailedVariant();
      default:
        return renderDefaultVariant();
    }
  };

  return (
    <DashboardCard
      variant="metric"
      isLoading={isLoading}
      onRefresh={onRefresh}
      onClick={onClick}
      interactive={!!onClick}
      className={className}
      aria-label={ariaLabel || `${title}: ${formattedValue}`}
    >
      {renderContent()}
    </DashboardCard>
  );
};

KPIWidget.displayName = 'KPIWidget';

export default KPIWidget;