import React, { useEffect, useMemo, useState } from 'react';
import type { CSSProperties, FC, MouseEvent } from 'react';

import TripleStarsIcon from '../icons/TripleStarsIcon';
import { hexToRgb, normalizeHex } from '../../utils/colors';

const DEFAULT_PRIMARY = '#8F0060';
const DEFAULT_SECONDARY = '#0494F7';
const DEFAULT_PRIMARY_RGB = '143, 0, 96';
const DEFAULT_SECONDARY_RGB = '4, 148, 247';

const INTRO_STEP_DURATION = 1500;

const SIZES = {
  small: {
    orbSize: 56,
    orbRadius: 18,
    orbBorder: 3,
    faceRadius: 15,
    logoSize: 30,
    spinSize: 280,
    introIconSize: 24,
    fontSize: 12.5,
    bubbleMaxWidth: 210,
  },
  medium: {
    orbSize: 66,
    orbRadius: 21,
    orbBorder: 3.5,
    faceRadius: 17.5,
    logoSize: 36,
    spinSize: 330,
    introIconSize: 28,
    fontSize: 13,
    bubbleMaxWidth: 235,
  },
  big: {
    orbSize: 78,
    orbRadius: 25,
    orbBorder: 4,
    faceRadius: 21,
    logoSize: 42,
    spinSize: 390,
    introIconSize: 32,
    fontSize: 14,
    bubbleMaxWidth: 265,
  },
} as const;

const InfoIcon = ({ color, size = 40 }: { color: string; size?: number }) => (
  <svg
    width={size}
    height={size}
    viewBox="0 0 42 42"
    fill="none"
    style={{ pointerEvents: 'none' }}
  >
    <path
      d="M21 1.5C9.228 1.5 1.5 9.228 1.5 21s7.728 19.5 19.5 19.5S40.5 32.772 40.5 21 32.772 1.5 21 1.5Zm0 36C10.869 37.5 4.5 31.131 4.5 21S10.869 4.5 21 4.5 37.5 10.869 37.5 21 31.131 37.5 21 37.5Zm3-8.5a1.5 1.5 0 0 1 0 3 3 3 0 0 1-3-3v-7.5a1.5 1.5 0 0 1 0-3 3 3 0 0 1 3 3V29a1.5 1.5 0 0 1 0 3Zm-4.5-17.25a2.25 2.25 0 1 1 1.5 2.25 2.25 2.25 0 0 1-1.5-2.25Z"
      fill={color}
    />
  </svg>
);

const DiscountIcon = ({
  color,
  size = 40,
}: {
  color: string;
  size?: number;
}) => (
  <svg
    width={size}
    height={size}
    viewBox="30 26 60 60"
    fill="none"
    style={{ pointerEvents: 'none' }}
  >
    <path
      d="M78.35 47.28c-.71-.74-1.44-1.5-1.72-2.17-.25-.61-.27-1.63-.28-2.61-.03-1.83-.06-3.9-1.5-5.35-1.44-1.44-3.52-1.47-5.35-1.5-1-.01-2.01-.03-2.61-.28-.67-.28-1.43-1.01-2.17-1.72C63.43 32.41 61.96 31 60 31s-3.43 1.41-4.72 2.65c-.74.71-1.5 1.44-2.17 1.72-.61.25-1.63.27-2.61.28-1.83.03-3.9.06-5.35 1.5-1.44 1.44-1.46 3.52-1.5 5.35-.01 1-.03 2.01-.28 2.61-.28.67-1.01 1.43-1.72 2.17C40.41 48.57 39 50.04 39 52s1.41 3.43 2.65 4.72c.71.74 1.44 1.5 1.72 2.17.25.61.27 1.63.28 2.61.03 1.83.06 3.9 1.5 5.35 1.44 1.44 3.52 1.46 5.35 1.5 1 .01 2.01.03 2.61.28.67.28 1.43 1.01 2.17 1.72C56.57 71.59 58.04 73 60 73s3.43-1.41 4.72-2.65c.74-.71 1.5-1.44 2.17-1.72.61-.25 1.63-.27 2.61-.28 1.83-.03 3.9-.06 5.35-1.5 1.44-1.44 1.46-3.52 1.5-5.35.01-1 .03-2.01.28-2.61.28-.67 1.01-1.43 1.72-2.17C79.59 55.43 81 53.96 81 52s-1.41-3.43-2.65-4.72ZM54 46a4.5 4.5 0 1 1 0 9 4.5 4.5 0 0 1 0-9Zm14.56-.44-17 17a1.5 1.5 0 0 1-2.12-2.12l17-17a1.5 1.5 0 1 1 2.12 2.12ZM66 62.5a4.5 4.5 0 1 1 0-9 4.5 4.5 0 0 1 0 9Z"
      fill={color}
    />
  </svg>
);

const HeartIcon = ({ color, size = 40 }: { color: string; size?: number }) => (
  <svg
    width={size}
    height={size}
    viewBox="30 26 60 60"
    fill="none"
    style={{ pointerEvents: 'none' }}
  >
    <path
      d="M69.38 35.5c-3.87 0-7.26 1.67-9.38 4.48-2.11-2.81-5.5-4.48-9.38-4.48a12.14 12.14 0 0 0-12.12 12.12C38.5 60.75 58.46 71.37 59.29 71.81a1.5 1.5 0 0 0 1.42 0c.83-.44 20.29-11.06 20.29-24.19a12.14 12.14 0 0 0-12.12-12.12ZM60 68.27C56.58 66.28 42 57.19 42 47.13a9.13 9.13 0 0 1 9.13-9.13c3.64 0 6.71 1.94 7.98 5.06a1.5 1.5 0 0 0 2.78 0c1.28-3.13 4.34-5.06 7.98-5.06a9.13 9.13 0 0 1 9.13 9.13c0 10.05-14.58 19.15-18 21.15Z"
      fill={color}
    />
  </svg>
);

type IntroItem = {
  color: string;
  text: string;
  Icon: FC<{ color: string; size?: number }>;
};

const INTRO_ITEMS: IntroItem[] = [
  { color: '#0494F7', text: 'Product details', Icon: InfoIcon },
  { color: '#00AF5B', text: 'Discounts', Icon: DiscountIcon },
  { color: '#FF2828', text: 'Your favorites', Icon: HeartIcon },
];

type BuySmartButtonProps = {
  image: string | File | null;
  position: string;
  popupBorderColorLeft: string;
  popupBorderColorRight: string;
  size?: 'small' | 'medium' | 'big';
  engagementText?: string;
  expanded?: boolean;
  skipIntro?: boolean;
};

export const BuySmartButton = ({
  image,
  position,
  popupBorderColorLeft,
  popupBorderColorRight,
  size = 'medium',
  engagementText = 'Buy smarter with AI',
  expanded,
  skipIntro = false,
}: BuySmartButtonProps) => {
  const metrics = SIZES[size] || SIZES.medium;
  const isOnLeftSide = position === 'left';

  const normPrimary = normalizeHex(popupBorderColorLeft || DEFAULT_PRIMARY);
  const normSecondary = normalizeHex(
    popupBorderColorRight || DEFAULT_SECONDARY
  );
  const primaryRgb = hexToRgb(normPrimary) || DEFAULT_PRIMARY_RGB;
  const secondaryRgb = hexToRgb(normSecondary) || DEFAULT_SECONDARY_RGB;

  const [introIndex, setIntroIndex] = useState(
    skipIntro ? INTRO_ITEMS.length : 0
  );
  const [introDone, setIntroDone] = useState(skipIntro);
  const [nudgeOpen, setNudgeOpen] = useState(expanded ?? true);
  const [nudgeDismissed, setNudgeDismissed] = useState(false);

  useEffect(() => {
    if (expanded !== undefined) setNudgeOpen(expanded);
  }, [expanded]);

  useEffect(() => {
    setNudgeDismissed(false);
  }, [expanded, skipIntro]);

  useEffect(() => {
    if (skipIntro) {
      setIntroDone(true);
      setIntroIndex(INTRO_ITEMS.length);
    } else {
      setIntroDone(false);
      setIntroIndex(0);
    }
  }, [skipIntro]);

  useEffect(() => {
    if (introDone) return;
    if (introIndex >= INTRO_ITEMS.length) {
      setIntroDone(true);
      return;
    }
    const timer = setTimeout(
      () => setIntroIndex(prev => prev + 1),
      INTRO_STEP_DURATION
    );
    return () => clearTimeout(timer);
  }, [introIndex, introDone]);

  const logoUrl = useMemo(
    () => (image instanceof File ? URL.createObjectURL(image) : image),
    [image]
  );

  useEffect(() => {
    if (image instanceof File && logoUrl) {
      return () => URL.revokeObjectURL(logoUrl);
    }
  }, [image, logoUrl]);

  const showIntro = !introDone;
  const safeIndex = Math.min(introIndex, INTRO_ITEMS.length - 1);
  const nudgeVisible =
    nudgeOpen && !nudgeDismissed && (showIntro || Boolean(engagementText));

  const handleDismissNudge = (event: MouseEvent) => {
    event.stopPropagation();
    setNudgeDismissed(true);
  };

  const handleToggleNudge = () => {
    if (nudgeDismissed) {
      setNudgeDismissed(false);
      setNudgeOpen(true);
      return;
    }
    setNudgeOpen(prev => !prev);
  };

  const noDragStyle: CSSProperties = {
    userSelect: 'none',
    WebkitUserSelect: 'none',
  };

  return (
    <div
      className={`flex px-6 pb-10 pt-24 ${isOnLeftSide ? 'justify-start' : 'justify-end'}`}
    >
      <div
        className={`recomaze-ai-launcher${isOnLeftSide ? ' recomaze-ai-launcher--left' : ''}`}
        style={
          {
            '--recomaze-ai-orb-size': `${metrics.orbSize}px`,
            '--recomaze-ai-orb-radius': `${metrics.orbRadius}px`,
            '--recomaze-ai-orb-border': `${metrics.orbBorder}px`,
            '--recomaze-ai-orb-face-radius': `${metrics.faceRadius}px`,
            '--recomaze-ai-orb-spin-size': `${metrics.spinSize}px`,
            '--recomaze-ai-orb-primary': normPrimary,
            '--recomaze-ai-orb-secondary': normSecondary,
            '--recomaze-ai-orb-primary-rgb': primaryRgb,
            '--recomaze-ai-orb-secondary-rgb': secondaryRgb,
            '--recomaze-ai-nudge-max-width': `${metrics.bubbleMaxWidth}px`,
            '--recomaze-ai-nudge-font-size': `${metrics.fontSize}px`,
            ...noDragStyle,
          } as CSSProperties
        }
      >
        <div
          className={
            `recomaze-ai-nudge` +
            `${showIntro ? ' recomaze-ai-nudge--intro' : ''}` +
            `${nudgeVisible ? '' : ' recomaze-ai-nudge--hidden'}`
          }
          aria-hidden={nudgeVisible ? undefined : true}
          onClick={handleToggleNudge}
        >
          <button
            type="button"
            className="recomaze-ai-nudge-close"
            onClick={handleDismissNudge}
            aria-label="Dismiss message"
          >
            <svg
              width="11"
              height="11"
              viewBox="0 0 24 24"
              fill="none"
              stroke="currentColor"
              strokeWidth="3"
              strokeLinecap="round"
              strokeLinejoin="round"
            >
              <path d="M18 6 6 18" />
              <path d="m6 6 12 12" />
            </svg>
          </button>

          {showIntro ? (
            <div
              className="recomaze-ai-nudge-intro"
              style={{ height: metrics.introIconSize }}
            >
              {INTRO_ITEMS.map((item, i) => (
                <div
                  key={item.text}
                  className={
                    `recomaze-ai-nudge-intro-item` +
                    `${i === safeIndex ? ' recomaze-ai-nudge-intro-item--on' : ''}` +
                    `${i < safeIndex ? ' recomaze-ai-nudge-intro-item--past' : ''}`
                  }
                  style={{ color: item.color }}
                >
                  <item.Icon color={item.color} size={metrics.introIconSize} />
                  <span className="recomaze-ai-nudge-intro-text">
                    {item.text}
                  </span>
                </div>
              ))}
            </div>
          ) : (
            <p className="recomaze-ai-nudge-text">{engagementText}</p>
          )}
        </div>

        <button
          type="button"
          className="recomaze-ai-orb"
          onClick={handleToggleNudge}
          aria-label={engagementText || 'Buy smarter with AI'}
          style={noDragStyle}
        >
          <span className="recomaze-ai-orb-ring" aria-hidden="true" />
          <span className="recomaze-ai-orb-body">
            <span className="recomaze-ai-orb-gradient" aria-hidden="true" />
            <span className="recomaze-ai-orb-face">
              {logoUrl ? (
                <img
                  src={logoUrl}
                  alt="logo"
                  draggable={false}
                  className="recomaze-ai-orb-logo"
                  style={{
                    width: metrics.logoSize,
                    height: metrics.logoSize,
                    ...noDragStyle,
                  }}
                />
              ) : (
                <div
                  style={{
                    width: metrics.logoSize,
                    height: metrics.logoSize,
                    display: 'flex',
                    alignItems: 'center',
                    justifyContent: 'center',
                    pointerEvents: 'none',
                  }}
                >
                  <TripleStarsIcon
                    colorLeft={normPrimary}
                    colorRight={normSecondary}
                    className="w-full h-full"
                  />
                </div>
              )}
            </span>
          </span>
        </button>
      </div>
    </div>
  );
};
