import React, { useState, useMemo, type SetStateAction } from 'react';

import { Card } from '../card';
import { colors } from '../colors';
import { Popover } from '../popover';

const SHADES = ['200', '300', '400', '500', '600', '700', '800'] as const;

const ORDERED_COLOR_NAMES = [
  's-green',
  's-red',
  'orange',
  's-yellow',
  'purple',
  'gray',
  'green',
  's-pink',
  'pink',
  'cyan',
  's-purple',
  's-blue',
] as const;

type ColorPickerProps = {
  value?: string;
  setValue: (value: string) => void;
  children: React.ReactNode;
  isOpen: boolean;
  setIsOpen: React.Dispatch<SetStateAction<boolean>>;
};

export function ColorPicker({ value, setValue, children, isOpen, setIsOpen }: ColorPickerProps) {
  const [hoveredColor, setHoveredColor] = useState<string | null>(null);

  const colorLookupMap = useMemo(() => {
    const map = new Map();
    ORDERED_COLOR_NAMES.forEach(colorName => {
      SHADES.forEach(shade => {
        const color = colors[colorName];
        map.set(color[shade], `${colorName} ${shade}`);
      });
    });
    return map;
  }, []);

  const getColorNameAndHue = (colorValue?: string): string => {
    return colorLookupMap.get(colorValue) || 'Color Name and Hue not found';
  };

  const displayedColorInfo = hoveredColor || value ? getColorNameAndHue(hoveredColor ?? value) : 'Select a color';

  const handleColorSelect = (colorValue: string) => {
    setValue(colorValue);
    setIsOpen(false);
  };

  const handleMouseEnter = (colorValue: string) => setHoveredColor(colorValue);
  const handleMouseLeave = () => setHoveredColor(null);

  return (
    <Popover
      open={isOpen}
      side="bottom"
      hasArrow
      onOpenChange={setIsOpen}
      content={
        <Card variant="elevate" className=" border border-solid border-border p-5">
          <div className="mb-3">
            <span className="text-sm font-bold capitalize">{displayedColorInfo}</span>
            <span className="ml-4 text-sm italic text-gray-500-400">{hoveredColor ?? value}</span>
          </div>

          <div className="grid grid-cols-12">
            {ORDERED_COLOR_NAMES.map(colorName => (
              <div key={colorName}>
                {SHADES.map(shade => {
                  const colorValue = colors[colorName][shade];

                  return (
                    <div
                      key={colorValue}
                      className="cursor-pointer rounded p-0.5"
                      onClick={() => handleColorSelect(colorValue)}
                      onMouseEnter={() => handleMouseEnter(colorValue)}
                      onMouseLeave={handleMouseLeave}
                    >
                      <div className="h-5 w-5" style={{ backgroundColor: colorValue }} />
                    </div>
                  );
                })}
              </div>
            ))}
          </div>
        </Card>
      }
    >
      {children}
    </Popover>
  );
}
