import React, { useMemo } from 'react';
import { Bar, BarChart, XAxis, YAxis, CartesianGrid, Cell, ResponsiveContainer } from 'recharts';
import { useGridStore } from '../../store/gridStore';
import { Card, CardContent, CardHeader, CardTitle } from '../ui/card';
import { Button } from '../ui/button';
import {
  BarChart3,
  Activity,
  Clock,
  HardDrive,
  Route,
  Play,
  RefreshCw,
  Check,
  FlaskConical,
  Trophy,
  Medal,
  TrendingDown,
} from 'lucide-react';

export const ComparisonDashboard: React.FC = () => {
  const { comparisonResults, runComparison, isLoading, grid } = useGridStore();

  // Sort results by cost (best to worst)
  const sortedResults = useMemo(() => {
    if (!comparisonResults) return null;
    return [...comparisonResults].sort((a, b) => {
      if (a.cost === Infinity && b.cost === Infinity) return 0;
      if (a.cost === Infinity) return 1;
      if (b.cost === Infinity) return -1;
      return a.cost - b.cost;
    });
  }, [comparisonResults]);

  // Prepare sorted chart data for each metric
  const chartDataByMetric = useMemo(() => {
    if (!comparisonResults) return null;

    const baseData = comparisonResults.map((r) => ({
      name: r.algorithm,
      fullName: r.name,
      nodesExpanded: r.nodesExpanded,
      runtime: r.runtimeMs,
      cost: r.cost === Infinity ? 0 : r.cost,
      memory: r.memoryKb,
      isOptimal: r.isOptimal,
    }));

    return {
      nodes: [...baseData].sort((a, b) => b.nodesExpanded - a.nodesExpanded),
      runtime: [...baseData].sort((a, b) => b.runtime - a.runtime),
      cost: [...baseData].sort((a, b) => b.cost - a.cost),
      memory: [...baseData].sort((a, b) => b.memory - a.memory),
    };
  }, [comparisonResults]);

  if (!grid) {
    return (
      <div className="h-full flex items-center justify-center bg-zinc-900 rounded-lg border border-zinc-800">
        <div className="text-center">
          <BarChart3 className="w-12 h-12 text-zinc-700 mx-auto mb-4" />
          <p className="text-zinc-500 text-sm">Generate a grid first</p>
          <p className="text-zinc-600 text-xs mt-1">Then compare all algorithms</p>
        </div>
      </div>
    );
  }

  if (!comparisonResults) {
    return (
      <div className="h-full flex items-center justify-center bg-zinc-900 rounded-lg border border-zinc-800">
        <div className="text-center">
          <FlaskConical className="w-12 h-12 text-zinc-700 mx-auto mb-4" />
          <p className="text-zinc-500 text-sm mb-4">Compare Search Algorithms</p>
          <Button
            onClick={runComparison}
            disabled={isLoading}
            variant="primary"
            className="gap-2"
          >
            <Play className="w-4 h-4" />
            {isLoading ? 'Running...' : 'Run Comparison'}
          </Button>
        </div>
      </div>
    );
  }

  const getRankIcon = (index: number) => {
    if (index === 0) return <Trophy className="w-4 h-4 text-amber-500" />;
    if (index === 1) return <Medal className="w-4 h-4 text-zinc-400" />;
    if (index === 2) return <Medal className="w-4 h-4 text-amber-700" />;
    return <span className="w-4 h-4 flex items-center justify-center text-zinc-600 text-xs font-mono">{index + 1}</span>;
  };

  // Custom tooltip
  const CustomTooltip = ({ active, payload }: any) => {
    if (active && payload && payload.length) {
      const data = payload[0].payload;
      return (
        <div className="bg-zinc-900 border border-zinc-700 rounded-lg px-3 py-2 shadow-xl">
          <p className="text-zinc-200 text-xs font-medium">{data.fullName}</p>
          <p className="text-zinc-400 text-xs mt-1">
            {payload[0].name}: <span className="text-zinc-100 font-mono">{typeof payload[0].value === 'number' ? payload[0].value.toLocaleString(undefined, { maximumFractionDigits: 2 }) : payload[0].value}</span>
          </p>
        </div>
      );
    }
    return null;
  };

  // Chart component with gradient
  const GradientBarChart = ({
    data,
    dataKey,
    title,
    icon: Icon,
    gradientId,
  }: {
    data: any[];
    dataKey: string;
    title: string;
    icon: React.ElementType;
    gradientId: string;
    unit?: string;
  }) => {
    return (
      <Card className="overflow-hidden">
        <CardHeader className="pb-2 bg-zinc-800/30">
          <CardTitle className="flex items-center justify-between">
            <div className="flex items-center gap-2 text-zinc-400 text-xs font-medium">
              <Icon className="w-3.5 h-3.5" />
              {title}
            </div>
            <div className="flex items-center gap-1 text-zinc-600 text-[10px]">
              <TrendingDown className="w-3 h-3" />
              Sorted high to low
            </div>
          </CardTitle>
        </CardHeader>
        <CardContent className="pt-4">
          <ResponsiveContainer width="100%" height={180}>
            <BarChart
              data={data}
              margin={{ top: 5, right: 5, left: -20, bottom: 5 }}
              barCategoryGap="20%"
            >
              <defs>
                <linearGradient id={gradientId} x1="0" y1="0" x2="0" y2="1">
                  <stop offset="0%" stopColor="#a1a1aa" stopOpacity={0.9} />
                  <stop offset="50%" stopColor="#71717a" stopOpacity={0.8} />
                  <stop offset="100%" stopColor="#52525b" stopOpacity={0.7} />
                </linearGradient>
                <linearGradient id={`${gradientId}-best`} x1="0" y1="0" x2="0" y2="1">
                  <stop offset="0%" stopColor="#fbbf24" stopOpacity={0.9} />
                  <stop offset="50%" stopColor="#f59e0b" stopOpacity={0.8} />
                  <stop offset="100%" stopColor="#d97706" stopOpacity={0.7} />
                </linearGradient>
              </defs>
              <CartesianGrid
                strokeDasharray="3 3"
                stroke="#27272a"
                vertical={false}
              />
              <XAxis
                dataKey="name"
                tick={{ fill: '#71717a', fontSize: 9, fontFamily: 'ui-monospace' }}
                axisLine={{ stroke: '#27272a' }}
                tickLine={false}
                interval={0}
              />
              <YAxis
                tick={{ fill: '#52525b', fontSize: 9 }}
                axisLine={false}
                tickLine={false}
                tickFormatter={(value) => value.toLocaleString()}
              />
              <Bar
                dataKey={dataKey}
                radius={[4, 4, 0, 0]}
                maxBarSize={50}
              >
                {data.map((entry, index) => {
                  // Highlight the best performer (lowest value for cost, or mark optimal)
                  const isBest = entry.isOptimal || (dataKey === 'cost' && entry[dataKey] === Math.min(...data.filter(d => d[dataKey] > 0).map(d => d[dataKey])));
                  return (
                    <Cell
                      key={`cell-${index}`}
                      fill={isBest ? `url(#${gradientId}-best)` : `url(#${gradientId})`}
                      stroke={isBest ? '#fbbf24' : '#3f3f46'}
                      strokeWidth={1}
                    />
                  );
                })}
              </Bar>
              <CustomTooltip />
            </BarChart>
          </ResponsiveContainer>
        </CardContent>
      </Card>
    );
  };

  return (
    <div className="h-full overflow-auto bg-zinc-900 rounded-lg border border-zinc-800 p-4">
      <div className="flex justify-between items-center mb-4">
        <div>
          <h2 className="text-sm font-semibold text-zinc-300">Algorithm Comparison</h2>
          <p className="text-xs text-zinc-600">8 algorithms on the same problem instance</p>
        </div>
        <Button
          onClick={runComparison}
          disabled={isLoading}
          variant="outline"
          size="sm"
          className="gap-2"
        >
          <RefreshCw className={`w-3 h-3 ${isLoading ? 'animate-spin' : ''}`} />
          Re-run
        </Button>
      </div>

      {/* Charts Grid */}
      <div className="grid grid-cols-1 lg:grid-cols-2 gap-4 mb-4">
        <GradientBarChart
          data={chartDataByMetric!.nodes}
          dataKey="nodesExpanded"
          title="Nodes Expanded"
          icon={Activity}
          gradientId="nodesGradient"
        />
        <GradientBarChart
          data={chartDataByMetric!.runtime}
          dataKey="runtime"
          title="Runtime (ms)"
          icon={Clock}
          gradientId="runtimeGradient"
        />
        <GradientBarChart
          data={chartDataByMetric!.cost}
          dataKey="cost"
          title="Path Cost"
          icon={Route}
          gradientId="costGradient"
        />
        <GradientBarChart
          data={chartDataByMetric!.memory}
          dataKey="memory"
          title="Memory (MB)"
          icon={HardDrive}
          gradientId="memoryGradient"
        />
      </div>

      {/* Results Table - Sorted by best to worst */}
      <Card>
        <CardHeader className="pb-2 bg-zinc-800/30">
          <CardTitle className="flex items-center gap-2 text-zinc-400 text-xs font-medium">
            <Trophy className="w-3.5 h-3.5" />
            Rankings (Best to Worst by Path Cost)
          </CardTitle>
        </CardHeader>
        <CardContent className="p-0">
          <div className="overflow-x-auto">
            <table className="w-full text-xs">
              <thead>
                <tr className="border-b border-zinc-800 bg-zinc-800/20">
                  <th className="px-4 py-3 text-left text-zinc-500 font-medium w-12">Rank</th>
                  <th className="px-4 py-3 text-left text-zinc-500 font-medium">Algorithm</th>
                  <th className="px-4 py-3 text-right text-zinc-500 font-medium">Cost</th>
                  <th className="px-4 py-3 text-right text-zinc-500 font-medium">Nodes</th>
                  <th className="px-4 py-3 text-right text-zinc-500 font-medium">Runtime</th>
                  <th className="px-4 py-3 text-right text-zinc-500 font-medium">Memory</th>
                  <th className="px-4 py-3 text-center text-zinc-500 font-medium">Optimal</th>
                </tr>
              </thead>
              <tbody>
                {sortedResults?.map((result, index) => (
                  <tr
                    key={result.algorithm}
                    className={`border-b border-zinc-800/50 last:border-0 ${
                      index === 0 ? 'bg-gradient-to-r from-amber-500/10 to-transparent' :
                      index === 1 ? 'bg-gradient-to-r from-zinc-500/10 to-transparent' :
                      index === 2 ? 'bg-gradient-to-r from-amber-700/10 to-transparent' :
                      ''
                    } hover:bg-zinc-800/50 transition-colors`}
                  >
                    <td className="px-4 py-3">
                      {getRankIcon(index)}
                    </td>
                    <td className="px-4 py-3">
                      <span className={index === 0 ? 'text-zinc-100 font-medium' : 'text-zinc-300'}>{result.name}</span>
                      <span className="text-zinc-600 ml-1.5">({result.algorithm})</span>
                    </td>
                    <td className={`px-4 py-3 text-right font-mono ${
                      result.cost === Infinity ? 'text-red-400' :
                      index === 0 ? 'text-amber-400 font-semibold' :
                      result.isOptimal ? 'text-zinc-200' : 'text-zinc-400'
                    }`}>
                      {result.cost === Infinity ? 'No path' : result.cost}
                    </td>
                    <td className="px-4 py-3 text-right font-mono text-zinc-400">
                      {result.nodesExpanded.toLocaleString()}
                    </td>
                    <td className="px-4 py-3 text-right font-mono text-zinc-400">
                      {result.runtimeMs.toFixed(2)}ms
                    </td>
                    <td className="px-4 py-3 text-right font-mono text-zinc-400">
                      {result.memoryKb.toFixed(2)}KB
                    </td>
                    <td className="px-4 py-3 text-center">
                      {result.isOptimal && (
                        <Check className="w-4 h-4 text-emerald-500 mx-auto" />
                      )}
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        </CardContent>
      </Card>
    </div>
  );
};

export default ComparisonDashboard;
