import { useState } from 'react';
import { motion, AnimatePresence } from 'framer-motion';
import type { OffsetProject } from '../types';
import { getProjectColor, hexToRgba } from '../utils/portfolioColors';

interface PortfolioDonutChartProps {
  projects: OffsetProject[];
  totalTons: number;
  size?: number;
  className?: string;
}

interface SegmentPath {
  d: string;
  percentage: number;
  project: OffsetProject;
  color: string;
  index: number;
}

export function PortfolioDonutChart({
  projects,
  totalTons,
  size = 240,
  className = '',
}: PortfolioDonutChartProps) {
  const [hoveredIndex, setHoveredIndex] = useState<number | null>(null);
  const [tooltipPosition, setTooltipPosition] = useState<{ x: number; y: number } | null>(null);
  const [containerWidth, setContainerWidth] = useState<number>(0);
  const [clickedIndex, setClickedIndex] = useState<number | null>(null);
  const centerX = size / 2;
  const centerY = size / 2;
  const radius = size * 0.35;
  const innerRadius = size * 0.25;

  // Generate SVG path for a donut segment
  const createSegmentPath = (
    startAngle: number,
    endAngle: number,
    outerR: number,
    innerR: number
  ): string => {
    const start = polarToCartesian(centerX, centerY, outerR, endAngle);
    const end = polarToCartesian(centerX, centerY, outerR, startAngle);
    const innerStart = polarToCartesian(centerX, centerY, innerR, endAngle);
    const innerEnd = polarToCartesian(centerX, centerY, innerR, startAngle);

    const largeArcFlag = endAngle - startAngle <= 180 ? '0' : '1';

    return [
      'M', start.x, start.y,
      'A', outerR, outerR, 0, largeArcFlag, 0, end.x, end.y,
      'L', innerEnd.x, innerEnd.y,
      'A', innerR, innerR, 0, largeArcFlag, 1, innerStart.x, innerStart.y,
      'Z',
    ].join(' ');
  };

  const polarToCartesian = (centerX: number, centerY: number, radius: number, angleInDegrees: number) => {
    const angleInRadians = ((angleInDegrees - 90) * Math.PI) / 180.0;
    return {
      x: centerX + radius * Math.cos(angleInRadians),
      y: centerY + radius * Math.sin(angleInRadians),
    };
  };

  // Calculate segments
  const segments: SegmentPath[] = [];
  let currentAngle = 0;

  projects.forEach((project, index) => {
    if (!project.percentage) return;

    const percentage = project.percentage * 100;
    const segmentAngle = (percentage / 100) * 360;
    const color = getProjectColor(index);

    segments.push({
      d: createSegmentPath(currentAngle, currentAngle + segmentAngle, radius, innerRadius),
      percentage,
      project,
      color,
      index,
    });

    currentAngle += segmentAngle;
  });

  const handleSegmentMouseEnter = (index: number, e: React.MouseEvent) => {
    setHoveredIndex(index);
    const container = e.currentTarget.closest('.donut-container');
    if (container) {
      const rect = container.getBoundingClientRect();
      setContainerWidth(rect.width);
      setTooltipPosition({
        x: e.clientX - rect.left,
        y: e.clientY - rect.top,
      });
    }
  };

  const handleSegmentMouseMove = (e: React.MouseEvent) => {
    const container = e.currentTarget.closest('.donut-container');
    if (container && hoveredIndex !== null) {
      const rect = container.getBoundingClientRect();
      setContainerWidth(rect.width);
      setTooltipPosition({
        x: e.clientX - rect.left,
        y: e.clientY - rect.top,
      });
    }
  };

  const handleSegmentMouseLeave = () => {
    // Don't clear if segment is clicked (for mobile)
    if (clickedIndex === null) {
      setHoveredIndex(null);
      setTooltipPosition(null);
    }
  };

  const handleLegendClick = (index: number) => {
    // Toggle off if clicking the same item, otherwise switch to new item
    if (hoveredIndex === index) {
      setHoveredIndex(null);
    } else {
      setHoveredIndex(index);
    }
  };

  const handleLegendMouseEnter = (index: number) => {
    // Only respond to hover on desktop
    if (clickedIndex === null && window.innerWidth >= 768) {
      setHoveredIndex(index);
    }
  };

  const handleLegendMouseLeave = () => {
    // Only clear hover on desktop
    if (clickedIndex === null && window.innerWidth >= 768) {
      setHoveredIndex(null);
    }
  };

  return (
    <div className={`flex flex-col items-center ${className}`}>
      {/* Donut Chart */}
      <div
        className="relative w-full max-w-sm md:max-w-lg lg:max-w-xl mx-auto donut-container"
        style={{ aspectRatio: '1/1' }}
        onClick={(e) => {
          // Clear clicked state when clicking on the container (but not on a segment)
          if (e.target === e.currentTarget) {
            setClickedIndex(null);
            setHoveredIndex(null);
            setTooltipPosition(null);
          }
        }}
      >
        <svg
          width="100%"
          height="100%"
          viewBox={`0 0 ${size} ${size}`}
          className="transform rotate-0"
          preserveAspectRatio="xMidYMid meet"
        >
          {segments.map((segment, _index) => (
              <motion.path
                key={segment.project.id || segment.index}
                d={segment.d}
                fill={segment.color}
                initial={{ opacity: 0 }}
                animate={{
                  opacity: hoveredIndex === null || hoveredIndex === segment.index ? 1 : 0.4,
                }}
                transition={{
                  duration: 0.15,
                  delay: segment.index * 0.02,
                  ease: [0.22, 1, 0.36, 1],
                }}
                onMouseEnter={(e) => handleSegmentMouseEnter(segment.index, e)}
                onMouseMove={handleSegmentMouseMove}
                onMouseLeave={handleSegmentMouseLeave}
                className="md:cursor-pointer transition-all"
                style={{
                  transformOrigin: `${centerX}px ${centerY}px`,
                  filter: hoveredIndex === segment.index ? 'drop-shadow(0 4px 8px rgba(0,0,0,0.2))' : 'none',
                }}
              />
            ))}
        </svg>

        {/* Floating Tooltip - Desktop only */}
        <div className="hidden md:block">
          <AnimatePresence>
            {hoveredIndex !== null && tooltipPosition && segments[hoveredIndex] && (() => {
            // Position tooltip ABOVE cursor to avoid overlap consistently
            const cursorClearance = 60; // Space above cursor for tooltip
            const estimatedTooltipWidth = 250;
            const padding = 16;

            // Always center tooltip on cursor horizontally
            let finalLeftPos = tooltipPosition.x;
            const transformX = '-50%'; // Always center

            // Calculate where tooltip edges would be with centering
            const tooltipLeftEdge = finalLeftPos - estimatedTooltipWidth / 2;
            const tooltipRightEdge = finalLeftPos + estimatedTooltipWidth / 2;

            // Smoothly constrain position to stay within viewport
            if (tooltipLeftEdge < padding) {
              // Shift right just enough to fit
              finalLeftPos = padding + estimatedTooltipWidth / 2;
            } else if (tooltipRightEdge > containerWidth - padding) {
              // Shift left just enough to fit
              finalLeftPos = containerWidth - padding - estimatedTooltipWidth / 2;
            }

            return (
              <motion.div
                initial={{ opacity: 0, y: 5 }}
                animate={{ opacity: 1, y: 0 }}
                exit={{ opacity: 0, y: 5 }}
                transition={{ duration: 0.1 }}
                className="absolute pointer-events-none z-50"
                style={{
                  left: `${finalLeftPos}px`,
                  top: `${tooltipPosition.y - cursorClearance}px`,
                  transform: `translate(${transformX}, -100%)`,
                  maxWidth: `${containerWidth - padding * 2}px`,
                }}
              >
                <div className="bg-gray-900 text-white px-3 py-2 rounded-lg shadow-xl">
                  <div className="font-semibold text-sm whitespace-nowrap overflow-hidden text-ellipsis">
                    {segments[hoveredIndex].project.name}
                  </div>
                  <div className="text-xs text-gray-300 mt-0.5 whitespace-nowrap">
                    {segments[hoveredIndex].percentage.toFixed(1)}% · {(totalTons * segments[hoveredIndex].project.percentage!).toFixed(2)} tons
                  </div>
                </div>
              </motion.div>
            );
          })()}
          </AnimatePresence>
        </div>

        {/* Center content */}
        <div className="absolute inset-0 flex flex-col items-center justify-center pointer-events-none">
          <AnimatePresence mode="wait">
            {hoveredIndex !== null ? (
              <motion.div
                key="hovered"
                initial={{ opacity: 0, scale: 0.8 }}
                animate={{ opacity: 1, scale: 1 }}
                exit={{ opacity: 0, scale: 0.8 }}
                transition={{ duration: 0.1 }}
                className="text-center px-4"
              >
                <div className="hidden md:block text-xs text-gray-600 mb-1 break-words text-center leading-tight max-w-[180px]">
                  {segments[hoveredIndex].project.name}
                </div>
                <div className="text-2xl font-bold text-gray-900">
                  {segments[hoveredIndex].percentage.toFixed(1)}%
                </div>
                <div className="text-xs text-gray-500">
                  {(totalTons * segments[hoveredIndex].project.percentage!).toFixed(2)} tons
                </div>
              </motion.div>
            ) : (
              <motion.div
                key="default"
                initial={{ opacity: 0, scale: 0.8 }}
                animate={{ opacity: 1, scale: 1 }}
                exit={{ opacity: 0, scale: 0.8 }}
                transition={{ duration: 0.1 }}
                className="text-center"
              >
                <div className="text-xs text-gray-600 mb-1">Total CO₂</div>
                <div className="text-2xl font-bold text-gray-900">{totalTons.toFixed(2)}</div>
                <div className="text-xs text-gray-500">tons</div>
              </motion.div>
            )}
          </AnimatePresence>
        </div>
      </div>

      {/* Legend */}
      <div className="mt-2 grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-3 w-full">
        {segments.map((segment) => (
          <motion.div
            key={segment.project.id || segment.index}
            className="flex items-center gap-2 cursor-pointer p-2 rounded-lg transition-colors"
            onClick={() => handleLegendClick(segment.index)}
            onMouseEnter={() => handleLegendMouseEnter(segment.index)}
            onMouseLeave={handleLegendMouseLeave}
            initial={{ opacity: 0, y: 10 }}
            animate={{ opacity: 1, y: 0 }}
            transition={{ delay: segment.index * 0.02, duration: 0.2 }}
            style={{
              backgroundColor: hoveredIndex === segment.index ? hexToRgba(segment.color, 0.1) : 'transparent',
            }}
          >
            <div
              className="w-3 h-3 rounded-full flex-shrink-0"
              style={{ backgroundColor: segment.color }}
            />
            <div className="flex-1 min-w-0">
              <div className="text-xs font-medium text-gray-900 leading-tight break-words">
                {segment.project.name}
              </div>
              <div className="text-xs text-gray-500">
                {segment.percentage.toFixed(1)}%
              </div>
            </div>
          </motion.div>
        ))}
      </div>
    </div>
  );
}
