import React, {
  useCallback,
  useEffect,
  useMemo,
  useRef,
  useState,
} from 'react';
import { buildStyles, CircularProgressbar } from 'react-circular-progressbar';
import { FaChevronRight } from 'react-icons/fa';
import { Link, useNavigate } from 'react-router-dom';

import { useAppStateContext } from '../context/user.data.context';
import { IPopupData, IQuickAction } from '../service/popup/popup.interface';
import {
  getMedia,
  getPopupData,
  getPopupImage,
  saveLogo,
  savePopupData,
} from '../service/popup/popup.service';
import { hexToRgba } from '../utils/colors';
import { DEFAULT_QUICK_ACTIONS } from '../utils/quickAction';
import CustomizationSettings from '../components/settings/CustomizationSettings';
import CustomizationStyles from '../components/settings/CustomizationStyles';
import { PreviewSection } from '../components/preview/PreviewSection';
import PromptConfigSettings from '../components/settings/PromptConfigSettings';
import { getLocalStorageValue } from '../utils';
import { PlanType } from '../types';

const TabIcons: Record<string, React.ReactNode> = {
  style: (
    <svg
      width="14"
      height="14"
      viewBox="0 0 14 14"
      fill="none"
      stroke="currentColor"
      strokeWidth="1.2"
    >
      <circle cx="4" cy="4" r="2.5" />
      <circle cx="10" cy="10" r="2.5" />
      <line x1="6.5" y1="4" x2="12" y2="4" strokeLinecap="round" />
      <line x1="2" y1="10" x2="7.5" y2="10" strokeLinecap="round" />
    </svg>
  ),
  setting: (
    <svg
      width="14"
      height="14"
      viewBox="0 0 14 14"
      fill="none"
      stroke="currentColor"
      strokeWidth="1.2"
    >
      <line x1="2" y1="4" x2="12" y2="4" strokeLinecap="round" />
      <line x1="2" y1="7" x2="12" y2="7" strokeLinecap="round" />
      <line x1="2" y1="10" x2="12" y2="10" strokeLinecap="round" />
      <circle cx="5" cy="4" r="1" fill="currentColor" stroke="none" />
      <circle cx="9" cy="7" r="1" fill="currentColor" stroke="none" />
      <circle cx="6" cy="10" r="1" fill="currentColor" stroke="none" />
    </svg>
  ),
  'prompt-config': (
    <svg
      width="14"
      height="14"
      viewBox="0 0 14 14"
      fill="none"
      stroke="currentColor"
      strokeWidth="1.3"
    >
      <path d="M3 3L7 7L3 11" strokeLinecap="round" strokeLinejoin="round" />
      <line x1="7" y1="11" x2="11" y2="11" strokeLinecap="round" />
    </svg>
  ),
};

const Customization = (): JSX.Element => {
  const navigate = useNavigate();
  const [selected, setSelected] = useState<number>(0);

  const [position, setPosition] = useState('left');
  const [headerMessage, setHeaderMessage] = useState<string | null>(null);
  const [expandedHeaderMessage, setExpandedHeaderMessage] = useState<
    string | null
  >(null);
  const [useStock, setUseStock] = useState(true);

  const [textColor, setTextColor] = useState('#000000');
  const [buttonColor, setButtonColor] = useState('#000000');
  const [popupBorderColorLeft, setPopupBorderColorLeft] = useState('#7897ff');
  const [popupBorderColorRight, setPopupBorderColorRight] = useState('#eb6362');
  const [image, setImage] = useState<File | string | null>(null);
  const [imageName, setImageName] = useState<string>('');
  const { user, token, onboarding, completeOnboardingStep } =
    useAppStateContext();
  const promptConfigPlans = useMemo(
    () => [PlanType.SCALING, PlanType.HYPER_SCALING, PlanType.ENTERPRISE],
    []
  );

  const [cartIconColor, setCartIconColor] = useState('#FFFFFF');
  const [restoreOnNavigation, setRestoreOnNavigation] = useState(true);
  const [defaultState, setDefaultState] = useState('minimized');
  const [defaultStateMobile, setDefaultStateMobile] = useState('minimized');
  const [size, setSize] = useState<'small' | 'medium' | 'big'>('medium');
  const [showPrices, setShowPrices] = useState(true);
  const [showAddToCartButton, setShowAddToCartButton] = useState(true);

  const [sourceVideo, setSourceVideo] = useState<string | null>(null);
  const [popup, setPopup] = useState<IPopupData | null>(null);

  const [quickActions, setQuickActions] = useState<IQuickAction[]>(
    DEFAULT_QUICK_ACTIONS
  );
  const [placeholders, setPlaceholders] = useState<string[]>(['']);
  const [isUploadingIcon, setIsUploadingIcon] = useState(false);

  const [previewTab, setPreviewTab] = useState<{
    index: number | undefined;
    tick: number;
  }>({ index: undefined, tick: 0 });
  const [blobExpanded, setBlobExpanded] = useState<boolean | undefined>(
    undefined
  );
  const [blobSkipIntro, setBlobSkipIntro] = useState<boolean | undefined>(
    undefined
  );
  const isInitialMount = useRef(true);

  const goToPreviewTab = useCallback((tabIndex: number) => {
    setPreviewTab(prev => ({ index: tabIndex, tick: prev.tick + 1 }));
  }, []);

  const handleWidgetStateChange = useCallback(
    (state: string) => {
      if (state === 'expanded') {
        goToPreviewTab(0);
        setBlobExpanded(undefined);
        setBlobSkipIntro(undefined);
      } else if (state === 'partial') {
        goToPreviewTab(1);
        setBlobExpanded(true);
        setBlobSkipIntro(false);
      } else {
        goToPreviewTab(1);
        setBlobExpanded(false);
        setBlobSkipIntro(true);
      }
    },
    [goToPreviewTab]
  );

  useEffect(() => {
    if (isInitialMount.current) {
      isInitialMount.current = false;
      return;
    }
    goToPreviewTab(1);
  }, [size, goToPreviewTab]);

  const handleWidgetPosition = useCallback(
    (pos: string) => {
      if (pos === 'left' || pos === 'right') {
        goToPreviewTab(1);
      }
    },
    [goToPreviewTab]
  );

  const wrappedPopupPosition = useCallback(
    (pos: string) => {
      setPosition(pos);
      handleWidgetPosition(pos);
    },
    [handleWidgetPosition]
  );

  const updateQuickAction = useCallback(
    (idx: number, patch: Partial<IQuickAction>) => {
      setQuickActions(prev =>
        prev.map((a, i) => (i === idx ? { ...a, ...patch } : a))
      );
    },
    []
  );

  const uploadQuickActionIcon = useCallback(
    async (idx: number, file: File) => {
      if (!user) return;
      setIsUploadingIcon(true);
      try {
        const mediaType = `QUICK_ACTION_${idx}`;
        const formData = new FormData();
        formData.append('file', file);
        formData.append('file_type', 'LOGO');
        formData.append('model_type', mediaType);
        formData.append('model_id', user.id);
        await saveLogo(formData);
        const mediaRes = await getMedia(user.id, mediaType);
        const iconUrl = mediaRes?.media?.file_path ?? null;
        if (iconUrl) {
          updateQuickAction(idx, { icon_url: iconUrl });
        }
      } catch (error) {
        console.error('Failed to upload quick action icon:', error);
      } finally {
        setIsUploadingIcon(false);
      }
    },
    [user, updateQuickAction]
  );

  const saveQuickActions = useCallback(
    async (actions: IQuickAction[]) => {
      if (!popup) return;

      const originalActions = popup.settings?.quick_actions?.length
        ? popup.settings.quick_actions
        : DEFAULT_QUICK_ACTIONS;

      const hasChanges = actions.filter((currentAction, index) => {
        const originalAction = originalActions[index];
        if (!originalAction) return true;
        return (
          currentAction.label !== originalAction.label ||
          currentAction.query !== originalAction.query ||
          currentAction.visible !== originalAction.visible ||
          currentAction.icon_url !== originalAction.icon_url ||
          currentAction.key !== originalAction.key
        );
      });

      if (!hasChanges) {
        return;
      }

      try {
        await savePopupData({
          color: popup.color || hexToRgba(textColor),
          secondary_color: popup.secondary_color || hexToRgba(buttonColor),
          settings: {
            ...popup.settings,
            quick_actions: actions,
          },
          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: popup.like_button_message || 'like',
          dislike_button_message: popup.dislike_button_message || 'dislike',
          loading_message: popup.loading_message || 'Reveal Secret Deals!',
          come_back_button_message:
            popup.come_back_button_message || 'Come back for more',
          in_stock_message: popup.in_stock_message || 'In stock',
          link_copied_message: popup.link_copied_message || 'Link copied',
          engagement_messages: popup.engagement_messages,
          source_video: popup.source_video,
          use_stock: popup.use_stock ?? true,
          default_state: popup.default_state || 'minimized',
          default_state_mobile: popup.default_state_mobile || 'minimized',
        });
      } catch (error) {
        console.error('Failed to save quick actions:', error);
      }
    },
    [popup, textColor, buttonColor, position]
  );

  const wrappedSetDefaultState = useCallback(
    (state: string) => {
      setDefaultState(state);
      handleWidgetStateChange(state);
    },
    [handleWidgetStateChange]
  );

  const wrappedSetDefaultStateMobile = useCallback(
    (state: string) => {
      setDefaultStateMobile(state);
      handleWidgetStateChange(state);
    },
    [handleWidgetStateChange]
  );

  const hasPromptConfigAccess = useMemo(() => {
    const normalizedPlan = (user?.plan_snapshot || user?.plan || '')
      .toString()
      .toUpperCase();

    return promptConfigPlans.includes(normalizedPlan as PlanType);
  }, [promptConfigPlans, user?.plan_snapshot, user?.plan]);

  const tabs = useMemo(() => {
    const baseTabs = [
      { id: 'style', content: 'Popup Styles', panelID: 'style' },
      { id: 'setting', content: 'Settings', panelID: 'setting' },
    ];
    if (hasPromptConfigAccess) {
      baseTabs.push({
        id: 'prompt-config',
        content: 'Prompt Config',
        panelID: 'prompt-config',
      });
    }

    return baseTabs;
  }, [hasPromptConfigAccess]);

  useEffect(() => {
    const rating = getLocalStorageValue('rating-popup');
    if (!rating) {
      navigate('/onboarding');
      return;
    }
  }, [navigate]);

  useEffect(() => {
    if (onboarding && !onboarding.popup_customized) {
      completeOnboardingStep('customize');
    }
  }, [onboarding?.popup_customized, completeOnboardingStep, onboarding]);

  useEffect(() => {
    if (!popup && token) fetchPopData();
  }, [token, popup]);

  useEffect((): void => {
    if (token && !image && user) fetchPopupImage(user?.id);
  }, [image, token, user]);

  useEffect(() => {
    const styleId = 'dynamic-gradient-style';
    const oldStyle = document.getElementById(styleId);
    if (oldStyle) oldStyle.remove();
    const style = document.createElement('style');
    style.id = styleId;
    style.innerHTML = `
      @keyframes dynamicGradient {
        0% { background-position: 0% 50%; }
        50% { background-position: 100% 50%; }
        100% { background-position: 0% 50%; }
      }
      .dynamic-gradient-bg {
        background: linear-gradient(-45deg, ${popupBorderColorLeft}, ${popupBorderColorRight}, ${popupBorderColorLeft}, ${popupBorderColorRight});
        background-size: 400% 400%;
        animation: dynamicGradient 15s ease infinite;
      }
    `;
    document.head.appendChild(style);
    return () => {
      const el = document.getElementById(styleId);
      if (el) el.remove();
    };
  }, [popupBorderColorLeft, popupBorderColorRight]);

  const fetchPopupImage = async (userId: string): Promise<void> => {
    try {
      const response = await getPopupImage({ modelId: userId });
      if (response?.media) {
        setImage(response?.media?.file_path as string);
        setImageName(response?.media?.file_name as string);
      }
    } catch (error) {
      console.log(error);
    }
  };

  const fetchPopData = async (): Promise<void> => {
    try {
      const response = await getPopupData();

      if (response?.success && response?.popup) {
        setPopup(response.popup);
        setHeaderMessage(response?.popup?.engagement_messages?.header_message);
        setExpandedHeaderMessage(
          response?.popup?.engagement_messages?.expanded_header_message
        );
        setPosition(response?.popup?.position || 'left');
        setSourceVideo(response?.popup?.source_video);
        setUseStock(response?.popup?.use_stock || true);
        setDefaultState(response?.popup?.default_state || 'minimized');
        setDefaultStateMobile(
          response?.popup?.default_state_mobile || 'minimized'
        );

        if (response?.popup?.settings) {
          setCartIconColor(
            response?.popup?.settings?.cart_icon_color || '#FFFFFF'
          );
          setTextColor(response?.popup?.settings?.text_color);
          setButtonColor(response?.popup?.settings?.button_color);
          setPopupBorderColorLeft(
            response?.popup?.settings?.gradient_colors[0] || '#ff7e5f'
          );
          setPopupBorderColorRight(
            response?.popup?.settings?.gradient_colors[1] || '#feb47b'
          );
          setRestoreOnNavigation(
            response?.popup?.settings?.restore_on_navigation || true
          );
          setSize(response?.popup?.settings?.size || 'medium');
          setShowPrices(response?.popup?.settings?.show_prices || true);
          setShowAddToCartButton(
            response?.popup?.settings?.show_add_to_cart_button || true
          );

          const savedQA = response?.popup?.settings?.quick_actions;
          if (savedQA?.length) {
            setQuickActions(
              DEFAULT_QUICK_ACTIONS.map((def, i) =>
                savedQA[i] ? { ...def, ...savedQA[i] } : def
              )
            );
          }

          const savedPlaceholders = response?.popup?.settings?.placeholders;
          if (Array.isArray(savedPlaceholders) && savedPlaceholders.length) {
            setPlaceholders(savedPlaceholders.slice(0, 5));
          }
        }

        if (user?.id) {
          try {
            const iconResults = await Promise.all(
              [0, 1, 2, 3].map(i =>
                getMedia(user.id, `QUICK_ACTION_${i}`).catch(() => null)
              )
            );
            setQuickActions(prev =>
              prev.map((a, i) => ({
                ...a,
                icon_url: iconResults[i]?.media?.file_path ?? a.icon_url,
              }))
            );
          } catch {
            // icon fetch is non-critical
          }
        }
      }
    } catch (error) {
      console.log(error);
    }
  };

  useEffect(() => {
    if (selected > tabs.length - 1) {
      setSelected(0);
    }
  }, [selected, tabs.length]);

  const onResetDefaultColors = () => {
    setTextColor('#000000');
    setButtonColor('#000000');
    setCartIconColor('#FFFFFF');
    setPopupBorderColorLeft('#7897ff');
    setPopupBorderColorRight('#eb6362');
  };

  return (
    <div className="w-full h-full mx-auto space-y-5">
      <style>{`.scrollbar-hide::-webkit-scrollbar { display: none; }`}</style>

      {user?.step && user?.step <= 2 ? (
        <div className="w-full rounded-xl border border-gray-200 bg-gradient-to-br from-zinc-50 to-white p-5 shadow-sm">
          <div className="flex flex-col md:flex-row md:items-center md:justify-between gap-4">
            <div className="space-y-1.5">
              <div className="inline-flex items-center gap-2">
                <span className="inline-flex items-center rounded-full bg-emerald-100 text-emerald-700 px-2 py-0.5 text-[11px] font-medium">
                  Getting started
                </span>
                {user?.step >= 2 ? (
                  <span className="text-xs text-emerald-700">
                    2 of 2 steps completed
                  </span>
                ) : (
                  <span className="text-xs text-gray-500">
                    Basic steps to raise your conversion rate
                  </span>
                )}
              </div>
              <p className="font-semibold text-base">
                Complete these basic important steps
              </p>
              <p className="font-normal text-sm text-gray-500">
                Basic yet important steps to start using Recomaze and raise your
                conversion rate
              </p>
            </div>

            <div className="flex items-center gap-3">
              <div className="h-10 w-10">
                <CircularProgressbar
                  value={Math.ceil((user?.step || 1) * 33)}
                  maxValue={100}
                  minValue={1}
                  strokeWidth={12}
                  styles={buildStyles({
                    pathColor: '#ff1d64',
                    trailColor: '#F3F4F6',
                    textColor: '#111827',
                  })}
                  text={`${Math.min(user?.step || 1, 2)} / 2`}
                  className="h-10 w-10"
                />
              </div>

              <Link
                to="/onboarding"
                className="inline-flex items-center rounded-lg bg-black text-white px-3 py-2 text-sm font-medium hover:bg-gray-900"
              >
                {user?.step && user?.step <= 1
                  ? 'Continue setup'
                  : 'Review setup'}
                <FaChevronRight className="ml-1 h-4 w-4 text-white/80" />
              </Link>
            </div>
          </div>

          <div className="pt-5">
            <p className="font-bold text-base">
              Customize Recomaze on Your Storefront
            </p>
          </div>
        </div>
      ) : null}

      <div className="w-full h-full grid grid-cols-1 lg:grid-cols-3 xl:grid-cols-3 gap-5">
        <div className="w-full h-full col-span-1 xl:col-span-1 bg-white p-6">
          <div
            className="flex items-center border-b border-zinc-200 pb-0 overflow-x-auto scrollbar-hide"
            style={{
              scrollbarWidth: 'none',
              msOverflowStyle: 'none',
              WebkitOverflowScrolling: 'touch',
            }}
          >
            {tabs.map((tab, key) => {
              const isActive = selected === key;

              return (
                <button
                  key={tab.id}
                  type="button"
                  onClick={() => setSelected(key)}
                  className={[
                    'relative flex items-center gap-1.5 px-3 py-2.5 text-xs font-semibold transition-colors rounded-t-lg flex-shrink-0',
                    isActive
                      ? 'text-black'
                      : 'text-zinc-400 hover:text-zinc-600',
                  ].join(' ')}
                >
                  <span className={isActive ? 'text-black' : 'text-zinc-400'}>
                    {TabIcons[tab.id]}
                  </span>
                  <span className="whitespace-nowrap">{tab.content}</span>
                  {isActive && (
                    <div className="absolute bottom-0 left-2 right-2 h-[2px] bg-black rounded-full" />
                  )}
                </button>
              );
            })}
          </div>

          <div className="w-full py-5">
            {tabs[selected]?.id === 'style' ? (
              <CustomizationStyles
                user={user}
                token={token}
                popup={popup}
                image={image}
                imageName={imageName}
                setImage={setImage}
                setImageName={setImageName}
                textColor={textColor}
                buttonColor={buttonColor}
                position={position}
                setPosition={wrappedPopupPosition}
                popupBorderColorLeft={popupBorderColorLeft}
                popupBorderColorRight={popupBorderColorRight}
                setButtonColor={color => {
                  setButtonColor(color);
                  goToPreviewTab(3);
                }}
                setPopupBorderColorLeft={color => {
                  setPopupBorderColorLeft(color);
                  goToPreviewTab(3);
                }}
                setPopupBorderColorRight={color => {
                  setPopupBorderColorRight(color);
                  goToPreviewTab(3);
                }}
                setTextColor={color => {
                  setTextColor(color);
                  goToPreviewTab(3);
                }}
                setCartIconColor={color => {
                  setCartIconColor(color);
                  goToPreviewTab(3);
                }}
                onResetDefaultColors={onResetDefaultColors}
                headerMessage={headerMessage}
                sourceVideo={sourceVideo}
                expandedHeaderMessage={expandedHeaderMessage}
                cartIconColor={cartIconColor}
                restoreOnNavigation={restoreOnNavigation}
                defaultState={defaultState as any}
                size={size}
                showAddToCartButton={showAddToCartButton}
                showPrices={showPrices}
                quickActions={quickActions}
              />
            ) : null}

            {tabs[selected]?.id === 'setting' ? (
              <CustomizationSettings
                popup={popup}
                token={token}
                cartIconColor={cartIconColor}
                textColor={textColor}
                buttonColor={buttonColor}
                popupBorderColorLeft={popupBorderColorLeft}
                popupBorderColorRight={popupBorderColorRight}
                setUseStock={setUseStock}
                useStock={useStock}
                position={position}
                setSourceVideo={setSourceVideo}
                sourceVideo={sourceVideo}
                headerMessage={headerMessage}
                setHeaderMessage={setHeaderMessage}
                expandedHeaderMessage={expandedHeaderMessage}
                setExpandedHeaderMessage={setExpandedHeaderMessage}
                defaultState={defaultState}
                restoreOnNavigation={restoreOnNavigation}
                setDefaultState={wrappedSetDefaultState}
                setRestoreOnNavigation={setRestoreOnNavigation}
                defaultStateMobile={defaultStateMobile}
                setDefaultStateMobile={wrappedSetDefaultStateMobile}
                size={size}
                setSize={setSize}
                setShowAddToCartButton={setShowAddToCartButton}
                setShowPrices={setShowPrices}
                showPrices={showPrices}
                showAddToCartButton={showAddToCartButton}
                quickActions={quickActions}
                placeholders={placeholders}
                setPlaceholders={next => {
                  setPlaceholders(next);
                  goToPreviewTab(0);
                }}
              />
            ) : null}

            {tabs[selected]?.id === 'prompt-config' ? (
              <PromptConfigSettings token={token || null} />
            ) : null}
          </div>
        </div>

        <div className="col-span-1 lg:col-span-2 w-full h-auto bg-white p-4">
          <PreviewSection
            image={
              image ||
              'https://recomaze-cdn.nyc3.cdn.digitaloceanspaces.com/popup/p_holder.jpeg'
            }
            sourceVideo={sourceVideo}
            expandedHeaderMessage={expandedHeaderMessage}
            headerMessage={headerMessage}
            position={position}
            buttonColor={buttonColor}
            textColor={textColor}
            popupBorderColorLeft={popupBorderColorLeft}
            popupBorderColorRight={popupBorderColorRight}
            cartIconColor={cartIconColor}
            size={size}
            showPrices={showPrices}
            showAddToCartButton={showAddToCartButton}
            activeTabIndex={previewTab.index}
            activeTabTick={previewTab.tick}
            blobExpanded={blobExpanded}
            blobSkipIntro={blobSkipIntro}
            quickActions={quickActions}
            onUpdateQuickAction={updateQuickAction}
            onUploadQuickActionIcon={uploadQuickActionIcon}
            onSaveQuickActions={saveQuickActions}
            isUploadingIcon={isUploadingIcon}
            placeholders={placeholders}
          />
        </div>
      </div>
    </div>
  );
};

export default Customization;
