import { useState, useEffect, useCallback } from 'react';
import { Button } from '../../ui/Button';
import { Input } from '../../ui/Input';
import { Card, CardHeader } from '../../ui/Card';

type ElasticidadTipo = 'precio' | 'ingreso' | 'cruzada';

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

export function CalculadoraElasticidad({ ejercicioId: _ejercicioId, onComplete }: CalculadoraElasticidadProps) {
  const [tipo, setTipo] = useState<ElasticidadTipo>('precio');
  const [p1, setP1] = useState('');
  const [p2, setP2] = useState('');
  const [q1, setQ1] = useState('');
  const [q2, setQ2] = useState('');
  const [error, setError] = useState('');

  const [resultado, setResultado] = useState<{
    deltaQ: number;
    deltaP: number;
    qPromedio: number;
    pPromedio: number;
    porcentajeQ: number;
    porcentajeP: number;
    elasticidad: number;
    interpretacion: string;
  } | null>(null);

  const calcular = useCallback(() => {
    const numP1 = parseFloat(p1);
    const numP2 = parseFloat(p2);
    const numQ1 = parseFloat(q1);
    const numQ2 = parseFloat(q2);

    if (isNaN(numP1) || isNaN(numP2) || isNaN(numQ1) || isNaN(numQ2)) {
      setError('Todos los valores deben ser numéricos');
      setResultado(null);
      return;
    }

    if (numP1 === numP2 && tipo === 'precio') {
      setError('P1 y P2 no pueden ser iguales para calcular elasticidad');
      setResultado(null);
      return;
    }

    setError('');

    // Método del punto medio
    const deltaQ = numQ2 - numQ1;
    const deltaP = numP2 - numP1;
    const qPromedio = (numQ1 + numQ2) / 2;
    const pPromedio = (numP1 + numP2) / 2;
    
    const porcentajeQ = (deltaQ / qPromedio) * 100;
    const porcentajeP = (deltaP / pPromedio) * 100;
    const elasticidad = porcentajeQ / porcentajeP;

    let interpretacion = '';
    const absE = Math.abs(elasticidad);
    
    if (tipo === 'precio') {
      if (absE > 1) interpretacion = 'Demanda ELÁSTICA: |E| > 1. El consumo responde más que proporcionalmente al cambio de precio.';
      else if (absE < 1) interpretacion = 'Demanda INELÁSTICA: |E| < 1. El consumo responde menos que proporcionalmente al cambio de precio.';
      else interpretacion = 'Demanda UNITARIA: |E| = 1. El consumo responde exactamente proporcional al cambio de precio.';
    } else if (tipo === 'ingreso') {
      if (elasticidad > 1) interpretacion = 'Bien de LUJO: Ei > 1. El gasto en el bien aumenta más que proporcionalmente al ingreso.';
      else if (elasticidad > 0 && elasticidad < 1) interpretacion = 'Bien NECESARIO: 0 < Ei < 1. El gasto aumenta menos que proporcionalmente al ingreso.';
      else if (elasticidad < 0) interpretacion = 'Bien INFERIOR: Ei < 0. El consumo disminuye cuando aumenta el ingreso.';
      else interpretacion = 'Bien NEUTRO: Ei = 0. El consumo no cambia con el ingreso.';
    } else {
      if (elasticidad > 0) interpretacion = 'BIENES SUSTITUTOS: Ecr > 0. El aumento del precio de Y aumenta la demanda de X.';
      else if (elasticidad < 0) interpretacion = 'BIENES COMPLEMENTARIOS: Ecr < 0. El aumento del precio de Y disminuye la demanda de X.';
      else interpretacion = 'BIENES INDEPENDIENTES: Ecr = 0. No existe relación entre los bienes.';
    }

    setResultado({
      deltaQ,
      deltaP,
      qPromedio,
      pPromedio,
      porcentajeQ,
      porcentajeP,
      elasticidad,
      interpretacion
    });

    if (onComplete) {
      onComplete(100);
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [p1, p2, q1, q2, tipo]);

  useEffect(() => {
    if (p1 && p2 && q1 && q2) {
      calcular();
    }
  }, [p1, p2, q1, q2, tipo, calcular]);

  const getLabelPrecio = () => {
    if (tipo === 'cruzada') return 'P1/Py1 (Precio del otro bien)';
    return 'P1 (Precio inicial)';
  };

  const getLabelCantidad = () => {
    if (tipo === 'ingreso') return 'Q1 (Cantidad con ingreso I1)';
    return 'Q1 (Cantidad inicial)';
  };

  const tipoLabels: Record<ElasticidadTipo, string> = {
    precio: 'Elasticidad Precio de la Demanda',
    ingreso: 'Elasticidad Ingreso',
    cruzada: 'Elasticidad Cruzada'
  };

  return (
    <Card className="max-w-2xl mx-auto">
      <CardHeader 
        title="Calculadora de Elasticidad"
        subtitle="Método del punto medio (Arco)"
      />

      <div className="space-y-6">
        <div className="flex flex-wrap gap-2">
          {(['precio', 'ingreso', 'cruzada'] as ElasticidadTipo[]).map((t) => (
            <Button
              key={t}
              variant={tipo === t ? 'primary' : 'outline'}
              size="sm"
              onClick={() => setTipo(t)}
            >
              {tipoLabels[t]}
            </Button>
          ))}
        </div>

        <div className="bg-blue-50 p-4 rounded-lg">
          <p className="text-sm text-blue-800 font-medium">{tipoLabels[tipo]}</p>
          <p className="text-xs text-blue-600 mt-1">
            {tipo === 'precio' && 'Mide la sensibilidad de la cantidad demandada ante cambios en el precio del propio bien'}
            {tipo === 'ingreso' && 'Mide la sensibilidad de la cantidad demandada ante cambios en el ingreso del consumidor'}
            {tipo === 'cruzada' && 'Mide la sensibilidad de la cantidad demandada de X ante cambios en el precio de Y'}
          </p>
        </div>

        <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
          <Input
            label={getLabelCantidad()}
            type="number"
            value={q1}
            onChange={(e) => setQ1(e.target.value)}
            placeholder="Ej: 100"
          />
          <Input
            label={tipo === 'ingreso' ? 'Q2 (Cantidad con ingreso I2)' : 'Q2 (Cantidad final)'}
            type="number"
            value={q2}
            onChange={(e) => setQ2(e.target.value)}
            placeholder="Ej: 80"
          />
          <Input
            label={getLabelPrecio()}
            type="number"
            value={p1}
            onChange={(e) => setP1(e.target.value)}
            placeholder="Ej: 10"
          />
          <Input
            label={tipo === 'cruzada' ? 'P2/Py2 (Precio final del otro bien)' : 'P2 (Precio final)'}
            type="number"
            value={p2}
            onChange={(e) => setP2(e.target.value)}
            placeholder="Ej: 12"
          />
        </div>

        {error && (
          <p className="text-red-500 text-sm bg-red-50 p-3 rounded-lg">{error}</p>
        )}

        {resultado && (
          <div className="space-y-4">
            <div className="bg-gray-50 p-4 rounded-lg space-y-3">
              <h4 className="font-semibold text-gray-700">Desarrollo paso a paso:</h4>
              
              <div className="space-y-2 text-sm">
                <div className="bg-white p-3 rounded border">
                  <p className="font-medium text-gray-600">Paso 1: Calcular cambios</p>
                  <p className="font-mono text-gray-800">
                    ΔQ = Q2 - Q1 = {q2} - {q1} = {resultado.deltaQ.toFixed(2)}
                  </p>
                  <p className="font-mono text-gray-800">
                    ΔP = P2 - P1 = {p2} - {p1} = {resultado.deltaP.toFixed(2)}
                  </p>
                </div>

                <div className="bg-white p-3 rounded border">
                  <p className="font-medium text-gray-600">Paso 2: Calcular promedios</p>
                  <p className="font-mono text-gray-800">
                    Q̄ = (Q1 + Q2) / 2 = ({q1} + {q2}) / 2 = {resultado.qPromedio.toFixed(2)}
                  </p>
                  <p className="font-mono text-gray-800">
                    P̄ = (P1 + P2) / 2 = ({p1} + {p2}) / 2 = {resultado.pPromedio.toFixed(2)}
                  </p>
                </div>

                <div className="bg-white p-3 rounded border">
                  <p className="font-medium text-gray-600">Paso 3: Calcular variaciones porcentuales</p>
                  <p className="font-mono text-gray-800">
                    %ΔQ = (ΔQ / Q̄) × 100 = ({resultado.deltaQ.toFixed(2)} / {resultado.qPromedio.toFixed(2)}) × 100 = {resultado.porcentajeQ.toFixed(2)}%
                  </p>
                  <p className="font-mono text-gray-800">
                    %ΔP = (ΔP / P̄) × 100 = ({resultado.deltaP.toFixed(2)} / {resultado.pPromedio.toFixed(2)}) × 100 = {resultado.porcentajeP.toFixed(2)}%
                  </p>
                </div>

                <div className="bg-blue-100 p-3 rounded border border-blue-300">
                  <p className="font-medium text-blue-800">Paso 4: Calcular elasticidad</p>
                  <p className="font-mono text-blue-900 text-lg">
                    E = %ΔQ / %ΔP = {resultado.porcentajeQ.toFixed(2)} / {resultado.porcentajeP.toFixed(2)} = <strong>{resultado.elasticidad.toFixed(4)}</strong>
                  </p>
                </div>
              </div>
            </div>

            <div className={`p-4 rounded-lg ${
              tipo === 'precio' 
                ? (Math.abs(resultado.elasticidad) > 1 
                    ? 'bg-green-100 border border-green-300' 
                    : Math.abs(resultado.elasticidad) < 1 
                      ? 'bg-orange-100 border border-orange-300' 
                      : 'bg-blue-100 border border-blue-300')
                : tipo === 'ingreso'
                  ? (resultado.elasticidad > 1 
                      ? 'bg-purple-100 border border-purple-300' 
                      : resultado.elasticidad > 0 
                        ? 'bg-yellow-100 border border-yellow-300' 
                        : 'bg-red-100 border border-red-300')
                  : (resultado.elasticidad > 0 
                      ? 'bg-green-100 border border-green-300' 
                      : 'bg-red-100 border border-red-300')
            }`}>
              <p className="font-semibold text-gray-800">Interpretación:</p>
              <p className="text-gray-700 mt-1">{resultado.interpretacion}</p>
              {tipo === 'precio' && Math.abs(resultado.elasticidad) > 1 && (
                <p className="text-sm text-gray-600 mt-2">
                  El ingreso total aumentará si se reduce el precio (efecto cantidad domina).
                </p>
              )}
              {tipo === 'precio' && Math.abs(resultado.elasticidad) < 1 && (
                <p className="text-sm text-gray-600 mt-2">
                  El ingreso total aumentará si se aumenta el precio (efecto precio domina).
                </p>
              )}
            </div>
          </div>
        )}
      </div>
    </Card>
  );
}

export default CalculadoraElasticidad;
