/**
 * Correlation Matrix Component
 * Displays asset correlations in a heatmap format
 * with tooltips and color-coded values
 */

import React, { useMemo, useState } from 'react';
import {
  TableCellsIcon,
  InformationCircleIcon,
  ArrowPathIcon,
} from '@heroicons/react/24/solid';
import type { PortfolioAllocation } from '../../../services/portfolio.service';

interface CorrelationMatrixProps {
  allocations: PortfolioAllocation[];
  compact?: boolean;
}

interface CorrelationData {
  matrix: number[][];
  assets: string[];
}

// Generate realistic correlation values based on asset types
const generateCorrelation = (asset1: string, asset2: string): number => {
  if (asset1 === asset2) return 1;

  // Crypto assets tend to be highly correlated
  const cryptoPairs: Record<string, Record<string, number>> = {
    BTC: { ETH: 0.85, SOL: 0.78, LINK: 0.72, AVAX: 0.75, ADA: 0.68, DOT: 0.70, MATIC: 0.73, UNI: 0.65, USDT: 0.05, USDC: 0.05 },
    ETH: { BTC: 0.85, SOL: 0.82, LINK: 0.78, AVAX: 0.80, ADA: 0.72, DOT: 0.75, MATIC: 0.85, UNI: 0.82, USDT: 0.03, USDC: 0.03 },
    SOL: { BTC: 0.78, ETH: 0.82, LINK: 0.70, AVAX: 0.78, ADA: 0.65, DOT: 0.68, MATIC: 0.75, UNI: 0.70, USDT: 0.02, USDC: 0.02 },
    LINK: { BTC: 0.72, ETH: 0.78, SOL: 0.70, AVAX: 0.72, ADA: 0.62, DOT: 0.65, MATIC: 0.68, UNI: 0.75, USDT: 0.01, USDC: 0.01 },
    AVAX: { BTC: 0.75, ETH: 0.80, SOL: 0.78, LINK: 0.72, ADA: 0.68, DOT: 0.70, MATIC: 0.72, UNI: 0.68, USDT: 0.02, USDC: 0.02 },
    ADA: { BTC: 0.68, ETH: 0.72, SOL: 0.65, LINK: 0.62, AVAX: 0.68, DOT: 0.72, MATIC: 0.65, UNI: 0.60, USDT: 0.01, USDC: 0.01 },
    DOT: { BTC: 0.70, ETH: 0.75, SOL: 0.68, LINK: 0.65, AVAX: 0.70, ADA: 0.72, MATIC: 0.68, UNI: 0.62, USDT: 0.02, USDC: 0.02 },
    MATIC: { BTC: 0.73, ETH: 0.85, SOL: 0.75, LINK: 0.68, AVAX: 0.72, ADA: 0.65, DOT: 0.68, UNI: 0.75, USDT: 0.02, USDC: 0.02 },
    UNI: { BTC: 0.65, ETH: 0.82, SOL: 0.70, LINK: 0.75, AVAX: 0.68, ADA: 0.60, DOT: 0.62, MATIC: 0.75, USDT: 0.01, USDC: 0.01 },
    USDT: { BTC: 0.05, ETH: 0.03, SOL: 0.02, LINK: 0.01, AVAX: 0.02, ADA: 0.01, DOT: 0.02, MATIC: 0.02, UNI: 0.01, USDC: 0.98 },
    USDC: { BTC: 0.05, ETH: 0.03, SOL: 0.02, LINK: 0.01, AVAX: 0.02, ADA: 0.01, DOT: 0.02, MATIC: 0.02, UNI: 0.01, USDT: 0.98 },
  };

  const corr1 = cryptoPairs[asset1]?.[asset2];
  const corr2 = cryptoPairs[asset2]?.[asset1];

  if (corr1 !== undefined) return corr1;
  if (corr2 !== undefined) return corr2;

  // Default moderate correlation for unknown pairs
  return 0.5 + (Math.random() * 0.3 - 0.15);
};

// Get color based on correlation value
const getCorrelationColor = (value: number): string => {
  if (value >= 0.8) return 'bg-red-500';
  if (value >= 0.6) return 'bg-orange-400';
  if (value >= 0.4) return 'bg-yellow-400';
  if (value >= 0.2) return 'bg-green-300';
  if (value >= 0) return 'bg-green-500';
  if (value >= -0.2) return 'bg-cyan-400';
  if (value >= -0.4) return 'bg-blue-400';
  if (value >= -0.6) return 'bg-blue-500';
  return 'bg-indigo-600';
};

const getCorrelationTextColor = (value: number): string => {
  if (Math.abs(value) >= 0.6) return 'text-white';
  return 'text-gray-900';
};

const getCorrelationLabel = (value: number): string => {
  if (value === 1) return 'Perfecta';
  if (value >= 0.8) return 'Muy Alta';
  if (value >= 0.6) return 'Alta';
  if (value >= 0.4) return 'Moderada';
  if (value >= 0.2) return 'Baja';
  if (value >= 0) return 'Muy Baja';
  if (value >= -0.2) return 'Inversa Baja';
  if (value >= -0.4) return 'Inversa Moderada';
  if (value >= -0.6) return 'Inversa Alta';
  return 'Inversa Muy Alta';
};

export const CorrelationMatrix: React.FC<CorrelationMatrixProps> = ({
  allocations,
  compact = false,
}) => {
  const [hoveredCell, setHoveredCell] = useState<{ row: number; col: number } | null>(null);
  const [isLoading, setIsLoading] = useState(false);

  // Generate correlation data
  const correlationData = useMemo((): CorrelationData => {
    const assets = allocations.map((a) => a.asset);
    const matrix: number[][] = [];

    for (let i = 0; i < assets.length; i++) {
      const row: number[] = [];
      for (let j = 0; j < assets.length; j++) {
        row.push(generateCorrelation(assets[i], assets[j]));
      }
      matrix.push(row);
    }

    return { matrix, assets };
  }, [allocations]);

  // Calculate portfolio diversification score
  const diversificationScore = useMemo(() => {
    const { matrix } = correlationData;
    if (matrix.length < 2) return 100;

    let totalCorr = 0;
    let count = 0;

    for (let i = 0; i < matrix.length; i++) {
      for (let j = i + 1; j < matrix.length; j++) {
        totalCorr += matrix[i][j];
        count++;
      }
    }

    const avgCorr = count > 0 ? totalCorr / count : 0;
    // Score inversely related to average correlation
    return Math.max(0, Math.min(100, (1 - avgCorr) * 100));
  }, [correlationData]);

  // Find highly correlated pairs
  const highCorrelationPairs = useMemo(() => {
    const pairs: Array<{ asset1: string; asset2: string; correlation: number }> = [];
    const { matrix, assets } = correlationData;

    for (let i = 0; i < matrix.length; i++) {
      for (let j = i + 1; j < matrix.length; j++) {
        if (matrix[i][j] >= 0.7) {
          pairs.push({
            asset1: assets[i],
            asset2: assets[j],
            correlation: matrix[i][j],
          });
        }
      }
    }

    return pairs.sort((a, b) => b.correlation - a.correlation).slice(0, 3);
  }, [correlationData]);

  if (compact) {
    return (
      <div className="bg-white dark:bg-gray-800 rounded-xl shadow-lg p-6">
        <div className="flex items-center justify-between mb-4">
          <div className="flex items-center gap-3">
            <div className="p-2 bg-cyan-100 dark:bg-cyan-900/30 rounded-lg">
              <TableCellsIcon className="w-5 h-5 text-cyan-600" />
            </div>
            <h3 className="font-bold text-gray-900 dark:text-white">Correlaciones</h3>
          </div>
        </div>

        {/* Diversification Score */}
        <div className="mb-4">
          <div className="flex items-center justify-between mb-1">
            <span className="text-sm text-gray-500 dark:text-gray-400">Diversificacion</span>
            <span className={`font-bold ${
              diversificationScore >= 60 ? 'text-green-500' :
              diversificationScore >= 40 ? 'text-yellow-500' : 'text-red-500'
            }`}>
              {diversificationScore.toFixed(0)}%
            </span>
          </div>
          <div className="h-2 bg-gray-200 dark:bg-gray-700 rounded-full overflow-hidden">
            <div
              className={`h-full rounded-full ${
                diversificationScore >= 60 ? 'bg-green-500' :
                diversificationScore >= 40 ? 'bg-yellow-500' : 'bg-red-500'
              }`}
              style={{ width: `${diversificationScore}%` }}
            />
          </div>
        </div>

        {/* High Correlation Warning */}
        {highCorrelationPairs.length > 0 && (
          <div className="text-xs text-orange-600 dark:text-orange-400">
            {highCorrelationPairs.length} par(es) altamente correlacionado(s)
          </div>
        )}
      </div>
    );
  }

  return (
    <div className="bg-white dark:bg-gray-800 rounded-xl shadow-lg p-6">
      {/* Header */}
      <div className="flex items-center justify-between mb-6">
        <div className="flex items-center gap-3">
          <div className="p-2 bg-cyan-100 dark:bg-cyan-900/30 rounded-lg">
            <TableCellsIcon className="w-6 h-6 text-cyan-600" />
          </div>
          <div>
            <h3 className="font-bold text-gray-900 dark:text-white">Matriz de Correlacion</h3>
            <p className="text-sm text-gray-500 dark:text-gray-400">
              Relaciones entre activos del portfolio
            </p>
          </div>
        </div>

        {/* Diversification Score Badge */}
        <div className={`px-3 py-1.5 rounded-lg ${
          diversificationScore >= 60 ? 'bg-green-100 dark:bg-green-900/30' :
          diversificationScore >= 40 ? 'bg-yellow-100 dark:bg-yellow-900/30' :
          'bg-red-100 dark:bg-red-900/30'
        }`}>
          <span className="text-xs text-gray-600 dark:text-gray-400">Diversificacion: </span>
          <span className={`font-bold ${
            diversificationScore >= 60 ? 'text-green-600' :
            diversificationScore >= 40 ? 'text-yellow-600' : 'text-red-600'
          }`}>
            {diversificationScore.toFixed(0)}%
          </span>
        </div>
      </div>

      {/* Correlation Matrix Table */}
      <div className="overflow-x-auto">
        <table className="w-full">
          <thead>
            <tr>
              <th className="p-2 text-left text-sm font-medium text-gray-500 dark:text-gray-400">
                Activo
              </th>
              {correlationData.assets.map((asset) => (
                <th
                  key={asset}
                  className="p-2 text-center text-sm font-medium text-gray-900 dark:text-white"
                >
                  {asset}
                </th>
              ))}
            </tr>
          </thead>
          <tbody>
            {correlationData.matrix.map((row, i) => (
              <tr key={correlationData.assets[i]}>
                <td className="p-2 text-sm font-medium text-gray-900 dark:text-white">
                  {correlationData.assets[i]}
                </td>
                {row.map((value, j) => {
                  const isHovered = hoveredCell?.row === i && hoveredCell?.col === j;
                  const isHighlighted = hoveredCell !== null && (hoveredCell.row === i || hoveredCell.col === j);

                  return (
                    <td
                      key={j}
                      className="p-1"
                      onMouseEnter={() => setHoveredCell({ row: i, col: j })}
                      onMouseLeave={() => setHoveredCell(null)}
                    >
                      <div
                        className={`
                          w-12 h-12 flex items-center justify-center rounded-lg cursor-pointer
                          transition-all duration-150
                          ${getCorrelationColor(value)}
                          ${isHovered ? 'ring-2 ring-gray-900 dark:ring-white scale-110 z-10' : ''}
                          ${isHighlighted && !isHovered ? 'opacity-80' : ''}
                        `}
                      >
                        <span className={`text-xs font-medium ${getCorrelationTextColor(value)}`}>
                          {value.toFixed(2)}
                        </span>
                      </div>
                    </td>
                  );
                })}
              </tr>
            ))}
          </tbody>
        </table>
      </div>

      {/* Tooltip for hovered cell */}
      {hoveredCell && (
        <div className="mt-4 p-3 bg-gray-50 dark:bg-gray-700/50 rounded-lg">
          <p className="text-sm text-gray-700 dark:text-gray-300">
            <span className="font-bold">{correlationData.assets[hoveredCell.row]}</span>
            {' / '}
            <span className="font-bold">{correlationData.assets[hoveredCell.col]}</span>
            {': '}
            <span className={`font-bold ${
              correlationData.matrix[hoveredCell.row][hoveredCell.col] >= 0.7 ? 'text-red-500' :
              correlationData.matrix[hoveredCell.row][hoveredCell.col] >= 0.4 ? 'text-yellow-500' :
              'text-green-500'
            }`}>
              {correlationData.matrix[hoveredCell.row][hoveredCell.col].toFixed(3)}
            </span>
            {' - '}
            {getCorrelationLabel(correlationData.matrix[hoveredCell.row][hoveredCell.col])}
          </p>
        </div>
      )}

      {/* Color Legend */}
      <div className="mt-6">
        <h4 className="text-sm font-semibold text-gray-700 dark:text-gray-300 mb-3">
          Escala de Correlacion
        </h4>
        <div className="flex items-center gap-1">
          <span className="text-xs text-gray-500 dark:text-gray-400 w-8">-1</span>
          <div className="flex-1 h-4 rounded-full overflow-hidden flex">
            <div className="flex-1 bg-indigo-600" />
            <div className="flex-1 bg-blue-500" />
            <div className="flex-1 bg-blue-400" />
            <div className="flex-1 bg-cyan-400" />
            <div className="flex-1 bg-green-500" />
            <div className="flex-1 bg-green-300" />
            <div className="flex-1 bg-yellow-400" />
            <div className="flex-1 bg-orange-400" />
            <div className="flex-1 bg-red-500" />
          </div>
          <span className="text-xs text-gray-500 dark:text-gray-400 w-4">+1</span>
        </div>
        <div className="flex justify-between text-xs text-gray-500 dark:text-gray-400 mt-1">
          <span>Inversa Perfecta</span>
          <span>Sin Correlacion</span>
          <span>Correlacion Perfecta</span>
        </div>
      </div>

      {/* High Correlation Warnings */}
      {highCorrelationPairs.length > 0 && (
        <div className="mt-6 p-4 bg-orange-50 dark:bg-orange-900/20 rounded-lg border border-orange-200 dark:border-orange-800">
          <div className="flex items-start gap-3">
            <InformationCircleIcon className="w-5 h-5 text-orange-500 flex-shrink-0 mt-0.5" />
            <div>
              <p className="font-medium text-orange-800 dark:text-orange-200">
                Pares Altamente Correlacionados
              </p>
              <p className="text-sm text-orange-700 dark:text-orange-300 mt-1">
                Los siguientes pares de activos se mueven juntos, lo que puede reducir la diversificacion:
              </p>
              <ul className="mt-2 space-y-1">
                {highCorrelationPairs.map((pair, index) => (
                  <li key={index} className="text-sm text-orange-600 dark:text-orange-400">
                    <span className="font-medium">{pair.asset1}</span> - <span className="font-medium">{pair.asset2}</span>
                    {': '}
                    <span className="font-bold">{(pair.correlation * 100).toFixed(0)}%</span>
                  </li>
                ))}
              </ul>
            </div>
          </div>
        </div>
      )}

      {/* Interpretation Guide */}
      <div className="mt-6 pt-4 border-t border-gray-200 dark:border-gray-700">
        <h4 className="text-sm font-semibold text-gray-700 dark:text-gray-300 mb-3">
          Interpretacion
        </h4>
        <div className="grid md:grid-cols-3 gap-4 text-xs text-gray-600 dark:text-gray-400">
          <div className="p-3 bg-gray-50 dark:bg-gray-700/50 rounded-lg">
            <p className="font-medium text-green-600 mb-1">Correlacion Baja (0-0.3)</p>
            <p>Excelente para diversificacion. Los activos se mueven independientemente.</p>
          </div>
          <div className="p-3 bg-gray-50 dark:bg-gray-700/50 rounded-lg">
            <p className="font-medium text-yellow-600 mb-1">Correlacion Moderada (0.3-0.7)</p>
            <p>Diversificacion parcial. Algunos movimientos compartidos.</p>
          </div>
          <div className="p-3 bg-gray-50 dark:bg-gray-700/50 rounded-lg">
            <p className="font-medium text-red-600 mb-1">Correlacion Alta (0.7-1.0)</p>
            <p>Poca diversificacion. Los activos tienden a moverse juntos.</p>
          </div>
        </div>
      </div>
    </div>
  );
};

export default CorrelationMatrix;
