import React, { useEffect, useRef, useState } from 'react';
import { HexColorInput, HexColorPicker } from 'react-colorful';
import { FaEdit, FaPlus } from 'react-icons/fa';
import { Link } from 'react-router-dom';

import { IPopupData, IQuickAction } from '../../service/popup/popup.interface';
import { saveLogo, savePopupData } from '../../service/popup/popup.service';
import { hexToRgba } from '../../utils/rgbaUtil';
import Banner from '../widgets/Banner';
import ErrorWrapper from '../alert/ErrorWrapper';
import Button from '../widgets/Button';
import { useAppStateContext } from '../../context/user.data.context';

const PopoverColorPicker = ({
  color,
  onChange,
}: {
  color: string;
  onChange: (color: string) => void;
}) => {
  const [isOpen, setIsOpen] = useState(false);
  const [popoverStyle, setPopoverStyle] = useState<React.CSSProperties>({});
  const popoverRef = useRef<HTMLDivElement>(null);
  const triggerRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    if (!isOpen) return;
    const handleClickOutside = (e: MouseEvent) => {
      if (
        popoverRef.current &&
        !popoverRef.current.contains(e.target as Node) &&
        triggerRef.current &&
        !triggerRef.current.contains(e.target as Node)
      ) {
        setIsOpen(false);
      }
    };
    document.addEventListener('mousedown', handleClickOutside);

    return () => document.removeEventListener('mousedown', handleClickOutside);
  }, [isOpen]);

  useEffect(() => {
    if (!isOpen) return;

    const handleScrollOrResize = () => {
      updatePosition();
    };

    window.addEventListener('scroll', handleScrollOrResize, true);
    window.addEventListener('resize', handleScrollOrResize);

    return () => {
      window.removeEventListener('scroll', handleScrollOrResize, true);
      window.removeEventListener('resize', handleScrollOrResize);
    };
  }, [isOpen]);

  const updatePosition = () => {
    if (!triggerRef.current) return;
    const rect = triggerRef.current.getBoundingClientRect();
    const popoverHeight = 290;
    const popoverWidth = 232;
    const spaceBelow = window.innerHeight - rect.bottom;
    const spaceRight = window.innerWidth - rect.left;
    const openAbove = spaceBelow < popoverHeight && rect.top > popoverHeight;
    const openLeft = spaceRight < popoverWidth;

    setPopoverStyle({
      position: 'fixed' as const,
      left: openLeft ? Math.max(8, rect.right - popoverWidth) : rect.left,
      top: openAbove ? rect.top - popoverHeight - 8 : rect.bottom + 8,
      zIndex: 9999,
    });
  };

  const handleToggle = () => {
    if (!isOpen) updatePosition();
    setIsOpen(!isOpen);
  };

  return (
    <div>
      <div
        ref={triggerRef}
        onClick={handleToggle}
        className="relative border border-zinc-300 hover:border-zinc-400 bg-white w-8 h-8 p-[2px] rounded-full cursor-pointer text-xs flex justify-center items-center transition-colors"
      >
        <div
          className="rounded-full relative w-full h-full"
          style={{ backgroundColor: color }}
        >
          <div className="absolute -right-1 -bottom-1 bg-zinc-200 rounded-full border border-zinc-300 p-0.5 flex items-center justify-center h-[18px] w-[18px]">
            <FaPlus className="text-[8px] text-zinc-500" />
          </div>
        </div>
      </div>

      {isOpen && (
        <div
          ref={popoverRef}
          style={popoverStyle}
          className="p-3 bg-white rounded-lg shadow-lg border border-zinc-200 space-y-2"
        >
          <HexColorPicker color={color} onChange={onChange} />
          <HexColorInput
            color={color}
            onChange={onChange}
            prefixed
            className="w-full border border-zinc-200 rounded px-2 py-1 text-sm font-mono focus:outline-none focus:border-zinc-400"
          />
        </div>
      )}
    </div>
  );
};

const ColorField = ({
  label,
  color,
  onChange,
  hint,
}: {
  label: string;
  color: string;
  onChange: (c: string) => void;
  hint?: string;
}) => (
  <div className="space-y-2">
    <p className="text-sm font-semibold text-zinc-900">{label}</p>
    <div className="flex items-center gap-3">
      <PopoverColorPicker color={color} onChange={onChange} />
      <HexColorInput
        color={color}
        onChange={onChange}
        prefixed
        className="text-xs font-mono text-zinc-700 bg-zinc-50 px-2 py-1.5 rounded border border-zinc-200 outline-none focus:border-zinc-400 focus:bg-white w-[76px] uppercase transition-colors"
      />
    </div>
    {hint && <p className="text-xs text-zinc-500">{hint}</p>}
  </div>
);

const PositionSelector = ({
  position,
  setPosition,
}: {
  position: string;
  setPosition: (p: string) => void;
}) => (
  <div className="space-y-2">
    <p className="text-sm font-semibold text-zinc-900">Widget Position</p>
    <div className="grid grid-cols-2 gap-3">
      {[
        { value: 'left', label: 'Bottom Left' },
        { value: 'right', label: 'Bottom Right' },
      ].map(opt => {
        const isActive = position === opt.value;

        return (
          <button
            key={opt.value}
            type="button"
            onClick={() => setPosition(opt.value)}
            className={[
              'relative flex flex-col items-center gap-2 rounded-xl border-2 p-3 transition-all cursor-pointer',
              isActive
                ? 'border-black bg-zinc-50 shadow-sm'
                : 'border-zinc-200 bg-white hover:border-zinc-300',
            ].join(' ')}
          >
            <div className="w-full h-14 rounded-md bg-zinc-100 border border-zinc-200 relative overflow-hidden">
              <div className="absolute top-1 left-1 right-1 h-2 rounded-sm bg-zinc-200" />
              <div
                className={[
                  'absolute w-4 h-4 rounded-md transition-all',
                  isActive ? 'bg-black' : 'bg-zinc-400',
                  opt.value === 'left' ? 'bottom-1 left-1' : 'bottom-1 right-1',
                ].join(' ')}
              />
            </div>
            <span
              className={[
                'text-xs font-medium',
                isActive ? 'text-black' : 'text-zinc-500',
              ].join(' ')}
            >
              {opt.label}
            </span>
            {isActive && (
              <div className="absolute -top-1 -right-1 w-4 h-4 bg-black rounded-full flex items-center justify-center">
                <svg width="10" height="10" viewBox="0 0 10 10" fill="none">
                  <path
                    d="M2 5L4.5 7.5L8 3"
                    stroke="white"
                    strokeWidth="1.5"
                    strokeLinecap="round"
                    strokeLinejoin="round"
                  />
                </svg>
              </div>
            )}
          </button>
        );
      })}
    </div>
  </div>
);

type Props = {
  token?: string | null;
  image: File | string | null;
  imageName: string;
  setImage: (image: File) => void;
  setImageName: (name: string) => void;
  popup: IPopupData | null;
  user?: any;
  popupBorderColorLeft: string;
  popupBorderColorRight: string;
  setPopupBorderColorLeft: (color: string) => void;
  setPopupBorderColorRight: (color: string) => void;
  textColor: string;
  setTextColor: (color: string) => void;
  buttonColor: string;
  setButtonColor: (color: string) => void;
  onResetDefaultColors: () => void;
  position: string;
  setPosition: (position: string) => void;
  headerMessage: string | null;
  expandedHeaderMessage: string | null;
  sourceVideo: string | null;
  cartIconColor: string;
  setCartIconColor: (color: string) => void;
  restoreOnNavigation: boolean;
  defaultState: 'minimized' | 'partial' | 'expanded';
  size: 'small' | 'medium' | 'big';
  showPrices: boolean;
  showAddToCartButton: boolean;
  quickActions?: IQuickAction[];
};

type IErrors = {
  popupBorderColorLeft: boolean;
  popupBorderColorRight: boolean;
  textColor: boolean;
  buttonColor: boolean;
};

const CustomizationStyles = ({
  // token,
  popup,
  image,
  buttonColor,
  popupBorderColorLeft,
  popupBorderColorRight,
  imageName,
  setImageName,
  setButtonColor,
  setPopupBorderColorLeft,
  setPopupBorderColorRight,
  setTextColor,
  textColor,
  setImage,
  onResetDefaultColors,
  position,
  setPosition,
  headerMessage,
  expandedHeaderMessage,
  sourceVideo,
  cartIconColor,
  setCartIconColor,
  restoreOnNavigation,
  defaultState,
  showAddToCartButton,
  showPrices,
  size,
  quickActions,
}: Props) => {
  const [loading, setLoading] = useState<boolean>(false);
  const [success, setSuccess] = useState<boolean>(false);

  const { user, completeOnboardingStep } = useAppStateContext();

  const [showGradientModal, setShowGradientModal] = useState<boolean>(false);
  const [apiError, setApiError] = useState<string | null>(null);

  const imageUploadRef = useRef<HTMLInputElement>(null);
  const modalRef = useRef<HTMLDivElement>(null);
  const modalTriggerRef = useRef<HTMLDivElement>(null);

  const allowedPlans = ['SCALING', 'HYPER_SCALING'];
  const planKey = (user?.plan_snapshot ?? '').toString().toUpperCase();
  const hasAllowedPlan = allowedPlans.includes(planKey);
  const logoBlocked = !hasAllowedPlan;

  const handleClick = (ref: React.RefObject<HTMLInputElement>) => {
    if (ref.current) ref.current?.click();
  };

  useEffect(() => {
    const handleClickOutside = (event: any) => {
      if (
        modalRef.current &&
        !modalRef.current.contains(event.target) &&
        modalTriggerRef.current &&
        !modalTriggerRef.current.contains(event.target)
      ) {
        setShowGradientModal(false);
      }
    };
    document.addEventListener('mousedown', handleClickOutside);

    return () => document.removeEventListener('mousedown', handleClickOutside);
  }, []);

  useEffect(() => {
    if (apiError || success) {
      const timer: NodeJS.Timeout = setTimeout(() => {
        setApiError(null);
        setSuccess(false);
      }, 3000);

      return () => clearTimeout(timer);
    }
  }, [success, apiError]);

  const saveSettings = async (): Promise<void> => {
    try {
      const validation: IErrors = {
        popupBorderColorLeft: popupBorderColorLeft.length === 0,
        popupBorderColorRight: popupBorderColorRight.length === 0,
        textColor: textColor.length === 0,
        buttonColor: buttonColor.length === 0,
      };

      if (
        validation.popupBorderColorLeft ||
        validation.popupBorderColorRight ||
        validation.textColor ||
        validation.buttonColor
      ) {
        return;
      }

      setLoading(true);
      const response = await savePopupData({
        color: hexToRgba(textColor),
        secondary_color: hexToRgba(buttonColor),
        settings: {
          cart_icon_color: cartIconColor,
          text_color: textColor,
          button_color: buttonColor,
          gradient_colors: [popupBorderColorLeft, popupBorderColorRight],
          restore_on_navigation: restoreOnNavigation,
          show_add_to_cart_button: showAddToCartButton,
          show_prices: showPrices,
          size,
          quick_actions: quickActions,
        },
        position: position,
        header_message: popup?.header_message || 'Keep browsing to unlock',
        unlocked_popup_message:
          popup?.unlocked_popup_message || 'Premium Recommendations Unlocked',
        expanded_header_message: popup?.expanded_header_message,
        buy_now_button_message: popup?.buy_now_button_message || 'Add to cart',
        locked_popup_message:
          popup?.locked_popup_message || 'Keep browsing to unlock',
        toggle_button_message: popup?.toggle_button_message || 'Discover',
        search_more_message:
          popup?.search_more_message ||
          "Keep exploring! We'll have more personalized picks for you soon.",
        like_button_message: 'like',
        dislike_button_message: 'dislike',
        loading_message: 'Reveal Secret Deals!',
        come_back_button_message: 'Come back for more',
        in_stock_message: 'In stock',
        link_copied_message: 'Link copied',
        engagement_messages: {
          expanded_header_message: expandedHeaderMessage?.slice(0, 130),
          header_message: headerMessage?.slice(0, 90),
        },
        source_video: sourceVideo,
        use_stock: popup?.use_stock || true,
        default_state: defaultState || popup?.default_state || 'minimized',
        default_state_mobile: popup?.default_state_mobile || 'minimized',
      });

      setLoading(false);
      if (response?.success) {
        setSuccess(true);
        completeOnboardingStep('customize');
      }
    } catch (error) {
      console.log('API ERROR: ', error);
      setApiError(String(error));
      setLoading(false);
    }
  };

  const onPopupLogoUpload = async (
    e: React.ChangeEvent<HTMLInputElement>
  ): Promise<any> => {
    e.preventDefault();

    if (logoBlocked) {
      setApiError(
        'Custom logo upload is available on the Hyper-Scaling plan. Upgrade to unlock branding.'
      );

      return;
    }

    try {
      if (e.target.files && e.target.files[0]) {
        setImage(e.target.files[0]);
        setImageName(e.target.files[0].name);

        const formData: FormData = new FormData();
        formData.append('file', e.target.files[0]);
        formData.append('file_type', 'LOGO');
        formData.append('model_type', 'LOGO');
        formData.append('model_id', user?.id as string);

        if (user) {
          await saveLogo(formData);
        }
      }
    } catch (error) {
      console.log(error);
    }
  };

  return (
    <div className="space-y-6">
      <div className="space-y-2">
        <div className="flex items-center justify-between">
          <p className="text-base font-semibold text-zinc-900">Colors</p>
          <button
            type="button"
            onClick={onResetDefaultColors}
            className="inline-flex items-center gap-1.5 rounded-lg border border-zinc-200 bg-white px-3 py-1.5 text-xs font-medium text-zinc-600 hover:bg-zinc-50 hover:border-zinc-300 transition-colors"
          >
            <svg width="12" height="12" viewBox="0 0 12 12" fill="none">
              <path
                d="M1.5 1.5V4.5H4.5"
                stroke="currentColor"
                strokeWidth="1.2"
                strokeLinecap="round"
                strokeLinejoin="round"
              />
              <path
                d="M2.09 7.5A4.5 4.5 0 1 0 2.5 4L1.5 4.5"
                stroke="currentColor"
                strokeWidth="1.2"
                strokeLinecap="round"
                strokeLinejoin="round"
              />
            </svg>
            Reset to defaults
          </button>
        </div>
        <p className="text-xs text-zinc-500">
          Customize your widget to match your store branding.
        </p>
      </div>

      <div className="space-y-5">
        <ColorField
          label="Text Color"
          color={textColor}
          onChange={setTextColor}
          hint="Applied to headings, body text, and labels inside the widget."
        />

        <ColorField
          label="Button Color"
          color={buttonColor}
          onChange={setButtonColor}
          hint="Used for primary action buttons like Add to Cart. Darker shades work best."
        />

        <ColorField
          label="Cart Text Color"
          color={cartIconColor}
          onChange={setCartIconColor}
          hint="Text and icon color inside the cart button. Use white for dark button backgrounds."
        />

        <div className="space-y-2">
          <p className="text-sm font-semibold text-zinc-900">
            Popup Border Gradient
          </p>
          <div className="flex items-center gap-3">
            <div className="relative">
              <div className="relative border border-zinc-300 hover:border-zinc-400 bg-white w-8 h-8 p-[2px] rounded-full cursor-pointer text-xs flex justify-center items-center transition-colors">
                <div
                  ref={modalTriggerRef}
                  onClick={() => setShowGradientModal(!showGradientModal)}
                  className="rounded-full relative w-full h-full"
                  style={{
                    backgroundImage: `linear-gradient(to right, ${popupBorderColorLeft}, ${popupBorderColorRight})`,
                  }}
                >
                  <div className="absolute -right-1 -bottom-1 bg-zinc-200 rounded-full border border-zinc-300 p-0.5 flex items-center justify-center h-[18px] w-[18px]">
                    <FaPlus className="text-[8px] text-zinc-500" />
                  </div>
                </div>
              </div>

              {showGradientModal && (
                <div
                  ref={modalRef}
                  className="rounded-xl fixed z-[9999] overflow-hidden shadow-xl border border-zinc-200"
                  style={{
                    top: modalTriggerRef.current
                      ? modalTriggerRef.current.getBoundingClientRect().bottom +
                        8
                      : 0,
                    left: modalTriggerRef.current
                      ? modalTriggerRef.current.getBoundingClientRect().left
                      : 0,
                  }}
                >
                  <div
                    className="h-10 w-full"
                    style={{
                      backgroundImage: `linear-gradient(to right, ${popupBorderColorLeft}, ${popupBorderColorRight})`,
                    }}
                  />
                  <div className="bg-white p-3 space-y-3">
                    <div className="space-y-1.5">
                      <p className="text-xs font-semibold text-zinc-700">
                        Start color
                      </p>
                      <PopoverColorPicker
                        color={popupBorderColorLeft}
                        onChange={setPopupBorderColorLeft}
                      />
                    </div>
                    <div className="space-y-1.5">
                      <p className="text-xs font-semibold text-zinc-700">
                        End color
                      </p>
                      <PopoverColorPicker
                        color={popupBorderColorRight}
                        onChange={setPopupBorderColorRight}
                      />
                    </div>
                  </div>
                </div>
              )}
            </div>

            <div className="flex items-center gap-1">
              <HexColorInput
                color={popupBorderColorLeft}
                onChange={setPopupBorderColorLeft}
                prefixed
                className="text-xs font-mono text-zinc-700 bg-zinc-50 px-2 py-1.5 rounded-l border border-zinc-200 outline-none focus:border-zinc-400 focus:bg-white w-20 uppercase text-center transition-colors"
              />
              <span className="text-xs text-zinc-400 px-1">→</span>
              <HexColorInput
                color={popupBorderColorRight}
                onChange={setPopupBorderColorRight}
                prefixed
                className="text-xs font-mono text-zinc-700 bg-zinc-50 px-2 py-1.5 rounded-r border border-zinc-200 outline-none focus:border-zinc-400 focus:bg-white w-20 uppercase text-center transition-colors"
              />
            </div>
          </div>
          <p className="text-xs text-zinc-500">
            The animated gradient border around your widget. Match your store
            accent color for a cohesive look.
          </p>
        </div>
      </div>

      <div className="space-y-3 border-t border-zinc-200 pt-5">
        <div>
          <p className="text-base font-semibold text-zinc-900">Brand Logo</p>
          <p className="text-xs text-zinc-500 mt-1">
            Replace the default AI icon with your brand mark. Use a transparent
            PNG for the cleanest result.
          </p>
        </div>

        <div
          className={logoBlocked ? 'pointer-events-none opacity-50' : ''}
          aria-hidden={logoBlocked}
        >
          <div className="flex items-center gap-4">
            <div className="relative flex-shrink-0">
              <div
                className="w-14 h-14 rounded-2xl flex items-center justify-center shadow-sm border border-zinc-100"
                style={{
                  background: `linear-gradient(135deg, ${popupBorderColorLeft}15, ${popupBorderColorRight}20)`,
                }}
              >
                {image ? (
                  <img
                    src={
                      image instanceof File ? URL.createObjectURL(image) : image
                    }
                    alt="logo"
                    className="object-contain w-10 h-10 rounded-lg"
                  />
                ) : (
                  <svg
                    xmlns="http://www.w3.org/2000/svg"
                    width="24"
                    height="24"
                    fill="none"
                    viewBox="0 0 24 24"
                  >
                    <path
                      fill="#999"
                      d="M21 15v3h3v2h-3v3h-2v-3h-3v-2h3v-3zm.008-12c.548 0 .992.445.992.993V13h-2V5H4v13.999L14 9l3 3v2.829l-3-3L6.827 19H14v2H2.992A.993.993 0 0 1 2 20.007V3.993A1 1 0 0 1 2.992 3zM8 7a2 2 0 1 1 0 4 2 2 0 0 1 0-4"
                    ></path>
                  </svg>
                )}
              </div>
            </div>

            <div className="flex-1">
              <div
                onClick={() => {
                  if (!logoBlocked) handleClick(imageUploadRef);
                }}
                className={`bg-zinc-50 hover:bg-zinc-100 w-full p-3 rounded-xl border border-dashed border-zinc-300 transition-colors ${
                  logoBlocked ? 'cursor-not-allowed' : 'cursor-pointer'
                }`}
                title={logoBlocked ? 'Upgrade to upload a custom logo' : ''}
              >
                <input
                  ref={imageUploadRef}
                  type="file"
                  accept=".png,.jpg,.jpeg,.svg"
                  name="logo"
                  onChange={onPopupLogoUpload}
                  disabled={logoBlocked}
                  className="absolute w-0 h-0 opacity-0 pointer-events-none"
                />
                <div className="flex items-center gap-2">
                  {image ? (
                    <>
                      <p className="text-sm font-medium text-zinc-900">
                        {imageName}
                      </p>
                      <FaEdit className="text-zinc-400 text-xs" />
                    </>
                  ) : (
                    <p className="text-sm text-zinc-500">
                      Click to upload PNG, JPG, or SVG
                    </p>
                  )}
                </div>
              </div>
              <p className="text-xs text-zinc-500 mt-1">
                Recommended: 100×100px with transparent background
              </p>
            </div>
          </div>
        </div>

        {logoBlocked && (
          <div className="rounded-xl border border-amber-200 bg-amber-50 p-4">
            <p className="text-sm font-bold text-zinc-900">
              Scaling or Hyper-Scaling plan required
            </p>
            <p className="text-xs text-zinc-600 mt-1">
              Personalize your AI icon with your brand logo. Upgrade to unlock
              custom branding.
            </p>
            <div className="mt-3">
              <Link to="/pricing">
                <Button className="w-full py-3 px-5 bg-black text-white rounded-md text-xs">
                  Upgrade Now
                </Button>
              </Link>
            </div>
          </div>
        )}
      </div>

      <div className="border-t border-zinc-200 pt-5">
        <PositionSelector position={position} setPosition={setPosition} />
      </div>

      <div className="pt-2">
        {apiError && (
          <div className="pb-2">
            <ErrorWrapper error={apiError} />
          </div>
        )}

        {success && (
          <div className="pb-2">
            <Banner type="success" open={success} setOpen={setSuccess}>
              Settings saved successfully
            </Banner>
          </div>
        )}

        <Button
          className="w-full py-3.5 px-5 text-base font-medium bg-slate-900 text-white flex justify-center items-center"
          onClick={saveSettings}
          isLoading={loading}
        >
          Save
        </Button>
      </div>
    </div>
  );
};

export default CustomizationStyles;
