/**
 * PortfolioOptimizerWidget Component
 * Interactive portfolio allocation optimizer with Markowitz-based recommendations
 * Epic: OQI-004 Cuentas de Inversion
 */

import React, { useState, useMemo, useCallback } from 'react';
import {
  PieChart,
  TrendingUp,
  Scale,
  Shield,
  Zap,
  RefreshCw,
  CheckCircle,
  AlertTriangle,
  Info,
  ArrowRight,
  Loader2,
  ChevronDown,
  ChevronUp,
} from 'lucide-react';

// Types
export interface AccountAllocation {
  accountId: string;
  accountName: string;
  productName: string;
  currentValue: number;
  currentAllocation: number;  // percentage
  recommendedAllocation: number;  // percentage
  riskLevel: 'low' | 'medium' | 'high';
  expectedReturn: number;
  color: string;
}

export interface OptimizationResult {
  strategy: OptimizationStrategy;
  accounts: AccountAllocation[];
  metrics: {
    expectedReturn: number;
    expectedVolatility: number;
    sharpeRatio: number;
    maxDrawdown: number;
  };
  rebalanceRequired: boolean;
  totalDrift: number;  // percentage drift from optimal
}

export interface PortfolioSimulation {
  year: number;
  conservative: number;
  balanced: number;
  aggressive: number;
}

export type OptimizationStrategy = 'conservative' | 'balanced' | 'aggressive' | 'custom';

export interface PortfolioOptimizerWidgetProps {
  accounts: AccountAllocation[];
  totalValue: number;
  currentResult?: OptimizationResult;
  onOptimize?: (strategy: OptimizationStrategy) => void;
  onApplyRebalance?: (allocations: AccountAllocation[]) => void;
  isOptimizing?: boolean;
  isApplying?: boolean;
  showSimulation?: boolean;
}

const STRATEGY_OPTIONS: {
  value: OptimizationStrategy;
  label: string;
  description: string;
  icon: React.ElementType;
  color: string;
}[] = [
  {
    value: 'conservative',
    label: 'Conservative',
    description: 'Minimize risk, preserve capital',
    icon: Shield,
    color: 'text-emerald-400',
  },
  {
    value: 'balanced',
    label: 'Balanced',
    description: 'Balance risk and return',
    icon: Scale,
    color: 'text-blue-400',
  },
  {
    value: 'aggressive',
    label: 'Aggressive',
    description: 'Maximize returns, higher risk',
    icon: Zap,
    color: 'text-amber-400',
  },
];

// Sample simulation data for visualization
const SIMULATION_DATA: PortfolioSimulation[] = [
  { year: 0, conservative: 100000, balanced: 100000, aggressive: 100000 },
  { year: 1, conservative: 106000, balanced: 110000, aggressive: 115000 },
  { year: 2, conservative: 112360, balanced: 121000, aggressive: 126500 },
  { year: 3, conservative: 119102, balanced: 133100, aggressive: 139150 },
  { year: 4, conservative: 126248, balanced: 146410, aggressive: 153065 },
  { year: 5, conservative: 133823, balanced: 161051, aggressive: 168372 },
];

const PortfolioOptimizerWidget: React.FC<PortfolioOptimizerWidgetProps> = ({
  accounts,
  totalValue,
  currentResult,
  onOptimize,
  onApplyRebalance,
  isOptimizing = false,
  isApplying = false,
  showSimulation = true,
}) => {
  const [selectedStrategy, setSelectedStrategy] = useState<OptimizationStrategy>('balanced');
  const [showDetails, setShowDetails] = useState(false);
  const [confirmRebalance, setConfirmRebalance] = useState(false);

  // Calculate drift for each account
  const accountsWithDrift = useMemo(() => {
    return accounts.map((account) => ({
      ...account,
      drift: Math.abs(account.currentAllocation - account.recommendedAllocation),
      driftDirection: account.currentAllocation > account.recommendedAllocation ? 'over' : 'under',
      adjustmentAmount: totalValue * ((account.recommendedAllocation - account.currentAllocation) / 100),
    }));
  }, [accounts, totalValue]);

  // Total drift
  const totalDrift = useMemo(() => {
    return accountsWithDrift.reduce((sum, acc) => sum + acc.drift, 0) / 2; // Divide by 2 because drift is counted twice
  }, [accountsWithDrift]);

  // Handle strategy selection
  const handleStrategySelect = useCallback((strategy: OptimizationStrategy) => {
    setSelectedStrategy(strategy);
    onOptimize?.(strategy);
  }, [onOptimize]);

  // Handle apply rebalance
  const handleApplyRebalance = useCallback(() => {
    if (confirmRebalance) {
      onApplyRebalance?.(accounts);
      setConfirmRebalance(false);
    } else {
      setConfirmRebalance(true);
    }
  }, [confirmRebalance, accounts, onApplyRebalance]);

  // Get risk level color
  const getRiskColor = (level: string) => {
    switch (level) {
      case 'low':
        return 'text-emerald-400';
      case 'medium':
        return 'text-amber-400';
      case 'high':
        return 'text-red-400';
      default:
        return 'text-slate-400';
    }
  };

  // Render allocation pie chart (simplified SVG)
  const renderAllocationChart = (type: 'current' | 'recommended') => {
    let cumulativeAngle = 0;

    return (
      <svg viewBox="0 0 100 100" className="w-full h-full">
        {accounts.map((account, index) => {
          const allocation = type === 'current' ? account.currentAllocation : account.recommendedAllocation;
          const angle = (allocation / 100) * 360;
          const startAngle = cumulativeAngle;
          cumulativeAngle += angle;

          // Calculate arc path
          const startRad = (startAngle - 90) * (Math.PI / 180);
          const endRad = (startAngle + angle - 90) * (Math.PI / 180);
          const x1 = 50 + 40 * Math.cos(startRad);
          const y1 = 50 + 40 * Math.sin(startRad);
          const x2 = 50 + 40 * Math.cos(endRad);
          const y2 = 50 + 40 * Math.sin(endRad);
          const largeArc = angle > 180 ? 1 : 0;

          if (allocation < 0.5) return null;

          return (
            <path
              key={`${type}-${account.accountId}`}
              d={`M 50 50 L ${x1} ${y1} A 40 40 0 ${largeArc} 1 ${x2} ${y2} Z`}
              fill={account.color}
              stroke="#1e293b"
              strokeWidth="1"
              opacity={0.9}
            />
          );
        })}
        {/* Center hole */}
        <circle cx="50" cy="50" r="25" fill="#0f172a" />
      </svg>
    );
  };

  // Render strategy selector
  const renderStrategySelector = () => (
    <div className="grid grid-cols-3 gap-3">
      {STRATEGY_OPTIONS.map((strategy) => {
        const Icon = strategy.icon;
        const isSelected = selectedStrategy === strategy.value;

        return (
          <button
            key={strategy.value}
            onClick={() => handleStrategySelect(strategy.value)}
            disabled={isOptimizing}
            className={`p-4 rounded-lg border text-left transition-all ${
              isSelected
                ? 'border-blue-500 bg-blue-900/20'
                : 'border-slate-700 bg-slate-800/50 hover:border-slate-600'
            } ${isOptimizing ? 'opacity-50 cursor-not-allowed' : ''}`}
          >
            <Icon className={`w-6 h-6 ${strategy.color} mb-2`} />
            <h4 className="text-white font-medium">{strategy.label}</h4>
            <p className="text-slate-400 text-xs mt-1">{strategy.description}</p>
          </button>
        );
      })}
    </div>
  );

  // Render allocation comparison
  const renderAllocationComparison = () => (
    <div className="grid grid-cols-2 gap-6">
      {/* Current Allocation */}
      <div>
        <h4 className="text-slate-400 text-sm text-center mb-3">Current Allocation</h4>
        <div className="w-32 h-32 mx-auto">
          {renderAllocationChart('current')}
        </div>
      </div>

      {/* Recommended Allocation */}
      <div>
        <h4 className="text-slate-400 text-sm text-center mb-3">Recommended</h4>
        <div className="w-32 h-32 mx-auto relative">
          {renderAllocationChart('recommended')}
          {isOptimizing && (
            <div className="absolute inset-0 flex items-center justify-center bg-slate-900/50 rounded-full">
              <Loader2 className="w-8 h-8 text-blue-400 animate-spin" />
            </div>
          )}
        </div>
      </div>
    </div>
  );

  // Render allocation legend
  const renderAllocationLegend = () => (
    <div className="space-y-2">
      {accountsWithDrift.map((account) => (
        <div
          key={account.accountId}
          className="flex items-center justify-between text-sm"
        >
          <div className="flex items-center gap-2">
            <div
              className="w-3 h-3 rounded-full"
              style={{ backgroundColor: account.color }}
            />
            <span className="text-slate-300">{account.accountName}</span>
          </div>
          <div className="flex items-center gap-4">
            <span className="text-slate-500 w-12 text-right">
              {account.currentAllocation.toFixed(1)}%
            </span>
            <ArrowRight className="w-4 h-4 text-slate-600" />
            <span className="text-white w-12 text-right">
              {account.recommendedAllocation.toFixed(1)}%
            </span>
            {account.drift > 0.5 && (
              <span className={`text-xs px-1.5 py-0.5 rounded ${
                account.driftDirection === 'over' ? 'bg-red-900/50 text-red-400' : 'bg-emerald-900/50 text-emerald-400'
              }`}>
                {account.driftDirection === 'over' ? '-' : '+'}{account.drift.toFixed(1)}%
              </span>
            )}
          </div>
        </div>
      ))}
    </div>
  );

  // Render metrics comparison
  const renderMetricsComparison = () => {
    if (!currentResult) return null;

    const metrics = [
      {
        label: 'Expected Return',
        value: `${currentResult.metrics.expectedReturn.toFixed(1)}%`,
        change: '+2.3%',
        positive: true,
      },
      {
        label: 'Expected Volatility',
        value: `${currentResult.metrics.expectedVolatility.toFixed(1)}%`,
        change: '-1.5%',
        positive: true,
      },
      {
        label: 'Sharpe Ratio',
        value: currentResult.metrics.sharpeRatio.toFixed(2),
        change: '+0.15',
        positive: true,
      },
      {
        label: 'Max Drawdown',
        value: `${currentResult.metrics.maxDrawdown.toFixed(1)}%`,
        change: '-2.1%',
        positive: true,
      },
    ];

    return (
      <div className="grid grid-cols-2 gap-3">
        {metrics.map((metric) => (
          <div
            key={metric.label}
            className="bg-slate-800/50 rounded-lg p-3 border border-slate-700"
          >
            <span className="text-slate-400 text-xs">{metric.label}</span>
            <div className="flex items-baseline gap-2 mt-1">
              <span className="text-white font-semibold">{metric.value}</span>
              <span className={`text-xs ${metric.positive ? 'text-emerald-400' : 'text-red-400'}`}>
                {metric.change}
              </span>
            </div>
          </div>
        ))}
      </div>
    );
  };

  // Render rebalance actions
  const renderRebalanceActions = () => {
    if (totalDrift < 1) {
      return (
        <div className="bg-emerald-900/20 border border-emerald-800/50 rounded-lg p-4 flex items-center gap-3">
          <CheckCircle className="w-6 h-6 text-emerald-400" />
          <div>
            <p className="text-emerald-400 font-medium">Portfolio is Optimized</p>
            <p className="text-slate-400 text-sm">Current allocation is within optimal range</p>
          </div>
        </div>
      );
    }

    return (
      <div className="space-y-4">
        {/* Drift Warning */}
        <div className="bg-amber-900/20 border border-amber-800/50 rounded-lg p-4 flex items-start gap-3">
          <AlertTriangle className="w-5 h-5 text-amber-400 flex-shrink-0 mt-0.5" />
          <div>
            <p className="text-amber-400 font-medium">Rebalancing Recommended</p>
            <p className="text-slate-400 text-sm">
              Your portfolio has drifted {totalDrift.toFixed(1)}% from the optimal allocation.
              Rebalancing can help maintain your risk profile and improve returns.
            </p>
          </div>
        </div>

        {/* Rebalance Details */}
        <button
          onClick={() => setShowDetails(!showDetails)}
          className="w-full flex items-center justify-between text-slate-300 hover:text-white"
        >
          <span className="text-sm">View rebalance details</span>
          {showDetails ? (
            <ChevronUp className="w-4 h-4" />
          ) : (
            <ChevronDown className="w-4 h-4" />
          )}
        </button>

        {showDetails && (
          <div className="bg-slate-800/50 rounded-lg p-4 border border-slate-700 space-y-3">
            <h4 className="text-white font-medium text-sm">Required Adjustments</h4>
            {accountsWithDrift
              .filter((acc) => Math.abs(acc.adjustmentAmount) > 10)
              .map((account) => (
                <div
                  key={account.accountId}
                  className="flex items-center justify-between text-sm"
                >
                  <span className="text-slate-300">{account.accountName}</span>
                  <span className={account.adjustmentAmount > 0 ? 'text-emerald-400' : 'text-red-400'}>
                    {account.adjustmentAmount > 0 ? '+' : ''}
                    ${Math.abs(account.adjustmentAmount).toLocaleString(undefined, { maximumFractionDigits: 0 })}
                  </span>
                </div>
              ))}
            <div className="pt-3 border-t border-slate-700">
              <p className="text-slate-500 text-xs flex items-center gap-1">
                <Info className="w-3 h-3" />
                Funds will be transferred between accounts automatically
              </p>
            </div>
          </div>
        )}

        {/* Confirm/Apply Button */}
        <div className="flex gap-3">
          {confirmRebalance && (
            <button
              onClick={() => setConfirmRebalance(false)}
              className="flex-1 px-4 py-2 text-slate-300 hover:text-white transition-colors"
            >
              Cancel
            </button>
          )}
          <button
            onClick={handleApplyRebalance}
            disabled={isApplying}
            className={`flex-1 flex items-center justify-center gap-2 px-4 py-3 rounded-lg transition-colors ${
              confirmRebalance
                ? 'bg-amber-600 hover:bg-amber-500 text-white'
                : 'bg-blue-600 hover:bg-blue-500 text-white'
            } disabled:opacity-50 disabled:cursor-not-allowed`}
          >
            {isApplying ? (
              <>
                <Loader2 className="w-4 h-4 animate-spin" />
                Rebalancing...
              </>
            ) : confirmRebalance ? (
              <>
                <CheckCircle className="w-4 h-4" />
                Confirm Rebalance
              </>
            ) : (
              <>
                <RefreshCw className="w-4 h-4" />
                Apply Rebalance
              </>
            )}
          </button>
        </div>
      </div>
    );
  };

  // Render simulation chart (simplified)
  const renderSimulationChart = () => {
    if (!showSimulation) return null;

    const maxValue = Math.max(...SIMULATION_DATA.map((d) => Math.max(d.conservative, d.balanced, d.aggressive)));
    const scale = 100 / maxValue;

    return (
      <div className="bg-slate-800/50 rounded-lg p-4 border border-slate-700">
        <h4 className="text-white font-medium mb-4">5-Year Projection (${totalValue.toLocaleString()})</h4>

        <div className="h-32 relative">
          <svg className="w-full h-full" preserveAspectRatio="none" viewBox="0 0 100 100">
            {/* Grid lines */}
            {[0, 25, 50, 75, 100].map((y) => (
              <line
                key={y}
                x1="0"
                y1={100 - y}
                x2="100"
                y2={100 - y}
                stroke="#334155"
                strokeWidth="0.5"
              />
            ))}

            {/* Conservative line */}
            <polyline
              fill="none"
              stroke="#10b981"
              strokeWidth="2"
              points={SIMULATION_DATA.map((d, i) =>
                `${(i / (SIMULATION_DATA.length - 1)) * 100},${100 - (d.conservative * scale)}`
              ).join(' ')}
            />

            {/* Balanced line */}
            <polyline
              fill="none"
              stroke="#3b82f6"
              strokeWidth="2"
              points={SIMULATION_DATA.map((d, i) =>
                `${(i / (SIMULATION_DATA.length - 1)) * 100},${100 - (d.balanced * scale)}`
              ).join(' ')}
            />

            {/* Aggressive line */}
            <polyline
              fill="none"
              stroke="#f59e0b"
              strokeWidth="2"
              points={SIMULATION_DATA.map((d, i) =>
                `${(i / (SIMULATION_DATA.length - 1)) * 100},${100 - (d.aggressive * scale)}`
              ).join(' ')}
            />
          </svg>
        </div>

        {/* Legend */}
        <div className="flex justify-center gap-6 mt-4">
          <div className="flex items-center gap-2">
            <div className="w-3 h-3 rounded-full bg-emerald-500" />
            <span className="text-slate-400 text-xs">Conservative</span>
          </div>
          <div className="flex items-center gap-2">
            <div className="w-3 h-3 rounded-full bg-blue-500" />
            <span className="text-slate-400 text-xs">Balanced</span>
          </div>
          <div className="flex items-center gap-2">
            <div className="w-3 h-3 rounded-full bg-amber-500" />
            <span className="text-slate-400 text-xs">Aggressive</span>
          </div>
        </div>

        <p className="text-slate-500 text-xs text-center mt-3">
          Projections are based on historical performance and do not guarantee future results
        </p>
      </div>
    );
  };

  return (
    <div className="bg-slate-900 rounded-xl border border-slate-800">
      {/* Header */}
      <div className="p-6 border-b border-slate-800">
        <div className="flex items-center gap-3">
          <PieChart className="w-6 h-6 text-blue-400" />
          <div>
            <h2 className="text-white text-lg font-semibold">Portfolio Optimizer</h2>
            <p className="text-slate-400 text-sm">
              Total Value: ${totalValue.toLocaleString()}
            </p>
          </div>
        </div>
      </div>

      {/* Content */}
      <div className="p-6 space-y-6">
        {/* Strategy Selector */}
        <div>
          <h3 className="text-white font-medium mb-3">Optimization Strategy</h3>
          {renderStrategySelector()}
        </div>

        {/* Allocation Comparison */}
        <div>
          <h3 className="text-white font-medium mb-3">Allocation Comparison</h3>
          {renderAllocationComparison()}
          <div className="mt-4">
            {renderAllocationLegend()}
          </div>
        </div>

        {/* Metrics */}
        {currentResult && (
          <div>
            <h3 className="text-white font-medium mb-3">Expected Impact</h3>
            {renderMetricsComparison()}
          </div>
        )}

        {/* Simulation */}
        {renderSimulationChart()}

        {/* Rebalance Actions */}
        <div>
          <h3 className="text-white font-medium mb-3">Rebalance</h3>
          {renderRebalanceActions()}
        </div>
      </div>
    </div>
  );
};

export default PortfolioOptimizerWidget;
