import React, { useState, useMemo, useEffect } from 'react';
import { motion, AnimatePresence } from 'framer-motion';
import { TrendingUp, TrendingDown, AlertTriangle, Calculator, RotateCcw, Info } from 'lucide-react';

interface SimuladorPreciosProps {
  ejercicioId: string;
  onComplete?: (puntuacion: number) => void;
}

interface CurvaParams {
  pendienteDemanda: number;
  interceptoDemanda: number;
  pendienteOferta: number;
  interceptoOferta: number;
}

const DEFAULT_PARAMS: CurvaParams = {
  pendienteDemanda: -1.5,
  interceptoDemanda: 90,
  pendienteOferta: 1.2,
  interceptoOferta: 10
};

const calcularEquilibrio = (params: CurvaParams) => {
  const { pendienteDemanda, interceptoDemanda, pendienteOferta, interceptoOferta } = params;
  // Pd = Po => a + b*Q = c + d*Q
  const Q = (interceptoOferta - interceptoDemanda) / (pendienteDemanda - pendienteOferta);
  const P = interceptoDemanda + pendienteDemanda * Q;
  return { Q: Math.max(0, Q), P: Math.max(0, P) };
};

const calcularCantidadEnPrecio = (precio: number, params: CurvaParams) => {
  // P = a + b*Q => Q = (P - a) / b
  const Qd = (precio - params.interceptoDemanda) / params.pendienteDemanda;
  const Qo = (precio - params.interceptoOferta) / params.pendienteOferta;
  return { Qd: Math.max(0, Qd), Qo: Math.max(0, Qo) };
};

export const SimuladorPrecios: React.FC<SimuladorPreciosProps> = ({ onComplete, ejercicioId: _ejercicioId }) => {
  const [params, _setParams] = useState<CurvaParams>(DEFAULT_PARAMS);
  const [precioMaximo, setPrecioMaximo] = useState<number | null>(null);
  const [precioMinimo, setPrecioMinimo] = useState<number | null>(null);
  const [showInfo, setShowInfo] = useState(true);
  const [startTime] = useState(Date.now());
  const [hasInteracted, setHasInteracted] = useState(false);

  const equilibrio = useMemo(() => calcularEquilibrio(params), [params]);

  const analisis = useMemo(() => {
    if (precioMaximo !== null && precioMaximo < equilibrio.P) {
      const { Qd, Qo } = calcularCantidadEnPrecio(precioMaximo, params);
      const excesoDemanda = Qd - Qo;
      const cantidadTransada = Qo;
      
      // Pérdida de peso muerto: área del triángulo
      const base = equilibrio.Q - cantidadTransada;
      const altura = precioMaximo - (params.interceptoOferta + params.pendienteOferta * cantidadTransada);
      const deadweightLoss = 0.5 * base * altura;

      return {
        tipo: 'precio-maximo' as const,
        excesoDemanda: Math.max(0, excesoDemanda),
        excesoOferta: 0,
        cantidadTransada,
        deadweightLoss: Math.max(0, deadweightLoss),
        mensaje: 'Precio máximo crea escasez (exceso de demanda)'
      };
    }

    if (precioMinimo !== null && precioMinimo > equilibrio.P) {
      const { Qd, Qo } = calcularCantidadEnPrecio(precioMinimo, params);
      const excesoOferta = Qo - Qd;
      const cantidadTransada = Qd;

      const base = equilibrio.Q - cantidadTransada;
      const altura = (params.interceptoDemanda + params.pendienteDemanda * cantidadTransada) - precioMinimo;
      const deadweightLoss = 0.5 * base * altura;

      return {
        tipo: 'precio-minimo' as const,
        excesoDemanda: 0,
        excesoOferta: Math.max(0, excesoOferta),
        cantidadTransada,
        deadweightLoss: Math.max(0, deadweightLoss),
        mensaje: 'Precio mínimo crea superávit (exceso de oferta)'
      };
    }

    return {
      tipo: 'equilibrio' as const,
      excesoDemanda: 0,
      excesoOferta: 0,
      cantidadTransada: equilibrio.Q,
      deadweightLoss: 0,
      mensaje: 'Mercado en equilibrio'
    };
  }, [precioMaximo, precioMinimo, equilibrio, params]);

  useEffect(() => {
    if (hasInteracted && (precioMaximo !== null || precioMinimo !== null)) {
      const timer = setTimeout(() => {
        if (onComplete) {
          onComplete(100);
        }
      }, 5000);
      return () => clearTimeout(timer);
    }
  }, [hasInteracted, precioMaximo, precioMinimo, startTime, onComplete]);

  const reset = () => {
    setPrecioMaximo(null);
    setPrecioMinimo(null);
    setHasInteracted(false);
  };

  // Generar puntos para las curvas
  const generateCurvePoints = () => {
    const points = [];
    for (let Q = 0; Q <= 60; Q += 2) {
      const Pd = params.interceptoDemanda + params.pendienteDemanda * Q;
      const Po = params.interceptoOferta + params.pendienteOferta * Q;
      points.push({ Q, Pd: Math.max(0, Pd), Po: Math.max(0, Po) });
    }
    return points;
  };

  const curvePoints = generateCurvePoints();

  // Escalar para SVG
  const scaleX = (Q: number) => 50 + (Q / 60) * 400;
  const scaleY = (P: number) => 350 - (P / 100) * 300;

  const demandaPath = curvePoints.map((p, i) => 
    `${i === 0 ? 'M' : 'L'} ${scaleX(p.Q)} ${scaleY(p.Pd)}`
  ).join(' ');

  const ofertaPath = curvePoints.map((p, i) => 
    `${i === 0 ? 'M' : 'L'} ${scaleX(p.Q)} ${scaleY(p.Po)}`
  ).join(' ');

  return (
    <div className="w-full max-w-5xl mx-auto p-6 bg-white rounded-xl shadow-lg">
      <div className="mb-6">
        <h2 className="text-2xl font-bold text-gray-800 flex items-center gap-3">
          <Calculator className="w-8 h-8 text-purple-600" />
          Simulador de Precios Intervenidos
        </h2>
        <p className="text-gray-600 mt-2">
          Experimenta con precios máximos y mínimos para ver cómo afectan el equilibrio de mercado.
        </p>
      </div>

      {showInfo && (
        <motion.div
          initial={{ opacity: 0, y: -20 }}
          animate={{ opacity: 1, y: 0 }}
          className="mb-6 p-4 bg-blue-50 border border-blue-200 rounded-lg flex items-start gap-3"
        >
          <Info className="w-5 h-5 text-blue-600 flex-shrink-0 mt-0.5" />
          <div className="flex-1">
            <h4 className="font-semibold text-blue-800 mb-1">Cómo usar:</h4>
            <ul className="text-sm text-blue-700 space-y-1">
              <li>• Ajusta los sliders para establecer un precio máximo o mínimo</li>
              <li>• Observa cómo cambian las cantidades demandadas y ofrecidas</li>
              <li>• Identifica escasez (exceso de demanda) o superávit (exceso de oferta)</li>
              <li>• La pérdida de peso muerto representa la ineficiencia creada</li>
            </ul>
          </div>
          <button 
            onClick={() => setShowInfo(false)}
            className="text-blue-600 hover:text-blue-800"
          >
            ×
          </button>
        </motion.div>
      )}

      <div className="grid md:grid-cols-2 gap-6">
        <div className="bg-gray-50 rounded-lg p-4">
          <div className="flex justify-between items-center mb-4">
            <h3 className="font-semibold text-gray-700">Gráfico de Mercado</h3>
            <button
              onClick={reset}
              className="p-2 text-gray-500 hover:text-purple-600 transition-colors"
            >
              <RotateCcw className="w-4 h-4" />
            </button>
          </div>
          
          <svg width="500" height="400" className="w-full">
            {/* Grid */}
            {Array.from({ length: 11 }).map((_, i) => (
              <g key={i}>
                <line
                  x1={50 + (i * 400) / 10}
                  y1={50}
                  x2={50 + (i * 400) / 10}
                  y2={350}
                  stroke="#e5e7eb"
                  strokeWidth="1"
                />
                <line
                  x1={50}
                  y1={50 + (i * 300) / 10}
                  x2={450}
                  y2={50 + (i * 300) / 10}
                  stroke="#e5e7eb"
                  strokeWidth="1"
                />
              </g>
            ))}

            {/* Ejes */}
            <line x1="50" y1="350" x2="450" y2="350" stroke="#374151" strokeWidth="2" />
            <line x1="50" y1="50" x2="50" y2="350" stroke="#374151" strokeWidth="2" />

            {/* Labels */}
            <text x="250" y="385" textAnchor="middle" className="text-sm fill-gray-600">Cantidad</text>
            <text x="15" y="200" textAnchor="middle" transform="rotate(-90, 15, 200)" className="text-sm fill-gray-600">Precio</text>

            {/* Curva de Demanda */}
            <path d={demandaPath} fill="none" stroke="#3b82f6" strokeWidth="3" />
            <text x="420" y={scaleY(15)} className="text-sm fill-blue-600 font-medium">D</text>

            {/* Curva de Oferta */}
            <path d={ofertaPath} fill="none" stroke="#22c55e" strokeWidth="3" />
            <text x="420" y={scaleY(80)} className="text-sm fill-green-600 font-medium">S</text>

            {/* Punto de equilibrio */}
            <circle
              cx={scaleX(equilibrio.Q)}
              cy={scaleY(equilibrio.P)}
              r="6"
              fill="#8b5cf6"
              stroke="white"
              strokeWidth="2"
            />
            <text x={scaleX(equilibrio.Q) + 10} y={scaleY(equilibrio.P)} className="text-xs fill-purple-600">
              E
            </text>

            {/* Línea de precio máximo */}
            {precioMaximo !== null && (
              <g>
                <line
                  x1="50"
                  y1={scaleY(precioMaximo)}
                  x2="450"
                  y2={scaleY(precioMaximo)}
                  stroke="#ef4444"
                  strokeWidth="2"
                  strokeDasharray="5,5"
                />
                <text x="460" y={scaleY(precioMaximo)} className="text-xs fill-red-500">Pmáx</text>
                
                {/* Zona de escasez */}
                {analisis.excesoDemanda > 0 && (
                  <polygon
                    points={`
                      ${scaleX(analisis.cantidadTransada)} ${scaleY(precioMaximo)}
                      ${scaleX(analisis.cantidadTransada + analisis.excesoDemanda)} ${scaleY(precioMaximo)}
                    `}
                    fill="#fef3c7"
                    opacity="0.5"
                  />
                )}
              </g>
            )}

            {/* Línea de precio mínimo */}
            {precioMinimo !== null && (
              <g>
                <line
                  x1="50"
                  y1={scaleY(precioMinimo)}
                  x2="450"
                  y2={scaleY(precioMinimo)}
                  stroke="#f59e0b"
                  strokeWidth="2"
                  strokeDasharray="5,5"
                />
                <text x="460" y={scaleY(precioMinimo)} className="text-xs fill-amber-500">Pmín</text>
              </g>
            )}

            {/* Indicador de pérdida de peso muerto */}
            {analisis.deadweightLoss > 0 && (
              <motion.text
                initial={{ opacity: 0 }}
                animate={{ opacity: 1 }}
                x={scaleX(equilibrio.Q / 2)}
                y={scaleY((equilibrio.P + (precioMaximo || precioMinimo || 0)) / 2)}
                textAnchor="middle"
                className="text-xs fill-red-600 font-medium"
              >
                Pérdida de peso muerto
              </motion.text>
            )}
          </svg>
        </div>

        <div className="space-y-6">
          <div className="bg-gray-50 rounded-lg p-4">
            <h3 className="font-semibold text-gray-700 mb-4">Controles de Precio</h3>
            
            <div className="space-y-4">
              <div>
                <label className="block text-sm font-medium text-gray-700 mb-2">
                  Precio Máximo (Pmáx)
                </label>
                <input
                  type="range"
                  min="0"
                  max={Math.round(equilibrio.P)}
                  value={precioMaximo ?? Math.round(equilibrio.P)}
                  onChange={(e) => {
                    setPrecioMaximo(Number(e.target.value) || null);
                    setPrecioMinimo(null);
                    setHasInteracted(true);
                  }}
                  className="w-full accent-red-500"
                />
                <div className="flex justify-between text-sm text-gray-500 mt-1">
                  <span>$0</span>
                  <span className="font-medium text-red-600">
                    {precioMaximo !== null ? `$${precioMaximo}` : 'Desactivado'}
                  </span>
                  <span>${Math.round(equilibrio.P)}</span>
                </div>
              </div>

              <div className="border-t border-gray-200 pt-4">
                <label className="block text-sm font-medium text-gray-700 mb-2">
                  Precio Mínimo (Pmín)
                </label>
                <input
                  type="range"
                  min={Math.round(equilibrio.P)}
                  max="100"
                  value={precioMinimo ?? Math.round(equilibrio.P)}
                  onChange={(e) => {
                    setPrecioMinimo(Number(e.target.value) || null);
                    setPrecioMaximo(null);
                    setHasInteracted(true);
                  }}
                  className="w-full accent-amber-500"
                />
                <div className="flex justify-between text-sm text-gray-500 mt-1">
                  <span>${Math.round(equilibrio.P)}</span>
                  <span className="font-medium text-amber-600">
                    {precioMinimo !== null ? `$${precioMinimo}` : 'Desactivado'}
                  </span>
                  <span>$100</span>
                </div>
              </div>
            </div>
          </div>

          <AnimatePresence mode="wait">
            <motion.div
              key={analisis.tipo}
              initial={{ opacity: 0, y: 20 }}
              animate={{ opacity: 1, y: 0 }}
              exit={{ opacity: 0, y: -20 }}
              className={`p-4 rounded-lg border ${
                analisis.tipo === 'equilibrio' 
                  ? 'bg-green-50 border-green-200' 
                  : analisis.tipo === 'precio-maximo'
                  ? 'bg-red-50 border-red-200'
                  : 'bg-amber-50 border-amber-200'
              }`}
            >
              <div className="flex items-center gap-2 mb-3">
                {analisis.tipo === 'equilibrio' ? (
                  <TrendingUp className="w-5 h-5 text-green-600" />
                ) : analisis.tipo === 'precio-maximo' ? (
                  <TrendingDown className="w-5 h-5 text-red-600" />
                ) : (
                  <AlertTriangle className="w-5 h-5 text-amber-600" />
                )}
                <h4 className={`font-semibold ${
                  analisis.tipo === 'equilibrio' 
                    ? 'text-green-800' 
                    : analisis.tipo === 'precio-maximo'
                    ? 'text-red-800'
                    : 'text-amber-800'
                }`}>
                  {analisis.mensaje}
                </h4>
              </div>

              <div className="grid grid-cols-2 gap-3 text-sm">
                <div className="bg-white rounded p-2">
                  <span className="text-gray-500">Precio de equilibrio:</span>
                  <p className="font-semibold text-gray-800">${equilibrio.P.toFixed(1)}</p>
                </div>
                <div className="bg-white rounded p-2">
                  <span className="text-gray-500">Cantidad de equilibrio:</span>
                  <p className="font-semibold text-gray-800">{equilibrio.Q.toFixed(1)} unidades</p>
                </div>
                {precioMaximo !== null && (
                  <div className="bg-white rounded p-2">
                    <span className="text-red-500">Precio máximo:</span>
                    <p className="font-semibold text-gray-800">${precioMaximo}</p>
                  </div>
                )}
                {precioMinimo !== null && (
                  <div className="bg-white rounded p-2">
                    <span className="text-amber-500">Precio mínimo:</span>
                    <p className="font-semibold text-gray-800">${precioMinimo}</p>
                  </div>
                )}
                {analisis.excesoDemanda > 0 && (
                  <div className="bg-red-100 rounded p-2 col-span-2">
                    <span className="text-red-700">Exceso de demanda (escasez):</span>
                    <p className="font-semibold text-red-800">{analisis.excesoDemanda.toFixed(1)} unidades</p>
                  </div>
                )}
                {analisis.excesoOferta > 0 && (
                  <div className="bg-amber-100 rounded p-2 col-span-2">
                    <span className="text-amber-700">Exceso de oferta (superávit):</span>
                    <p className="font-semibold text-amber-800">{analisis.excesoOferta.toFixed(1)} unidades</p>
                  </div>
                )}
                {analisis.deadweightLoss > 0 && (
                  <div className="bg-red-100 rounded p-2 col-span-2">
                    <span className="text-red-700">Pérdida de peso muerto:</span>
                    <p className="font-semibold text-red-800">${analisis.deadweightLoss.toFixed(1)}</p>
                  </div>
                )}
              </div>
            </motion.div>
          </AnimatePresence>

          <div className="p-4 bg-purple-50 rounded-lg">
            <h4 className="font-semibold text-purple-800 mb-2">Resultado</h4>
            <p className="text-sm text-purple-700">
              Cantidad transada: <span className="font-bold">{analisis.cantidadTransada.toFixed(1)} unidades</span>
            </p>
            <p className="text-xs text-purple-600 mt-1">
              {analisis.tipo === 'precio-maximo' 
                ? 'Con precio máximo, los vendedores quieren vender menos cantidad.'
                : analisis.tipo === 'precio-minimo'
                ? 'Con precio mínimo, los compradores quieren comprar menos cantidad.'
                : 'En equilibrio, la cantidad demandada = cantidad ofrecida.'}
            </p>
          </div>
        </div>
      </div>
    </div>
  );
};

export default SimuladorPrecios;
