import React, {
  useCallback,
  useEffect,
  useMemo,
  useRef,
  useState,
} from 'react';
import type { FC } from 'react';
import type { IconType } from 'react-icons';
import { BsQuestion } from 'react-icons/bs';
import {
  FiBox,
  FiEdit2,
  FiEyeOff,
  FiHeart,
  FiLoader,
  FiMic,
  FiPercent,
  FiStar,
  FiTrash2,
  FiUpload,
  FiX,
} from 'react-icons/fi';
import { PiDotsSixThin } from 'react-icons/pi';

import type { IQuickAction } from '../../service/popup/popup.interface';
import TripleStarsIcon from '../icons/TripleStarsIcon';
import {
  DEFAULT_BLUE_RGB,
  DEFAULT_PINK_RGB,
  hexToRgb,
} from '../../utils/colors';
import { DEFAULT_QUICK_ACTIONS } from '../../utils/quickAction';

const FALLBACK_PLACEHOLDERS = [
  'Search anything with AI...',
  'Show me bestsellers',
  'Find a gift for a friend',
  "What's trending this week?",
  'Show popular items on sale',
];

const SLOT_ICONS: { icon: IconType; iconClassName: string }[] = [
  { icon: BsQuestion, iconClassName: 'text-slate-800' },
  { icon: FiStar, iconClassName: 'text-yellow-500' },
  { icon: FiBox, iconClassName: 'text-blue-500' },
  { icon: FiPercent, iconClassName: 'text-green-500' },
];

function normalizeQuickActions(incoming?: IQuickAction[]): IQuickAction[] {
  // Merge overrides onto the default slots by index, mirroring
  // recomaze-custom-platform. Matching by key would break editing: the Label
  // field rewrites the key on every keystroke, so a key-based lookup loses the
  // override mid-edit and the input reverts to its default value.
  return DEFAULT_QUICK_ACTIONS.map((defaultQa, idx) => {
    const override = incoming?.[idx];

    return override ? { ...defaultQa, ...override } : { ...defaultQa };
  });
}

interface AiShoppingAssistantProps {
  textColor?: string;
  buttonColor?: string;
  image: string | File | null;
  popupBorderColorLeft?: string;
  popupBorderColorRight?: string;
  headerMessage: string | null;
  expandedHeaderMessage: string | null;
  quickActions?: IQuickAction[];
  onUpdateQuickAction?: (idx: number, patch: Partial<IQuickAction>) => void;
  onUploadQuickActionIcon?: (idx: number, file: File) => void;
  onSaveQuickActions?: (actions: IQuickAction[]) => Promise<void>;
  isUploadingIcon?: boolean;
  placeholders?: string[];
}

export const AiShoppingAssistantCard: FC<AiShoppingAssistantProps> = ({
  textColor,
  image,
  popupBorderColorLeft,
  popupBorderColorRight,
  expandedHeaderMessage,
  headerMessage,
  quickActions,
  onUpdateQuickAction,
  onUploadQuickActionIcon,
  onSaveQuickActions,
  isUploadingIcon,
  placeholders,
}) => {
  const [editingSlot, setEditingSlot] = useState<number | null>(null);
  const leftRgb = hexToRgb(popupBorderColorLeft || '');
  const rightRgb = hexToRgb(popupBorderColorRight || '');

  const normalizedActions = useMemo(
    () => normalizeQuickActions(quickActions),
    [quickActions]
  );

  const cardStyle: React.CSSProperties = {
    background: `linear-gradient(
    to bottom,
    rgba(${leftRgb}, 0.12) 0%,
    rgba(${leftRgb}, 0.12) 40%,
    rgba(${rightRgb}, 0.18) 100%
  )`,
    backdropFilter: 'blur(12px)',
    boxShadow: `0 25px 50px -12px rgba(${rightRgb}, 0.35)`,
  };

  const editingAction =
    editingSlot !== null ? normalizedActions[editingSlot] : null;
  const editingDefaults =
    editingSlot !== null ? DEFAULT_QUICK_ACTIONS[editingSlot] : null;
  const editingIcon = editingSlot !== null ? SLOT_ICONS[editingSlot] : null;
  const editable = !!onUpdateQuickAction;

  return (
    <div className="flex items-center justify-center p-2 py-8">
      {/* Glass card */}
      <section
        className="w-full max-w-md rounded-[24px] border border-white/80 p-6 pb-5 shadow-md"
        style={cardStyle}
      >
        {/* Top chrome */}
        <div className="mb-4 flex items-center justify-between text-slate-400">
          <button
            type="button"
            className="flex items-center justify-center rounded-full px-2 py-1 text-xs font-medium hover:bg-white/70 hover:text-slate-500 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-indigo-200"
          />

          <div className="flex items-center gap-1.5 text-sm font-medium text-slate-500">
            <PiDotsSixThin className="h-4 w-4" />
          </div>
          <div className="flex items-center gap-1.5 text-sm font-medium text-slate-500">
            <FiHeart className="h-4 w-4" />
            <span>0</span>
          </div>
        </div>

        {/* Logo / Sparkles */}
        <div className="flex flex-col items-center text-center gap-2">
          <div className="py-2">
            {image ? (
              <img
                src={image instanceof File ? URL.createObjectURL(image) : image}
                alt="logo"
                className="w-12 h-12"
              />
            ) : (
              <TripleStarsIcon
                colorLeft={popupBorderColorLeft}
                colorRight={popupBorderColorRight}
                className="w-10 h-10"
              />
            )}
          </div>

          <h1
            className="mb-1 text-base font-extrabold text-slate-900 line-clamp-2 break-words"
            style={{ color: textColor }}
            title={headerMessage || undefined}
          >
            {headerMessage || (
              <span className="text-slate-300 italic font-normal text-sm">
                Set your header message in Settings
              </span>
            )}
          </h1>
          <p
            className="mb-6 max-w-xs text-xs font-normal leading-relaxed text-neutral-600 line-clamp-3 break-words"
            style={{ color: textColor }}
            title={expandedHeaderMessage || undefined}
          >
            {expandedHeaderMessage || (
              <span className="text-slate-300 italic">
                Set your expanded message in Settings
              </span>
            )}
          </p>
        </div>

        {/* Quick actions */}
        <div className="grid gap-3 sm:grid-cols-2">
          {normalizedActions.map((qa, idx) => {
            const visible = qa.visible ?? true;
            const label = qa.label || DEFAULT_QUICK_ACTIONS[idx].label;
            const customIcon = qa.icon_url;
            const slotIcon = SLOT_ICONS[idx];
            const Icon = slotIcon.icon;

            if (!visible) {
              return editable ? (
                <button
                  key={idx}
                  type="button"
                  onClick={() => setEditingSlot(idx)}
                  className="!py-4 group flex !flex-col items-center gap-2 rounded-2xl border-2 border-dashed border-slate-300/60 bg-white/30 px-4 backdrop-blur-sm transition hover:border-slate-400/80 hover:bg-white/50"
                >
                  <FiEyeOff className="h-4 w-4 text-slate-400" />
                  <span className="text-xs text-slate-400">Hidden</span>
                </button>
              ) : null;
            }

            return (
              <button
                key={idx}
                type="button"
                onClick={editable ? () => setEditingSlot(idx) : undefined}
                className={[
                  '!py-4 group flex !flex-col items-center gap-2 rounded-2xl border border-white/70 bg-white/80 px-4 shadow-sm backdrop-blur-sm transition',
                  editable
                    ? 'hover:-translate-y-0.5 hover:shadow-md ring-1 ring-indigo-500/20 cursor-pointer relative'
                    : 'hover:-translate-y-0.5 hover:shadow-md',
                ].join(' ')}
              >
                {editable && (
                  <span className="absolute top-1.5 right-1.5 flex items-center justify-center rounded-full bg-indigo-50 p-1">
                    <FiEdit2 className="h-2.5 w-2.5 text-indigo-600" />
                  </span>
                )}
                <span
                  className={`flex items-center justify-center rounded-full ${
                    customIcon ? '' : slotIcon.iconClassName
                  }`}
                >
                  {customIcon ? (
                    <img
                      src={customIcon}
                      alt={label}
                      className="h-5 w-5 object-contain"
                    />
                  ) : (
                    <Icon className="h-5 w-5" />
                  )}
                </span>
                <span
                  className="text-xs font-medium text-slate-800"
                  style={{ color: textColor }}
                >
                  {label}
                </span>
              </button>
            );
          })}
        </div>

        {/* Search */}
        <SearchBar
          popupBorderColorLeft={popupBorderColorLeft}
          popupBorderColorRight={popupBorderColorRight}
          placeholders={placeholders}
        />
      </section>

      {/* Edit Quick Action Modal */}
      {onUpdateQuickAction &&
        editingSlot !== null &&
        editingDefaults &&
        editingIcon && (
          <EditQuickActionModal
            editingSlot={editingSlot}
            editingAction={editingAction ?? null}
            editingDefaults={editingDefaults}
            editingIcon={editingIcon}
            isUploadingIcon={isUploadingIcon}
            onUpdateQuickAction={onUpdateQuickAction}
            onUploadQuickActionIcon={onUploadQuickActionIcon}
            onSaveQuickActions={onSaveQuickActions}
            quickActions={normalizedActions}
            onClose={() => setEditingSlot(null)}
          />
        )}
    </div>
  );
};

/* ─── Edit Quick Action Modal ─── */

interface EditModalProps {
  editingSlot: number;
  editingAction: IQuickAction | null;
  editingDefaults: IQuickAction;
  editingIcon: { icon: IconType; iconClassName: string };
  isUploadingIcon?: boolean;
  onUpdateQuickAction: (idx: number, patch: Partial<IQuickAction>) => void;
  onUploadQuickActionIcon?: (idx: number, file: File) => void;
  onSaveQuickActions?: (actions: IQuickAction[]) => Promise<void>;
  quickActions?: IQuickAction[];
  onClose: () => void;
}

const EditQuickActionModal: FC<EditModalProps> = ({
  editingSlot,
  editingAction,
  editingDefaults,
  editingIcon,
  isUploadingIcon,
  onUpdateQuickAction,
  onUploadQuickActionIcon,
  onSaveQuickActions,
  quickActions,
  onClose,
}) => {
  const modalRef = useRef<HTMLDivElement>(null);
  const [isSaving, setIsSaving] = useState(false);
  const SlotIcon = editingIcon.icon;

  const handleDone = useCallback(async () => {
    if (onSaveQuickActions && quickActions) {
      setIsSaving(true);
      await onSaveQuickActions(quickActions);
      setIsSaving(false);
    }
    onClose();
  }, [onSaveQuickActions, quickActions, onClose]);

  useEffect(() => {
    const handleEsc = (e: KeyboardEvent) => {
      if (e.key === 'Escape') handleDone();
    };
    document.addEventListener('keydown', handleEsc);

    return () => document.removeEventListener('keydown', handleEsc);
  }, [handleDone]);

  return (
    <div
      className="fixed inset-0 z-[9999] flex items-center justify-center bg-black/40 backdrop-blur-sm"
      onClick={e => {
        if (e.target === e.currentTarget) handleDone();
      }}
    >
      <div
        ref={modalRef}
        className="w-full max-w-md rounded-2xl bg-white shadow-2xl border border-zinc-200 mx-4"
      >
        {/* Header */}
        <div className="flex items-center justify-between px-5 pt-5 pb-3 border-b border-zinc-100">
          <div>
            <h3 className="text-sm font-semibold text-zinc-900">
              Edit Quick Action
            </h3>
            <p className="text-xs text-zinc-500 mt-0.5">
              Customize this shortcut button on the greeting screen.
            </p>
          </div>
          <button
            type="button"
            onClick={handleDone}
            disabled={isSaving}
            className="flex items-center justify-center rounded-lg p-1.5 text-zinc-400 hover:text-zinc-600 hover:bg-zinc-100 transition-colors disabled:opacity-60"
          >
            <FiX className="h-4 w-4" />
          </button>
        </div>

        {/* Body */}
        <div className="px-5 py-4 space-y-4">
          {/* Visibility toggle */}
          <div className="flex items-center justify-between">
            <div className="flex items-center gap-2">
              <span className={editingIcon.iconClassName}>
                <SlotIcon className="h-4 w-4" />
              </span>
              <span className="text-sm font-medium text-zinc-700">
                {editingAction?.visible !== false ? 'Visible' : 'Hidden'}
              </span>
            </div>
            <button
              type="button"
              onClick={() =>
                onUpdateQuickAction(editingSlot, {
                  visible: !(editingAction?.visible ?? true),
                })
              }
              className={[
                'relative inline-flex h-6 w-11 items-center rounded-full transition-colors',
                editingAction?.visible !== false
                  ? 'bg-indigo-600'
                  : 'bg-zinc-300',
              ].join(' ')}
            >
              <span
                className={[
                  'inline-block h-4 w-4 rounded-full bg-white shadow transition-transform',
                  editingAction?.visible !== false
                    ? 'translate-x-6'
                    : 'translate-x-1',
                ].join(' ')}
              />
            </button>
          </div>

          {/* Label */}
          <div className="space-y-1.5">
            <label className="text-xs font-medium text-zinc-700">Label</label>
            <input
              type="text"
              value={editingAction?.label ?? editingDefaults.label}
              onChange={e =>
                onUpdateQuickAction(editingSlot, {
                  label: e.target.value,
                  key: e.target.value.toLowerCase().replace(/\s+/g, '_'),
                })
              }
              placeholder="e.g. Summer Sale"
              maxLength={40}
              className="w-full rounded-lg border border-zinc-200 bg-white px-3 py-2 text-sm text-zinc-900 placeholder:text-zinc-400 outline-none hover:border-zinc-300 focus:border-zinc-400 focus:ring-1 focus:ring-zinc-200 transition-colors"
            />
          </div>

          {/* Query */}
          <div className="space-y-1.5">
            <label className="text-xs font-medium text-zinc-700">Query</label>
            <input
              type="text"
              value={editingAction?.query ?? ''}
              onChange={e =>
                onUpdateQuickAction(editingSlot, {
                  query: e.target.value,
                })
              }
              placeholder="e.g. summer sale products"
              maxLength={100}
              className="w-full rounded-lg border border-zinc-200 bg-white px-3 py-2 text-sm text-zinc-900 placeholder:text-zinc-400 outline-none hover:border-zinc-300 focus:border-zinc-400 focus:ring-1 focus:ring-zinc-200 transition-colors"
            />
            <p className="text-xs text-zinc-400">
              Search query sent when clicked
            </p>
          </div>

          {/* Icon upload */}
          <div className="space-y-1.5">
            <label className="text-xs font-medium text-zinc-700">
              Custom Icon
            </label>
            <div className="flex items-center gap-3">
              <button
                type="button"
                onClick={() => {
                  const input = document.createElement('input');
                  input.type = 'file';
                  input.accept = '.png,.jpg,.jpeg,.svg,.webp';
                  input.onchange = e => {
                    const file = (e.target as HTMLInputElement).files?.[0];
                    if (!file || !onUploadQuickActionIcon) return;
                    onUpdateQuickAction(editingSlot, {
                      icon_url: URL.createObjectURL(file),
                    });
                    onUploadQuickActionIcon(editingSlot, file);
                  };
                  input.click();
                }}
                className="flex cursor-pointer items-center gap-2 rounded-lg bg-zinc-100 px-3 py-2 text-xs hover:bg-zinc-200 transition-colors"
              >
                {editingAction?.icon_url ? (
                  <>
                    <FiEdit2 className="h-3 w-3 text-indigo-600" />
                    <span>Change</span>
                  </>
                ) : (
                  <>
                    <FiUpload className="h-3 w-3 text-zinc-500" />
                    <span>Upload</span>
                  </>
                )}
              </button>
              {editingAction?.icon_url ? (
                <div className="flex items-center gap-2">
                  <img
                    src={editingAction.icon_url}
                    alt="Icon"
                    className="h-8 w-8 rounded object-contain bg-zinc-100 p-1"
                  />
                  <button
                    type="button"
                    onClick={() =>
                      onUpdateQuickAction(editingSlot, { icon_url: undefined })
                    }
                    className="text-zinc-400 hover:text-red-500 transition-colors"
                  >
                    <FiTrash2 className="h-3.5 w-3.5" />
                  </button>
                </div>
              ) : (
                <div className="flex h-8 w-8 items-center justify-center rounded bg-zinc-100">
                  <SlotIcon
                    className={`h-4 w-4 ${editingIcon.iconClassName}`}
                  />
                </div>
              )}
            </div>
            {isUploadingIcon && (
              <p className="text-xs text-indigo-600 flex items-center gap-1">
                <FiLoader className="h-3 w-3 animate-spin" /> Uploading...
              </p>
            )}
            <p className="text-xs text-zinc-400">
              PNG, JPG, SVG or WebP. Leave empty for default icon.
            </p>
          </div>
        </div>

        {/* Footer */}
        <div className="px-5 pb-5 pt-2 border-t border-zinc-100">
          <button
            type="button"
            onClick={handleDone}
            disabled={isSaving}
            className="w-full rounded-lg bg-zinc-900 px-4 py-2 text-sm font-medium text-white hover:bg-zinc-800 disabled:opacity-60 transition-colors flex items-center justify-center gap-2"
          >
            {isSaving ? (
              <>
                <FiLoader className="h-3.5 w-3.5 animate-spin" />
                Saving...
              </>
            ) : (
              'Done'
            )}
          </button>
        </div>
      </div>
    </div>
  );
};

/* ─── Search Bar ─── */

const SearchBar: FC<{
  popupBorderColorLeft?: string;
  popupBorderColorRight?: string;
  placeholders?: string[];
}> = ({ popupBorderColorLeft, popupBorderColorRight, placeholders }) => {
  const [value, setValue] = useState('');

  const customStyles = {
    '--accent-pink-rgb':
      hexToRgb(popupBorderColorLeft || '') || DEFAULT_PINK_RGB,
    '--accent-blue-rgb':
      hexToRgb(popupBorderColorRight || '') || DEFAULT_BLUE_RGB,
  } as React.CSSProperties;

  const cleanedPlaceholders = useMemo(() => {
    const cleaned = (placeholders ?? [])
      .map(p => (typeof p === 'string' ? p.trim() : ''))
      .filter(p => p.length > 0);

    return cleaned.length > 0 ? cleaned : FALLBACK_PLACEHOLDERS;
  }, [placeholders]);

  return (
    <div className="py-2 pt-4">
      <div
        style={customStyles}
        className="wbm-smart__custom-background rounded-xl p-0.5"
      >
        <div className="w-full flex items-center gap-3 rounded-xl bg-white px-3 py-2.5 shadow-sm backdrop-blur-sm">
          <FiMic className="h-4 w-4 flex-shrink-0 text-slate-400" />
          <div className="relative flex-1">
            <div className="wbm-smart__placeholder-wrapper relative">
              <input
                className="h-6 w-full rounded-xl border border-transparent bg-white/60 pl-1 pr-10 text-[13px] text-slate-700 placeholder:text-slate-400 focus:border-none focus:outline-none focus:ring-0 focus:ring-white relative z-[1]"
                value={value}
                onChange={e => setValue(e.target.value)}
              />
              <AnimatedPlaceholder
                searchKey={value}
                placeholderList={cleanedPlaceholders}
              />
            </div>
            <button
              type="button"
              className="absolute right-0 top-1/2 flex h-7 w-7 -translate-y-1/2 items-center justify-center rounded-full bg-white z-[2]"
            >
              <TripleStarsIcon
                colorLeft={popupBorderColorLeft}
                colorRight={popupBorderColorRight}
              />
            </button>
          </div>
        </div>
      </div>
    </div>
  );
};

/* ─── Animated Placeholder ─── */

const AnimatedPlaceholder: FC<{
  searchKey: string;
  placeholderList: string[];
}> = ({ searchKey, placeholderList }) => {
  const [text, setText] = useState('');
  const [animateIndex, setAnimateIndex] = useState(0);
  const [charIndex, setCharIndex] = useState(0);
  const [forward, setForward] = useState(true);
  const mainTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);
  const nestedTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);

  useEffect(() => {
    setAnimateIndex(0);
    setCharIndex(0);
    setForward(true);
    setText('');
  }, [placeholderList]);

  useEffect(() => {
    if (searchKey !== '') return;
    if (!placeholderList || placeholderList.length === 0) return;

    const safeIndex = animateIndex % placeholderList.length;
    const currentText = placeholderList[safeIndex];
    if (!currentText) return;

    const isTyping = forward && charIndex <= currentText.length;
    const isDeleting = !forward && charIndex >= 0;

    const minSpeed = 70;
    const maxSpeed = 140;
    const speed =
      Math.floor(Math.random() * (maxSpeed - minSpeed + 1)) + minSpeed;

    mainTimeoutRef.current = setTimeout(
      () => {
        if (forward) {
          if (charIndex <= currentText.length) {
            setText(currentText.slice(0, charIndex));
            setCharIndex(charIndex + 1);
          } else {
            nestedTimeoutRef.current = setTimeout(
              () => setForward(false),
              1000
            );
          }
        } else if (charIndex > 0) {
          setText(currentText.slice(0, charIndex));
          setCharIndex(charIndex - 1);
        } else {
          setText('');
          setCharIndex(0);
          setForward(true);
          setAnimateIndex(prev => (prev + 1) % placeholderList.length);
        }
      },
      isTyping || isDeleting ? speed : 1000
    );

    return () => {
      if (mainTimeoutRef.current) clearTimeout(mainTimeoutRef.current);
      if (nestedTimeoutRef.current) clearTimeout(nestedTimeoutRef.current);
    };
  }, [charIndex, forward, animateIndex, placeholderList, searchKey]);

  if (searchKey !== '') return null;

  return (
    <span className="wbm-smart__animated-placeholder">
      {Array.from(text).map((char, i, arr) => {
        const isLast = i === arr.length - 1;

        return (
          <span
            key={i}
            className={isLast ? 'wbm-smart__blur-letter' : ''}
            style={{ whiteSpace: 'pre' }}
          >
            {char}
          </span>
        );
      })}
      <span className="wbm-smart__cursor">|</span>
    </span>
  );
};
