/**
 * Allocations Card Component
 * Displays portfolio allocations with donut chart,
 * comparison with target allocation, and drift indicator
 */

import React, { useMemo } from 'react';
import {
  PieChart,
  Pie,
  Cell,
  ResponsiveContainer,
  Tooltip,
  Legend,
} from 'recharts';
import {
  ExclamationTriangleIcon,
  CheckCircleIcon,
  ArrowsRightLeftIcon,
} from '@heroicons/react/24/solid';
import type { PortfolioAllocation } from '../../../services/portfolio.service';

interface AllocationsCardProps {
  allocations: PortfolioAllocation[];
  showTargetComparison?: boolean;
  onRebalance?: () => void;
  maxDriftThreshold?: number;
}

// Asset colors for chart
const ASSET_COLORS: Record<string, string> = {
  BTC: '#F7931A',
  ETH: '#627EEA',
  USDT: '#26A17B',
  USDC: '#2775CA',
  SOL: '#9945FF',
  LINK: '#2A5ADA',
  AVAX: '#E84142',
  ADA: '#0033AD',
  DOT: '#E6007A',
  MATIC: '#8247E5',
  XRP: '#23292F',
  BNB: '#F0B90B',
  DOGE: '#C3A634',
  ATOM: '#2E3148',
  LTC: '#BFBBBB',
};

const DEFAULT_COLORS = [
  '#3B82F6', '#10B981', '#F59E0B', '#EF4444', '#8B5CF6',
  '#EC4899', '#06B6D4', '#84CC16', '#F97316', '#6366F1',
];

function getAssetColor(asset: string, index: number): string {
  return ASSET_COLORS[asset] || DEFAULT_COLORS[index % DEFAULT_COLORS.length];
}

interface DriftIndicatorProps {
  drift: number;
  threshold: number;
}

const DriftIndicator: React.FC<DriftIndicatorProps> = ({ drift, threshold }) => {
  const severity = Math.abs(drift) <= threshold / 2
    ? 'low'
    : Math.abs(drift) <= threshold
    ? 'medium'
    : 'high';

  const config = {
    low: {
      icon: CheckCircleIcon,
      color: 'text-green-500',
      bgColor: 'bg-green-100 dark:bg-green-900/30',
      label: 'Balanceado',
    },
    medium: {
      icon: ArrowsRightLeftIcon,
      color: 'text-yellow-500',
      bgColor: 'bg-yellow-100 dark:bg-yellow-900/30',
      label: 'Drift Moderado',
    },
    high: {
      icon: ExclamationTriangleIcon,
      color: 'text-red-500',
      bgColor: 'bg-red-100 dark:bg-red-900/30',
      label: 'Requiere Rebalanceo',
    },
  };

  const { icon: Icon, color, bgColor, label } = config[severity];

  return (
    <div className={`flex items-center gap-2 px-3 py-2 rounded-lg ${bgColor}`}>
      <Icon className={`w-5 h-5 ${color}`} />
      <div>
        <p className={`text-sm font-medium ${color}`}>{label}</p>
        <p className="text-xs text-gray-500 dark:text-gray-400">
          Drift maximo: {drift.toFixed(1)}%
        </p>
      </div>
    </div>
  );
};

interface CustomTooltipProps {
  active?: boolean;
  payload?: Array<{
    payload: {
      asset: string;
      value: number;
      currentPercent: number;
      targetPercent: number;
      deviation: number;
      pnl: number;
      pnlPercent: number;
    };
  }>;
}

const CustomTooltip: React.FC<CustomTooltipProps> = ({ active, payload }) => {
  if (!active || !payload || !payload.length) return null;

  const data = payload[0].payload;

  return (
    <div className="bg-white dark:bg-gray-800 p-3 rounded-lg shadow-lg border border-gray-200 dark:border-gray-700">
      <p className="font-bold text-gray-900 dark:text-white">{data.asset}</p>
      <div className="mt-2 space-y-1 text-sm">
        <div className="flex justify-between gap-4">
          <span className="text-gray-500 dark:text-gray-400">Valor:</span>
          <span className="text-gray-900 dark:text-white">
            ${data.value.toLocaleString(undefined, { minimumFractionDigits: 2 })}
          </span>
        </div>
        <div className="flex justify-between gap-4">
          <span className="text-gray-500 dark:text-gray-400">Actual:</span>
          <span className="text-gray-900 dark:text-white">{data.currentPercent.toFixed(1)}%</span>
        </div>
        <div className="flex justify-between gap-4">
          <span className="text-gray-500 dark:text-gray-400">Objetivo:</span>
          <span className="text-gray-900 dark:text-white">{data.targetPercent.toFixed(1)}%</span>
        </div>
        <div className="flex justify-between gap-4">
          <span className="text-gray-500 dark:text-gray-400">Drift:</span>
          <span className={data.deviation > 0 ? 'text-green-500' : data.deviation < 0 ? 'text-red-500' : 'text-gray-500'}>
            {data.deviation > 0 ? '+' : ''}{data.deviation.toFixed(1)}%
          </span>
        </div>
        <div className="flex justify-between gap-4 pt-1 border-t border-gray-200 dark:border-gray-700">
          <span className="text-gray-500 dark:text-gray-400">P&L:</span>
          <span className={data.pnl >= 0 ? 'text-green-500' : 'text-red-500'}>
            {data.pnl >= 0 ? '+' : ''}${data.pnl.toLocaleString(undefined, { minimumFractionDigits: 2 })}
          </span>
        </div>
      </div>
    </div>
  );
};

export const AllocationsCard: React.FC<AllocationsCardProps> = ({
  allocations,
  showTargetComparison = true,
  onRebalance,
  maxDriftThreshold = 5,
}) => {
  const chartData = useMemo(() => {
    return allocations.map((alloc, index) => ({
      ...alloc,
      name: alloc.asset,
      fill: getAssetColor(alloc.asset, index),
    }));
  }, [allocations]);

  const totalValue = useMemo(() => {
    return allocations.reduce((sum, alloc) => sum + alloc.value, 0);
  }, [allocations]);

  const maxDrift = useMemo(() => {
    return Math.max(...allocations.map((a) => Math.abs(a.deviation)));
  }, [allocations]);

  const needsRebalance = maxDrift > maxDriftThreshold;

  const targetChartData = useMemo(() => {
    return allocations.map((alloc, index) => ({
      name: alloc.asset,
      value: alloc.targetPercent,
      fill: getAssetColor(alloc.asset, index),
    }));
  }, [allocations]);

  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>
          <h3 className="font-bold text-gray-900 dark:text-white">
            Distribucion de Activos
          </h3>
          <p className="text-sm text-gray-500 dark:text-gray-400">
            Valor total: ${totalValue.toLocaleString(undefined, { minimumFractionDigits: 2 })}
          </p>
        </div>
        <DriftIndicator drift={maxDrift} threshold={maxDriftThreshold} />
      </div>

      {/* Charts Container */}
      <div className={`grid ${showTargetComparison ? 'grid-cols-2' : 'grid-cols-1'} gap-4`}>
        {/* Current Allocation Chart */}
        <div>
          <p className="text-sm font-medium text-center text-gray-600 dark:text-gray-400 mb-2">
            Actual
          </p>
          <ResponsiveContainer width="100%" height={200}>
            <PieChart>
              <Pie
                data={chartData}
                dataKey="currentPercent"
                nameKey="asset"
                cx="50%"
                cy="50%"
                innerRadius={50}
                outerRadius={80}
                paddingAngle={2}
              >
                {chartData.map((entry, index) => (
                  <Cell key={`cell-${index}`} fill={entry.fill} />
                ))}
              </Pie>
              <Tooltip content={<CustomTooltip />} />
            </PieChart>
          </ResponsiveContainer>
        </div>

        {/* Target Allocation Chart */}
        {showTargetComparison && (
          <div>
            <p className="text-sm font-medium text-center text-gray-600 dark:text-gray-400 mb-2">
              Objetivo
            </p>
            <ResponsiveContainer width="100%" height={200}>
              <PieChart>
                <Pie
                  data={targetChartData}
                  dataKey="value"
                  nameKey="name"
                  cx="50%"
                  cy="50%"
                  innerRadius={50}
                  outerRadius={80}
                  paddingAngle={2}
                >
                  {targetChartData.map((entry, index) => (
                    <Cell key={`cell-${index}`} fill={entry.fill} />
                  ))}
                </Pie>
                <Tooltip />
              </PieChart>
            </ResponsiveContainer>
          </div>
        )}
      </div>

      {/* Legend with Deviation */}
      <div className="mt-4 grid grid-cols-2 sm:grid-cols-3 gap-2">
        {allocations.map((alloc, index) => (
          <div
            key={alloc.asset}
            className="flex items-center gap-2 p-2 rounded-lg bg-gray-50 dark:bg-gray-700/50"
          >
            <div
              className="w-3 h-3 rounded-full flex-shrink-0"
              style={{ backgroundColor: getAssetColor(alloc.asset, index) }}
            />
            <div className="min-w-0 flex-1">
              <p className="text-sm font-medium text-gray-900 dark:text-white truncate">
                {alloc.asset}
              </p>
              <div className="flex items-center gap-1 text-xs">
                <span className="text-gray-500 dark:text-gray-400">
                  {alloc.currentPercent.toFixed(1)}%
                </span>
                {showTargetComparison && (
                  <>
                    <span className="text-gray-400 dark:text-gray-500">/</span>
                    <span className="text-gray-500 dark:text-gray-400">
                      {alloc.targetPercent.toFixed(1)}%
                    </span>
                    {alloc.deviation !== 0 && (
                      <span
                        className={`ml-1 ${
                          alloc.deviation > 0 ? 'text-green-500' : 'text-red-500'
                        }`}
                      >
                        ({alloc.deviation > 0 ? '+' : ''}{alloc.deviation.toFixed(1)}%)
                      </span>
                    )}
                  </>
                )}
              </div>
            </div>
          </div>
        ))}
      </div>

      {/* Deviation Details Table */}
      {showTargetComparison && (
        <div className="mt-6">
          <h4 className="text-sm font-semibold text-gray-700 dark:text-gray-300 mb-3">
            Detalle de Desviaciones
          </h4>
          <div className="space-y-2">
            {allocations
              .filter((a) => Math.abs(a.deviation) > 0.5)
              .sort((a, b) => Math.abs(b.deviation) - Math.abs(a.deviation))
              .slice(0, 5)
              .map((alloc) => (
                <div
                  key={alloc.asset}
                  className="flex items-center justify-between p-2 rounded-lg bg-gray-50 dark:bg-gray-700/50"
                >
                  <div className="flex items-center gap-2">
                    <span className="font-medium text-gray-900 dark:text-white">
                      {alloc.asset}
                    </span>
                    <span
                      className={`text-xs px-2 py-0.5 rounded-full ${
                        alloc.deviation > 0
                          ? 'bg-green-100 dark:bg-green-900/30 text-green-600'
                          : 'bg-red-100 dark:bg-red-900/30 text-red-600'
                      }`}
                    >
                      {alloc.deviation > 0 ? 'Exceso' : 'Deficit'}
                    </span>
                  </div>
                  <div className="flex items-center gap-3">
                    <div className="text-right">
                      <p className="text-sm text-gray-900 dark:text-white">
                        {alloc.currentPercent.toFixed(1)}% → {alloc.targetPercent.toFixed(1)}%
                      </p>
                    </div>
                    <span
                      className={`font-bold ${
                        alloc.deviation > 0 ? 'text-green-500' : 'text-red-500'
                      }`}
                    >
                      {alloc.deviation > 0 ? '+' : ''}{alloc.deviation.toFixed(1)}%
                    </span>
                  </div>
                </div>
              ))}
          </div>
        </div>
      )}

      {/* Rebalance Button */}
      {needsRebalance && onRebalance && (
        <button
          onClick={onRebalance}
          className="mt-6 w-full py-3 bg-purple-600 hover:bg-purple-700 text-white font-medium rounded-lg transition-colors flex items-center justify-center gap-2"
        >
          <ArrowsRightLeftIcon className="w-5 h-5" />
          Rebalancear Portfolio
        </button>
      )}

      {/* Info Footer */}
      <div className="mt-4 pt-4 border-t border-gray-200 dark:border-gray-700">
        <p className="text-xs text-gray-500 dark:text-gray-400">
          Se recomienda rebalancear cuando la desviacion maxima supera el {maxDriftThreshold}% del objetivo.
        </p>
      </div>
    </div>
  );
};

export default AllocationsCard;
