import { useMemo } from "react";
import { Card, CardContent } from "@/components/ui/card";
import { DiscountSimulationBucket } from "@/types/discount-simulator";
import { Skeleton } from "@/components/ui/skeleton";
import {
  Chart as ChartJS,
  CategoryScale,
  LinearScale,
  PointElement,
  LineElement,
  Tooltip,
  TooltipItem,
} from "chart.js";
import { Line } from "react-chartjs-2";

ChartJS.register(CategoryScale, LinearScale, PointElement, LineElement, Tooltip);

// Utility function to interpolate between two colors
const interpolateColor = (color1: [number, number, number], color2: [number, number, number], ratio: number): [number, number, number] => {
  return [
    Math.round(color1[0] + (color2[0] - color1[0]) * ratio),
    Math.round(color1[1] + (color2[1] - color1[1]) * ratio),
    Math.round(color1[2] + (color2[2] - color1[2]) * ratio)
  ];
};

// Utility function to calculate color based on profit percentage
const getProfitPercentageColor = (percentage: number): string => {
  const percent = percentage * 100; // Convert to percentage
  
  // Define color points (RGB values for red-400, yellow-400, green-400)
  const red: [number, number, number] = [248, 113, 113]; // red-400
  const yellow: [number, number, number] = [251, 191, 36]; // yellow-400
  const green: [number, number, number] = [74, 222, 128]; // green-400
  
  const min = 25;
  const mid = 29;
  const max = 35;
  
  let rgb: [number, number, number];
  
  if (percent <= min) {
    rgb = red;
  } else if (percent >= max) {
    rgb = green;
  } else if (percent <= mid) {
    // Interpolate between red and yellow
    const ratio = (percent - min) / (mid - min);
    rgb = interpolateColor(red, yellow, ratio);
  } else {
    // Interpolate between yellow and green
    const ratio = (percent - mid) / (max - mid);
    rgb = interpolateColor(yellow, green, ratio);
  }
  
  return `rgb(${rgb[0]}, ${rgb[1]}, ${rgb[2]})`;
};

interface ResultsChartProps {
  buckets: DiscountSimulationBucket[];
  isLoading: boolean;
}

export function ResultsChart({ buckets, isLoading }: ResultsChartProps) {
  const chartData = useMemo(() => {
    if (!buckets || buckets.length === 0) {
      return null;
    }

    const labels = buckets.map((bucket) => {
      if (bucket.max == null) {
        return `$${bucket.min.toLocaleString()}+`;
      }
      return `$${bucket.min.toLocaleString()}–$${bucket.max.toLocaleString()}`;
    });
    const profitPercentages = buckets.map((bucket) => Number((bucket.profitPercent * 100).toFixed(2)));
    
    // Generate colors for each point based on profit percentage
    const pointColors = buckets.map((bucket) => getProfitPercentageColor(bucket.profitPercent));
    
    return {
      labels,
      datasets: [
        {
          label: 'Profit %',
          data: profitPercentages,
          borderColor: (context: any) => {
            const chart = context.chart;
            const {ctx, chartArea} = chart;
            
            if (!chartArea) {
              return 'rgb(156, 163, 175)'; // fallback color
            }
            
            // Create gradient that changes color based on data points
            const gradient = ctx.createLinearGradient(chartArea.left, 0, chartArea.right, 0);
            
            // Add color stops based on data points
            profitPercentages.forEach((_, index) => {
              const stop = index / (profitPercentages.length - 1);
              gradient.addColorStop(stop, pointColors[index]);
            });
            
            return gradient;
          },
          backgroundColor: pointColors,
          pointBackgroundColor: pointColors,
          pointBorderColor: pointColors,
          pointRadius: 6,
          pointHoverRadius: 8,
          tension: 0,
          fill: false,
        },
      ],
    };
  }, [buckets]);

  const yAxisBounds = useMemo(() => {
    const populated = buckets.filter((bucket) => bucket.orderCount > 0);
    if (populated.length === 0) {
      return { min: 0, max: 50 };
    }
    const values = populated.map((bucket) => bucket.profitPercent * 100);
    const rawMin = Math.min(...values, 0);
    const rawMax = Math.max(...values, 0);
    const span = Math.max(rawMax - rawMin, 5);
    const pad = Math.max(span * 0.1, 1);
    const min = Math.floor((rawMin - pad) / 5) * 5;
    const max = Math.ceil((rawMax + pad) / 5) * 5;
    return { min, max: Math.max(max, min + 5) };
  }, [buckets]);

  const options = useMemo(() => ({
    responsive: true,
    maintainAspectRatio: false,
    layout: {
      padding: {
        left: 0,
        right: 0,
        top: 0,
        bottom: 0,
      },
    },
    interaction: {
      mode: 'index' as const,
      intersect: false,
    },
    plugins: {
      tooltip: {
        callbacks: {
          label: (context: TooltipItem<'line'>) => {
            const dataIndex = context.dataIndex;
            const bucket = buckets[dataIndex];
            if (bucket) {
              const profitPercent = context.parsed.y.toFixed(2);
              const profitDollar = bucket.profit.toLocaleString('en-US', {
                style: 'currency',
                currency: 'USD',
                minimumFractionDigits: 2,
                maximumFractionDigits: 2,
              });
              return [`Profit: ${profitPercent}%`, `Amount: ${profitDollar}`];
            }
            return `Profit: ${context.parsed.y.toFixed(2)}%`;
          },
        },
      },
    },
    scales: {
      y: {
        type: 'linear' as const,
        display: true,
        position: 'left' as const,
        min: yAxisBounds.min,
        max: yAxisBounds.max,
        ticks: {
          stepSize: 5,
          callback: (value: number | string) => `${Number(value).toFixed(0)}`,
        },
        title: {
          display: true,
          text: 'Profit %',
        },
      },
      x: {
        display: true,
        ticks: {
          maxRotation: 90,
          minRotation: 90,
          autoSkip: true, // Allow skipping labels if needed
        },
      },
    },
  }), [buckets, yAxisBounds]);

  if (isLoading && !chartData) {
    return (
      <Card className="pt-6">
        <CardContent>
          <Skeleton className="h-72 w-full" />
        </CardContent>
      </Card>
    );
  }

  if (!chartData) {
    return null;
  }

  return (
    <Card className="pt-6">
      <CardContent>
        <div className="h-72 w-full overflow-hidden">
          <Line data={chartData} options={options} />
        </div>
      </CardContent>
    </Card>
  );
}

