import {
  mdiContentSave,
  mdiPaletteSwatch,
  mdiPlus,
  mdiTrashCan,
} from '@mdi/js';
import axios from 'axios';
import Head from 'next/head';
import Link from 'next/link';
import { useRouter } from 'next/router';
import React, {
  ReactElement,
  useCallback,
  useEffect,
  useMemo,
  useState,
} from 'react';
import BaseButton from '../../components/BaseButton';
import CardBox from '../../components/CardBox';
import FormField from '../../components/FormField';
import LayoutAuthenticated from '../../layouts/Authenticated';
import SectionMain from '../../components/SectionMain';
import SectionTitleLineWithButton from '../../components/SectionTitleLineWithButton';
import { getPageTitle } from '../../config';
import { logger } from '../../lib/logger';

type UiElementType = {
  id: string;
  element_type: string;
  name?: string;
  sort_order?: number;
  is_active?: boolean;
  default_settings_json?: Record<string, any> | string | null;
};

type ElementType =
  | 'navigation_next'
  | 'navigation_prev'
  | 'gallery'
  | 'carousel'
  | 'tooltip'
  | 'description'
  | 'video_player'
  | 'audio_player';

type GalleryCard = {
  id: string;
  imageUrl: string;
  title: string;
  description: string;
};

type CarouselSlide = {
  id: string;
  imageUrl: string;
  caption: string;
};

const parseJsonObject = <T,>(value?: unknown, fallback?: T): T => {
  if (!value) return (fallback || ({} as T)) as T;

  try {
    if (typeof value === 'string') {
      const parsed = JSON.parse(value);
      return (parsed || fallback || {}) as T;
    }

    if (typeof value === 'object') {
      return value as T;
    }

    return (fallback || ({} as T)) as T;
  } catch (error) {
    logger.error(
      'Failed to parse UI element defaults JSON:',
      error instanceof Error ? error : { error },
    );
    return (fallback || ({} as T)) as T;
  }
};

const clampPercent = (value: string) => {
  const parsed = Number(value);
  if (!Number.isFinite(parsed)) return 0;
  return Math.min(Math.max(parsed, 0), 100);
};

const parseNullableNumber = (value: string) => {
  if (!value.trim()) return null;
  const parsed = Number(value);
  if (!Number.isFinite(parsed) || parsed < 0) return null;
  return parsed;
};

const extractNumericValue = (value: unknown) => {
  const normalized = String(value ?? '').trim();
  if (!normalized) return '';
  const matched = normalized.match(/-?\d*\.?\d+/);
  return matched ? matched[0] : '';
};

const normalizeNumberString = (value: string) => {
  const normalized = String(value || '').trim();
  if (!normalized) return '';
  const parsed = Number(normalized);
  if (!Number.isFinite(parsed)) return '';
  return String(parsed);
};

const toOptionalTrimmed = (value: string) => {
  const normalized = String(value || '').trim();
  return normalized ? normalized : undefined;
};

const toUnitValue = (value: string, unit: 'vw' | 'vh' | 'px') => {
  const normalized = normalizeNumberString(value);
  return normalized ? `${normalized}${unit}` : undefined;
};

const createLocalId = () => {
  if (typeof window !== 'undefined' && window.crypto?.randomUUID) {
    return window.crypto.randomUUID();
  }

  return `ui-default_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
};

const UiElementDetailsPage = () => {
  const router = useRouter();
  const id = useMemo(() => {
    const routeValue = router.query.id;
    if (Array.isArray(routeValue)) return routeValue[0] || '';
    return String(routeValue || '');
  }, [router.query.id]);

  const [item, setItem] = useState<UiElementType | null>(null);
  const [name, setName] = useState('');
  const [sortOrder, setSortOrder] = useState(0);
  const [isActive, setIsActive] = useState(true);

  const [label, setLabel] = useState('');
  const [xPercent, setXPercent] = useState('0');
  const [yPercent, setYPercent] = useState('0');
  const [width, setWidth] = useState('');
  const [height, setHeight] = useState('');
  const [minWidth, setMinWidth] = useState('');
  const [maxWidth, setMaxWidth] = useState('');
  const [minHeight, setMinHeight] = useState('');
  const [maxHeight, setMaxHeight] = useState('');
  const [margin, setMargin] = useState('');
  const [padding, setPadding] = useState('');
  const [gap, setGap] = useState('');
  const [fontSize, setFontSize] = useState('');
  const [lineHeight, setLineHeight] = useState('');
  const [fontWeight, setFontWeight] = useState('');
  const [border, setBorder] = useState('');
  const [borderRadius, setBorderRadius] = useState('');
  const [opacity, setOpacity] = useState('');
  const [boxShadow, setBoxShadow] = useState('');
  const [display, setDisplay] = useState('');
  const [position, setPosition] = useState('');
  const [justifyContent, setJustifyContent] = useState('');
  const [alignItems, setAlignItems] = useState('');
  const [textAlign, setTextAlign] = useState('');
  const [zIndex, setZIndex] = useState('');
  const [appearDelaySec, setAppearDelaySec] = useState('0');
  const [appearDurationSec, setAppearDurationSec] = useState('');
  const [iconUrl, setIconUrl] = useState('');
  const [navLabel, setNavLabel] = useState('');
  const [navType, setNavType] = useState<'forward' | 'back'>('forward');
  const [navDisabled, setNavDisabled] = useState(false);
  const [targetPageId, setTargetPageId] = useState('');
  const [transitionVideoUrl, setTransitionVideoUrl] = useState('');
  const [transitionReverseMode, setTransitionReverseMode] = useState<
    'auto_reverse' | 'separate_video'
  >('auto_reverse');
  const [reverseVideoUrl, setReverseVideoUrl] = useState('');
  const [transitionDurationSec, setTransitionDurationSec] = useState('0.7');
  const [tooltipTitle, setTooltipTitle] = useState('');
  const [tooltipText, setTooltipText] = useState('');
  const [descriptionTitle, setDescriptionTitle] = useState('');
  const [descriptionText, setDescriptionText] = useState('');
  const [descriptionTitleFontSize, setDescriptionTitleFontSize] = useState('');
  const [descriptionTextFontSize, setDescriptionTextFontSize] = useState('');
  const [descriptionTitleFontFamily, setDescriptionTitleFontFamily] =
    useState('');
  const [descriptionTextFontFamily, setDescriptionTextFontFamily] =
    useState('');
  const [descriptionTitleColor, setDescriptionTitleColor] = useState('');
  const [descriptionTextColor, setDescriptionTextColor] = useState('');
  const [descriptionBackgroundColor, setDescriptionBackgroundColor] =
    useState('');
  const [mediaUrl, setMediaUrl] = useState('');
  const [mediaAutoplay, setMediaAutoplay] = useState(false);
  const [mediaLoop, setMediaLoop] = useState(false);
  const [mediaMuted, setMediaMuted] = useState(false);
  const [carouselPrevIconUrl, setCarouselPrevIconUrl] = useState('');
  const [carouselNextIconUrl, setCarouselNextIconUrl] = useState('');
  const [galleryCards, setGalleryCards] = useState<GalleryCard[]>([]);
  const [carouselSlides, setCarouselSlides] = useState<CarouselSlide[]>([]);

  const [isLoading, setIsLoading] = useState(false);
  const [isSaving, setIsSaving] = useState(false);
  const [errorMessage, setErrorMessage] = useState('');
  const [successMessage, setSuccessMessage] = useState('');

  const applySettingsToForm = useCallback(
    (settingsValue?: UiElementType['default_settings_json']) => {
      const settings = parseJsonObject<Record<string, any>>(settingsValue, {});

      setLabel(String(settings.label || ''));
      setXPercent(String(settings.xPercent ?? 0));
      setYPercent(String(settings.yPercent ?? 0));
      setWidth(extractNumericValue(settings.width));
      setHeight(extractNumericValue(settings.height));
      setMinWidth(extractNumericValue(settings.minWidth));
      setMaxWidth(extractNumericValue(settings.maxWidth));
      setMinHeight(extractNumericValue(settings.minHeight));
      setMaxHeight(extractNumericValue(settings.maxHeight));
      setMargin(String(settings.margin || ''));
      setPadding(String(settings.padding || ''));
      setGap(String(settings.gap || ''));
      setFontSize(String(settings.fontSize || ''));
      setLineHeight(String(settings.lineHeight || ''));
      setFontWeight(String(settings.fontWeight || ''));
      setBorder(extractNumericValue(settings.border));
      setBorderRadius(extractNumericValue(settings.borderRadius));
      setOpacity(settings.opacity === 0 ? '0' : String(settings.opacity || ''));
      setBoxShadow(String(settings.boxShadow || ''));
      setDisplay(String(settings.display || ''));
      setPosition(String(settings.position || ''));
      setJustifyContent(String(settings.justifyContent || ''));
      setAlignItems(String(settings.alignItems || ''));
      setTextAlign(String(settings.textAlign || ''));
      setZIndex(String(settings.zIndex || ''));
      setAppearDelaySec(String(settings.appearDelaySec ?? 0));
      setAppearDurationSec(
        settings.appearDurationSec === null ||
          settings.appearDurationSec === undefined
          ? ''
          : String(settings.appearDurationSec),
      );
      setIconUrl(String(settings.iconUrl || ''));
      setNavLabel(String(settings.navLabel || ''));
      setNavType(settings.navType === 'back' ? 'back' : 'forward');
      setNavDisabled(Boolean(settings.navDisabled));
      setTargetPageId(String(settings.targetPageId || ''));
      setTransitionVideoUrl(String(settings.transitionVideoUrl || ''));
      setTransitionReverseMode(
        settings.transitionReverseMode === 'separate_video'
          ? 'separate_video'
          : 'auto_reverse',
      );
      setReverseVideoUrl(String(settings.reverseVideoUrl || ''));
      setTransitionDurationSec(String(settings.transitionDurationSec ?? 0.7));
      setTooltipTitle(String(settings.tooltipTitle || ''));
      setTooltipText(String(settings.tooltipText || ''));
      setDescriptionTitle(String(settings.descriptionTitle || ''));
      setDescriptionText(String(settings.descriptionText || ''));
      setDescriptionTitleFontSize(
        String(settings.descriptionTitleFontSize || ''),
      );
      setDescriptionTextFontSize(
        String(settings.descriptionTextFontSize || ''),
      );
      setDescriptionTitleFontFamily(
        String(settings.descriptionTitleFontFamily || ''),
      );
      setDescriptionTextFontFamily(
        String(settings.descriptionTextFontFamily || ''),
      );
      setDescriptionTitleColor(String(settings.descriptionTitleColor || ''));
      setDescriptionTextColor(String(settings.descriptionTextColor || ''));
      setDescriptionBackgroundColor(
        String(settings.descriptionBackgroundColor || ''),
      );
      setMediaUrl(String(settings.mediaUrl || ''));
      setMediaAutoplay(Boolean(settings.mediaAutoplay));
      setMediaLoop(Boolean(settings.mediaLoop));
      setMediaMuted(Boolean(settings.mediaMuted));
      setCarouselPrevIconUrl(String(settings.carouselPrevIconUrl || ''));
      setCarouselNextIconUrl(String(settings.carouselNextIconUrl || ''));

      const nextGalleryCards = Array.isArray(settings.galleryCards)
        ? settings.galleryCards.map((card: any, index: number) => ({
            id: String(card?.id || createLocalId()),
            imageUrl: String(card?.imageUrl || ''),
            title: String(card?.title || `Card ${index + 1}`),
            description: String(card?.description || ''),
          }))
        : [];

      const nextCarouselSlides = Array.isArray(settings.carouselSlides)
        ? settings.carouselSlides.map((slide: any, index: number) => ({
            id: String(slide?.id || createLocalId()),
            imageUrl: String(slide?.imageUrl || ''),
            caption: String(slide?.caption || `Slide ${index + 1}`),
          }))
        : [];

      setGalleryCards(nextGalleryCards);
      setCarouselSlides(nextCarouselSlides);
    },
    [],
  );

  const loadItem = useCallback(async () => {
    if (!id) return;

    try {
      setIsLoading(true);
      setErrorMessage('');
      setSuccessMessage('');

      const response = await axios.get(`/ui-elements/${id}`);
      const nextItem: UiElementType | null = response?.data || null;

      if (!nextItem) {
        setErrorMessage('UI element type not found.');
        setItem(null);
        return;
      }

      setItem(nextItem);
      setName(String(nextItem.name || ''));
      setSortOrder(Number(nextItem.sort_order || 0));
      setIsActive(Boolean(nextItem.is_active));
      applySettingsToForm(nextItem.default_settings_json);
    } catch (error: any) {
      const message =
        error?.response?.data?.message ||
        error?.message ||
        'Failed to load UI element type.';
      logger.error(
        'Failed to load UI element type details:',
        error instanceof Error ? error : { error },
      );
      setErrorMessage(message);
      setItem(null);
    } finally {
      setIsLoading(false);
    }
  }, [applySettingsToForm, id]);

  useEffect(() => {
    if (!router.isReady) return;
    loadItem();
  }, [loadItem, router.isReady]);

  const currentElementType = (item?.element_type || '') as ElementType;
  const isNavigationType =
    currentElementType === 'navigation_next' ||
    currentElementType === 'navigation_prev';
  const isTooltipType = currentElementType === 'tooltip';
  const isDescriptionType = currentElementType === 'description';
  const isGalleryType = currentElementType === 'gallery';
  const isCarouselType = currentElementType === 'carousel';
  const isMediaType =
    currentElementType === 'video_player' ||
    currentElementType === 'audio_player';

  const updateGalleryCard = (
    cardId: string,
    field: keyof GalleryCard,
    value: string,
  ) => {
    setGalleryCards((previous) =>
      previous.map((card) =>
        card.id === cardId ? { ...card, [field]: value } : card,
      ),
    );
  };

  const addGalleryCard = () => {
    setGalleryCards((previous) => [
      ...previous,
      {
        id: createLocalId(),
        imageUrl: '',
        title: `Card ${previous.length + 1}`,
        description: '',
      },
    ]);
  };

  const removeGalleryCard = (cardId: string) => {
    setGalleryCards((previous) =>
      previous.filter((card) => card.id !== cardId),
    );
  };

  const updateCarouselSlide = (
    slideId: string,
    field: keyof CarouselSlide,
    value: string,
  ) => {
    setCarouselSlides((previous) =>
      previous.map((slide) =>
        slide.id === slideId ? { ...slide, [field]: value } : slide,
      ),
    );
  };

  const addCarouselSlide = () => {
    setCarouselSlides((previous) => [
      ...previous,
      {
        id: createLocalId(),
        imageUrl: '',
        caption: `Slide ${previous.length + 1}`,
      },
    ]);
  };

  const removeCarouselSlide = (slideId: string) => {
    setCarouselSlides((previous) =>
      previous.filter((slide) => slide.id !== slideId),
    );
  };

  const handleSave = useCallback(async () => {
    if (!id || !item) return;

    const borderWidthValue = toUnitValue(border, 'px');
    const defaultSettings: Record<string, any> = {
      label: label.trim(),
      xPercent: clampPercent(xPercent),
      yPercent: clampPercent(yPercent),
      border: borderWidthValue
        ? `${borderWidthValue} solid currentColor`
        : 'none',
      borderRadius: toUnitValue(borderRadius, 'px') || '0px',
      appearDelaySec: Number(appearDelaySec) >= 0 ? Number(appearDelaySec) : 0,
      appearDurationSec: parseNullableNumber(appearDurationSec),
    };

    const widthValue = toUnitValue(width, 'vw');
    const heightValue = toUnitValue(height, 'vh');
    const minWidthValue = toUnitValue(minWidth, 'vw');
    const maxWidthValue = toUnitValue(maxWidth, 'vw');
    const minHeightValue = toUnitValue(minHeight, 'vh');
    const maxHeightValue = toUnitValue(maxHeight, 'vh');

    if (widthValue) defaultSettings.width = widthValue;
    if (heightValue) defaultSettings.height = heightValue;
    if (minWidthValue) defaultSettings.minWidth = minWidthValue;
    if (maxWidthValue) defaultSettings.maxWidth = maxWidthValue;
    if (minHeightValue) defaultSettings.minHeight = minHeightValue;
    if (maxHeightValue) defaultSettings.maxHeight = maxHeightValue;

    const marginValue = toOptionalTrimmed(margin);
    const paddingValue = toOptionalTrimmed(padding);
    const gapValue = toOptionalTrimmed(gap);
    const fontSizeValue = toOptionalTrimmed(fontSize);
    const lineHeightValue = toOptionalTrimmed(lineHeight);
    const fontWeightValue = toOptionalTrimmed(fontWeight);
    const opacityValue = toOptionalTrimmed(opacity);
    const boxShadowValue = toOptionalTrimmed(boxShadow);
    const displayValue = toOptionalTrimmed(display);
    const positionValue = toOptionalTrimmed(position);
    const justifyContentValue = toOptionalTrimmed(justifyContent);
    const alignItemsValue = toOptionalTrimmed(alignItems);
    const textAlignValue = toOptionalTrimmed(textAlign);
    const zIndexValue = toOptionalTrimmed(zIndex);

    if (marginValue) defaultSettings.margin = marginValue;
    if (paddingValue) defaultSettings.padding = paddingValue;
    if (gapValue) defaultSettings.gap = gapValue;
    if (fontSizeValue) defaultSettings.fontSize = fontSizeValue;
    if (lineHeightValue) defaultSettings.lineHeight = lineHeightValue;
    if (fontWeightValue) defaultSettings.fontWeight = fontWeightValue;
    if (opacityValue) defaultSettings.opacity = opacityValue;
    if (boxShadowValue) defaultSettings.boxShadow = boxShadowValue;
    if (displayValue) defaultSettings.display = displayValue;
    if (positionValue) defaultSettings.position = positionValue;
    if (justifyContentValue)
      defaultSettings.justifyContent = justifyContentValue;
    if (alignItemsValue) defaultSettings.alignItems = alignItemsValue;
    if (textAlignValue) defaultSettings.textAlign = textAlignValue;
    if (zIndexValue) defaultSettings.zIndex = zIndexValue;

    if (isNavigationType) {
      defaultSettings.iconUrl = iconUrl.trim();
      defaultSettings.navLabel = navLabel.trim();
      defaultSettings.navType = navType;
      defaultSettings.navDisabled = navDisabled;
      defaultSettings.targetPageId = targetPageId.trim();
      defaultSettings.transitionVideoUrl = transitionVideoUrl.trim();
      defaultSettings.transitionReverseMode = transitionReverseMode;
      defaultSettings.reverseVideoUrl = reverseVideoUrl.trim();
      defaultSettings.transitionDurationSec =
        Number(transitionDurationSec) > 0 ? Number(transitionDurationSec) : 0.7;
    }

    if (isTooltipType) {
      defaultSettings.iconUrl = iconUrl.trim();
      defaultSettings.tooltipTitle = tooltipTitle.trim();
      defaultSettings.tooltipText = tooltipText;
    }

    if (isDescriptionType) {
      defaultSettings.iconUrl = iconUrl.trim();
      defaultSettings.descriptionTitle = descriptionTitle.trim();
      defaultSettings.descriptionText = descriptionText;
      defaultSettings.descriptionTitleFontSize =
        descriptionTitleFontSize.trim() || '48px';
      defaultSettings.descriptionTextFontSize =
        descriptionTextFontSize.trim() || '36px';
      defaultSettings.descriptionTitleFontFamily =
        descriptionTitleFontFamily.trim() || 'inherit';
      defaultSettings.descriptionTextFontFamily =
        descriptionTextFontFamily.trim() || 'inherit';
      defaultSettings.descriptionTitleColor =
        descriptionTitleColor.trim() || '#000000';
      defaultSettings.descriptionTextColor =
        descriptionTextColor.trim() || '#4B5563';
      defaultSettings.descriptionBackgroundColor =
        descriptionBackgroundColor.trim() || 'transparent';
    }

    if (isGalleryType) {
      defaultSettings.galleryCards = galleryCards.map((card, index) => ({
        id: String(card.id || createLocalId()),
        imageUrl: card.imageUrl.trim(),
        title: card.title.trim() || `Card ${index + 1}`,
        description: card.description,
      }));
    }

    if (isCarouselType) {
      defaultSettings.carouselSlides = carouselSlides.map((slide, index) => ({
        id: String(slide.id || createLocalId()),
        imageUrl: slide.imageUrl.trim(),
        caption: slide.caption.trim() || `Slide ${index + 1}`,
      }));
      defaultSettings.carouselPrevIconUrl = carouselPrevIconUrl.trim();
      defaultSettings.carouselNextIconUrl = carouselNextIconUrl.trim();
    }

    if (isMediaType) {
      defaultSettings.mediaUrl = mediaUrl.trim();
      defaultSettings.mediaAutoplay = mediaAutoplay;
      defaultSettings.mediaLoop = mediaLoop;
      defaultSettings.mediaMuted = mediaMuted;
    }

    try {
      setIsSaving(true);
      setErrorMessage('');
      setSuccessMessage('');

      await axios.put(`/ui-elements/${id}`, {
        id,
        data: {
          element_type: item.element_type,
          name: String(name || '').trim() || item.element_type,
          sort_order: Number.isFinite(Number(sortOrder))
            ? Number(sortOrder)
            : 0,
          is_active: Boolean(isActive),
          default_settings_json: defaultSettings,
        },
      });

      setSuccessMessage('Default settings saved.');
      await loadItem();
    } catch (error: any) {
      const message =
        error?.response?.data?.message ||
        error?.message ||
        'Failed to save UI element defaults.';
      logger.error(
        'Failed to save UI element defaults:',
        error instanceof Error ? error : { error },
      );
      setErrorMessage(message);
      setSuccessMessage('');
    } finally {
      setIsSaving(false);
    }
  }, [
    appearDelaySec,
    appearDurationSec,
    carouselNextIconUrl,
    carouselPrevIconUrl,
    carouselSlides,
    currentElementType,
    descriptionText,
    descriptionTitle,
    descriptionTitleFontSize,
    descriptionTextFontSize,
    descriptionTitleFontFamily,
    descriptionTextFontFamily,
    descriptionTitleColor,
    descriptionTextColor,
    descriptionBackgroundColor,
    display,
    fontSize,
    fontWeight,
    gap,
    galleryCards,
    height,
    iconUrl,
    id,
    isActive,
    isCarouselType,
    isDescriptionType,
    isGalleryType,
    isMediaType,
    isNavigationType,
    isTooltipType,
    item,
    justifyContent,
    label,
    lineHeight,
    loadItem,
    margin,
    maxHeight,
    maxWidth,
    mediaAutoplay,
    mediaLoop,
    mediaMuted,
    mediaUrl,
    minHeight,
    minWidth,
    name,
    navDisabled,
    navLabel,
    navType,
    opacity,
    padding,
    position,
    reverseVideoUrl,
    sortOrder,
    textAlign,
    targetPageId,
    tooltipText,
    tooltipTitle,
    transitionDurationSec,
    transitionReverseMode,
    transitionVideoUrl,
    width,
    xPercent,
    yPercent,
    zIndex,
    alignItems,
    border,
    borderRadius,
    boxShadow,
  ]);

  return (
    <>
      <Head>
        <title>{getPageTitle('UI Element Defaults')}</title>
      </Head>
      <SectionMain>
        <SectionTitleLineWithButton
          icon={mdiPaletteSwatch}
          title='UI Element Defaults'
          main
        >
          {''}
        </SectionTitleLineWithButton>

        <CardBox className='mb-4'>
          <div className='flex items-center justify-between gap-2'>
            <Link href='/ui-elements'>
              <BaseButton color='info' outline label='Back to UI Elements' />
            </Link>
            <BaseButton
              color='info'
              icon={mdiContentSave}
              label={isSaving ? 'Saving...' : 'Save'}
              disabled={isLoading || isSaving || !item}
              onClick={handleSave}
            />
          </div>
        </CardBox>

        <CardBox>
          {isLoading ? (
            <p className='text-sm text-gray-500'>Loading...</p>
          ) : !item ? (
            <p className='text-sm text-gray-500'>UI element type not found.</p>
          ) : (
            <div className='space-y-4'>
              <FormField label='Element Type'>
                <input value={item.element_type} disabled />
              </FormField>

              <FormField label='Name'>
                <input
                  value={name}
                  onChange={(event) => setName(event.target.value)}
                />
              </FormField>

              <FormField label='Sort Order'>
                <input
                  type='number'
                  value={sortOrder}
                  onChange={(event) =>
                    setSortOrder(Number(event.target.value || 0))
                  }
                />
              </FormField>

              <FormField label='Active'>
                <label className='inline-flex items-center gap-2 text-sm'>
                  <input
                    type='checkbox'
                    checked={isActive}
                    onChange={(event) => setIsActive(event.target.checked)}
                  />
                  Use this element type in constructor
                </label>
              </FormField>

              <FormField label='Label'>
                <input
                  value={label}
                  onChange={(event) => setLabel(event.target.value)}
                />
              </FormField>

              <div className='grid gap-4 md:grid-cols-2'>
                <FormField label='X percent'>
                  <input
                    value={xPercent}
                    onChange={(event) => setXPercent(event.target.value)}
                  />
                </FormField>
                <FormField label='Y percent'>
                  <input
                    value={yPercent}
                    onChange={(event) => setYPercent(event.target.value)}
                  />
                </FormField>
                <FormField label='Appear delay (sec)'>
                  <input
                    value={appearDelaySec}
                    onChange={(event) => setAppearDelaySec(event.target.value)}
                  />
                </FormField>
                <FormField label='Appear duration (sec)'>
                  <input
                    value={appearDurationSec}
                    onChange={(event) =>
                      setAppearDurationSec(event.target.value)
                    }
                    placeholder='Leave empty for none'
                  />
                </FormField>
              </div>

              <CardBox className='border border-gray-200 dark:border-dark-700'>
                <h3 className='mb-3 text-sm font-semibold'>
                  View & stylization
                </h3>
                <p className='mb-3 text-xs text-gray-500'>
                  Fill numbers only: width is saved as vw, height as vh, border
                  and radius as px.
                </p>
                <div className='grid gap-3 md:grid-cols-2'>
                  <FormField label='Width (vw)'>
                    <input
                      type='number'
                      step='0.1'
                      min='0'
                      value={width}
                      onChange={(event) => setWidth(event.target.value)}
                      placeholder='e.g. 24'
                    />
                  </FormField>
                  <FormField label='Height (vh)'>
                    <input
                      type='number'
                      step='0.1'
                      min='0'
                      value={height}
                      onChange={(event) => setHeight(event.target.value)}
                      placeholder='e.g. 8'
                    />
                  </FormField>
                  <FormField label='Min width (vw)'>
                    <input
                      type='number'
                      step='0.1'
                      min='0'
                      value={minWidth}
                      onChange={(event) => setMinWidth(event.target.value)}
                    />
                  </FormField>
                  <FormField label='Max width (vw)'>
                    <input
                      type='number'
                      step='0.1'
                      min='0'
                      value={maxWidth}
                      onChange={(event) => setMaxWidth(event.target.value)}
                    />
                  </FormField>
                  <FormField label='Min height (vh)'>
                    <input
                      type='number'
                      step='0.1'
                      min='0'
                      value={minHeight}
                      onChange={(event) => setMinHeight(event.target.value)}
                    />
                  </FormField>
                  <FormField label='Max height (vh)'>
                    <input
                      type='number'
                      step='0.1'
                      min='0'
                      value={maxHeight}
                      onChange={(event) => setMaxHeight(event.target.value)}
                    />
                  </FormField>
                  <FormField label='Margin'>
                    <input
                      value={margin}
                      onChange={(event) => setMargin(event.target.value)}
                      placeholder='e.g. 0 auto / 0.5rem'
                    />
                  </FormField>
                  <FormField label='Padding'>
                    <input
                      value={padding}
                      onChange={(event) => setPadding(event.target.value)}
                      placeholder='e.g. 0.5rem 0.75rem'
                    />
                  </FormField>
                  <FormField label='Gap'>
                    <input
                      value={gap}
                      onChange={(event) => setGap(event.target.value)}
                    />
                  </FormField>
                  <FormField label='Font size'>
                    <input
                      value={fontSize}
                      onChange={(event) => setFontSize(event.target.value)}
                      placeholder='e.g. 0.875rem / clamp(...)'
                    />
                  </FormField>
                  <FormField label='Line height'>
                    <input
                      value={lineHeight}
                      onChange={(event) => setLineHeight(event.target.value)}
                    />
                  </FormField>
                  <FormField label='Font weight'>
                    <input
                      value={fontWeight}
                      onChange={(event) => setFontWeight(event.target.value)}
                      placeholder='e.g. 500 / bold'
                    />
                  </FormField>
                  <FormField label='Border width (px)'>
                    <input
                      type='number'
                      step='1'
                      min='0'
                      value={border}
                      onChange={(event) => setBorder(event.target.value)}
                      placeholder='empty = none'
                    />
                  </FormField>
                  <FormField label='Border radius (px)'>
                    <input
                      type='number'
                      step='1'
                      min='0'
                      value={borderRadius}
                      onChange={(event) => setBorderRadius(event.target.value)}
                      placeholder='empty = 0'
                    />
                  </FormField>
                  <FormField label='Opacity'>
                    <input
                      value={opacity}
                      onChange={(event) => setOpacity(event.target.value)}
                      placeholder='0..1'
                    />
                  </FormField>
                  <FormField label='Shadow'>
                    <input
                      value={boxShadow}
                      onChange={(event) => setBoxShadow(event.target.value)}
                      placeholder='e.g. 0 4px 12px rgba(...)'
                    />
                  </FormField>
                  <FormField label='Display'>
                    <select
                      value={display}
                      onChange={(event) => setDisplay(event.target.value)}
                    >
                      <option value=''>Not set</option>
                      <option value='block'>block</option>
                      <option value='inline-block'>inline-block</option>
                      <option value='flex'>flex</option>
                      <option value='inline-flex'>inline-flex</option>
                      <option value='grid'>grid</option>
                      <option value='none'>none</option>
                    </select>
                  </FormField>
                  <FormField label='Position'>
                    <select
                      value={position}
                      onChange={(event) => setPosition(event.target.value)}
                    >
                      <option value=''>Not set</option>
                      <option value='static'>static</option>
                      <option value='relative'>relative</option>
                      <option value='absolute'>absolute</option>
                      <option value='fixed'>fixed</option>
                      <option value='sticky'>sticky</option>
                    </select>
                  </FormField>
                  <FormField label='Justify content'>
                    <select
                      value={justifyContent}
                      onChange={(event) =>
                        setJustifyContent(event.target.value)
                      }
                    >
                      <option value=''>Not set</option>
                      <option value='flex-start'>flex-start</option>
                      <option value='center'>center</option>
                      <option value='flex-end'>flex-end</option>
                      <option value='space-between'>space-between</option>
                      <option value='space-around'>space-around</option>
                      <option value='space-evenly'>space-evenly</option>
                    </select>
                  </FormField>
                  <FormField label='Align items'>
                    <select
                      value={alignItems}
                      onChange={(event) => setAlignItems(event.target.value)}
                    >
                      <option value=''>Not set</option>
                      <option value='stretch'>stretch</option>
                      <option value='flex-start'>flex-start</option>
                      <option value='center'>center</option>
                      <option value='flex-end'>flex-end</option>
                      <option value='baseline'>baseline</option>
                    </select>
                  </FormField>
                  <FormField label='Text align'>
                    <select
                      value={textAlign}
                      onChange={(event) => setTextAlign(event.target.value)}
                    >
                      <option value=''>Not set</option>
                      <option value='left'>left</option>
                      <option value='center'>center</option>
                      <option value='right'>right</option>
                      <option value='justify'>justify</option>
                    </select>
                  </FormField>
                  <FormField label='z-index'>
                    <input
                      value={zIndex}
                      onChange={(event) => setZIndex(event.target.value)}
                      placeholder='e.g. 1 / 10'
                    />
                  </FormField>
                </div>
              </CardBox>

              {isNavigationType ? (
                <>
                  <FormField label='Icon URL'>
                    <input
                      value={iconUrl}
                      onChange={(event) => setIconUrl(event.target.value)}
                    />
                  </FormField>
                  <FormField label='Navigation label'>
                    <input
                      value={navLabel}
                      onChange={(event) => setNavLabel(event.target.value)}
                    />
                  </FormField>
                  <FormField label='Navigation type'>
                    <select
                      value={navType}
                      onChange={(event) =>
                        setNavType(
                          event.target.value === 'back' ? 'back' : 'forward',
                        )
                      }
                    >
                      <option value='forward'>Forward</option>
                      <option value='back'>Back</option>
                    </select>
                  </FormField>
                  <FormField label='Disabled'>
                    <label className='inline-flex items-center gap-2 text-sm'>
                      <input
                        type='checkbox'
                        checked={navDisabled}
                        onChange={(event) =>
                          setNavDisabled(event.target.checked)
                        }
                      />
                      Button is disabled (not clickable)
                    </label>
                  </FormField>
                  <FormField label='Target page ID (optional)'>
                    <input
                      value={targetPageId}
                      onChange={(event) => setTargetPageId(event.target.value)}
                    />
                  </FormField>
                  <FormField label='Transition video URL'>
                    <input
                      value={transitionVideoUrl}
                      onChange={(event) =>
                        setTransitionVideoUrl(event.target.value)
                      }
                    />
                  </FormField>
                  <FormField label='Reverse mode'>
                    <select
                      value={transitionReverseMode}
                      onChange={(event) =>
                        setTransitionReverseMode(
                          event.target.value === 'separate_video'
                            ? 'separate_video'
                            : 'auto_reverse',
                        )
                      }
                    >
                      <option value='auto_reverse'>Auto reverse</option>
                      <option value='separate_video'>
                        Separate reverse video
                      </option>
                    </select>
                  </FormField>
                  {transitionReverseMode === 'separate_video' ? (
                    <FormField label='Reverse video URL'>
                      <input
                        value={reverseVideoUrl}
                        onChange={(event) =>
                          setReverseVideoUrl(event.target.value)
                        }
                      />
                    </FormField>
                  ) : null}
                  <FormField label='Transition duration (sec)'>
                    <input
                      value={transitionDurationSec}
                      onChange={(event) =>
                        setTransitionDurationSec(event.target.value)
                      }
                    />
                  </FormField>
                </>
              ) : null}

              {isTooltipType ? (
                <>
                  <FormField label='Icon URL'>
                    <input
                      value={iconUrl}
                      onChange={(event) => setIconUrl(event.target.value)}
                    />
                  </FormField>
                  <FormField label='Tooltip title'>
                    <input
                      value={tooltipTitle}
                      onChange={(event) => setTooltipTitle(event.target.value)}
                    />
                  </FormField>
                  <FormField label='Tooltip text' hasTextareaHeight>
                    <textarea
                      value={tooltipText}
                      onChange={(event) => setTooltipText(event.target.value)}
                      className='h-28 w-full rounded border border-gray-300 p-2 dark:border-dark-700 dark:bg-dark-900'
                    />
                  </FormField>
                </>
              ) : null}

              {isDescriptionType ? (
                <>
                  <FormField label='Icon URL'>
                    <input
                      value={iconUrl}
                      onChange={(event) => setIconUrl(event.target.value)}
                    />
                  </FormField>
                  <FormField label='Description title'>
                    <input
                      value={descriptionTitle}
                      onChange={(event) =>
                        setDescriptionTitle(event.target.value)
                      }
                    />
                  </FormField>
                  <FormField label='Description text' hasTextareaHeight>
                    <textarea
                      value={descriptionText}
                      onChange={(event) =>
                        setDescriptionText(event.target.value)
                      }
                      className='h-28 w-full rounded border border-gray-300 p-2 dark:border-dark-700 dark:bg-dark-900'
                    />
                  </FormField>
                  <div className='grid gap-3 md:grid-cols-2'>
                    <FormField label='Title font size'>
                      <input
                        value={descriptionTitleFontSize}
                        onChange={(event) =>
                          setDescriptionTitleFontSize(event.target.value)
                        }
                        placeholder='e.g. 48px'
                      />
                    </FormField>
                    <FormField label='Text font size'>
                      <input
                        value={descriptionTextFontSize}
                        onChange={(event) =>
                          setDescriptionTextFontSize(event.target.value)
                        }
                        placeholder='e.g. 36px'
                      />
                    </FormField>
                    <FormField label='Title font family'>
                      <input
                        value={descriptionTitleFontFamily}
                        onChange={(event) =>
                          setDescriptionTitleFontFamily(event.target.value)
                        }
                        placeholder='e.g. Arial, sans-serif'
                      />
                    </FormField>
                    <FormField label='Text font family'>
                      <input
                        value={descriptionTextFontFamily}
                        onChange={(event) =>
                          setDescriptionTextFontFamily(event.target.value)
                        }
                        placeholder='e.g. Arial, sans-serif'
                      />
                    </FormField>
                    <FormField label='Title color'>
                      <input
                        type='color'
                        value={descriptionTitleColor || '#000000'}
                        onChange={(event) =>
                          setDescriptionTitleColor(event.target.value)
                        }
                        className='h-10 w-full'
                      />
                    </FormField>
                    <FormField label='Text color'>
                      <input
                        type='color'
                        value={descriptionTextColor || '#4B5563'}
                        onChange={(event) =>
                          setDescriptionTextColor(event.target.value)
                        }
                        className='h-10 w-full'
                      />
                    </FormField>
                    <FormField label='Background color'>
                      <input
                        value={descriptionBackgroundColor}
                        onChange={(event) =>
                          setDescriptionBackgroundColor(event.target.value)
                        }
                        placeholder='e.g. transparent, #ffffff'
                      />
                    </FormField>
                  </div>
                </>
              ) : null}

              {isGalleryType ? (
                <CardBox className='border border-gray-200 dark:border-dark-700'>
                  <div className='mb-3 flex items-center justify-between'>
                    <h3 className='text-sm font-semibold'>Gallery cards</h3>
                    <BaseButton
                      color='info'
                      icon={mdiPlus}
                      small
                      label='Add card'
                      onClick={addGalleryCard}
                    />
                  </div>

                  <div className='space-y-4'>
                    {galleryCards.length === 0 ? (
                      <p className='text-sm text-gray-500'>No cards yet.</p>
                    ) : (
                      galleryCards.map((card, index) => (
                        <CardBox
                          key={card.id}
                          className='border border-gray-200 dark:border-dark-700'
                        >
                          <div className='mb-3 flex items-center justify-between'>
                            <h4 className='text-sm font-semibold'>
                              Card {index + 1}
                            </h4>
                            <BaseButton
                              color='danger'
                              icon={mdiTrashCan}
                              small
                              outline
                              onClick={() => removeGalleryCard(card.id)}
                            />
                          </div>
                          <div className='grid gap-3 md:grid-cols-2'>
                            <FormField label='Image URL'>
                              <input
                                value={card.imageUrl}
                                onChange={(event) =>
                                  updateGalleryCard(
                                    card.id,
                                    'imageUrl',
                                    event.target.value,
                                  )
                                }
                              />
                            </FormField>
                            <FormField label='Title'>
                              <input
                                value={card.title}
                                onChange={(event) =>
                                  updateGalleryCard(
                                    card.id,
                                    'title',
                                    event.target.value,
                                  )
                                }
                              />
                            </FormField>
                            <div className='md:col-span-2'>
                              <FormField label='Description' hasTextareaHeight>
                                <textarea
                                  value={card.description}
                                  onChange={(event) =>
                                    updateGalleryCard(
                                      card.id,
                                      'description',
                                      event.target.value,
                                    )
                                  }
                                  className='h-24 w-full rounded border border-gray-300 p-2 dark:border-dark-700 dark:bg-dark-900'
                                />
                              </FormField>
                            </div>
                          </div>
                        </CardBox>
                      ))
                    )}
                  </div>
                </CardBox>
              ) : null}

              {isCarouselType ? (
                <CardBox className='border border-gray-200 dark:border-dark-700'>
                  <h3 className='mb-3 text-sm font-semibold'>
                    Carousel settings
                  </h3>
                  <div className='grid gap-3 md:grid-cols-2'>
                    <FormField label='Previous icon URL'>
                      <input
                        value={carouselPrevIconUrl}
                        onChange={(event) =>
                          setCarouselPrevIconUrl(event.target.value)
                        }
                      />
                    </FormField>
                    <FormField label='Next icon URL'>
                      <input
                        value={carouselNextIconUrl}
                        onChange={(event) =>
                          setCarouselNextIconUrl(event.target.value)
                        }
                      />
                    </FormField>
                  </div>
                  <div className='mb-3 mt-2 flex items-center justify-between'>
                    <h3 className='text-sm font-semibold'>Carousel slides</h3>
                    <BaseButton
                      color='info'
                      icon={mdiPlus}
                      small
                      label='Add slide'
                      onClick={addCarouselSlide}
                    />
                  </div>

                  <div className='space-y-4'>
                    {carouselSlides.length === 0 ? (
                      <p className='text-sm text-gray-500'>No slides yet.</p>
                    ) : (
                      carouselSlides.map((slide, index) => (
                        <CardBox
                          key={slide.id}
                          className='border border-gray-200 dark:border-dark-700'
                        >
                          <div className='mb-3 flex items-center justify-between'>
                            <h4 className='text-sm font-semibold'>
                              Slide {index + 1}
                            </h4>
                            <BaseButton
                              color='danger'
                              icon={mdiTrashCan}
                              small
                              outline
                              onClick={() => removeCarouselSlide(slide.id)}
                            />
                          </div>
                          <div className='grid gap-3 md:grid-cols-2'>
                            <FormField label='Image URL'>
                              <input
                                value={slide.imageUrl}
                                onChange={(event) =>
                                  updateCarouselSlide(
                                    slide.id,
                                    'imageUrl',
                                    event.target.value,
                                  )
                                }
                              />
                            </FormField>
                            <FormField label='Caption'>
                              <input
                                value={slide.caption}
                                onChange={(event) =>
                                  updateCarouselSlide(
                                    slide.id,
                                    'caption',
                                    event.target.value,
                                  )
                                }
                              />
                            </FormField>
                          </div>
                        </CardBox>
                      ))
                    )}
                  </div>
                </CardBox>
              ) : null}

              {isMediaType ? (
                <>
                  <FormField label='Media URL'>
                    <input
                      value={mediaUrl}
                      onChange={(event) => setMediaUrl(event.target.value)}
                    />
                  </FormField>
                  <FormField label='Playback'>
                    <div className='flex flex-wrap gap-4'>
                      <label className='inline-flex items-center gap-2 text-sm'>
                        <input
                          type='checkbox'
                          checked={mediaAutoplay}
                          onChange={(event) =>
                            setMediaAutoplay(event.target.checked)
                          }
                        />
                        Autoplay
                      </label>
                      <label className='inline-flex items-center gap-2 text-sm'>
                        <input
                          type='checkbox'
                          checked={mediaLoop}
                          onChange={(event) =>
                            setMediaLoop(event.target.checked)
                          }
                        />
                        Loop
                      </label>
                      <label className='inline-flex items-center gap-2 text-sm'>
                        <input
                          type='checkbox'
                          checked={mediaMuted}
                          onChange={(event) =>
                            setMediaMuted(event.target.checked)
                          }
                        />
                        Muted
                      </label>
                    </div>
                  </FormField>
                </>
              ) : null}

              {errorMessage ? (
                <p className='text-sm text-red-600'>{errorMessage}</p>
              ) : null}
              {successMessage ? (
                <p className='text-sm text-green-600'>{successMessage}</p>
              ) : null}
            </div>
          )}
        </CardBox>
      </SectionMain>
    </>
  );
};

UiElementDetailsPage.getLayout = function getLayout(page: ReactElement) {
  return (
    <LayoutAuthenticated permission='UPDATE_PAGE_ELEMENTS'>
      {page}
    </LayoutAuthenticated>
  );
};

export default UiElementDetailsPage;
