/**
 * useElementSettingsForm
 *
 * Shared hook for managing element settings form state.
 * Used by element-type-defaults, project-element-defaults, and constructor pages.
 */

import { useCallback, useState } from 'react';
import type { ElementStyleProperties } from '../../lib/elementStyles';
import type {
  CanvasElement,
  CanvasElementType,
  GalleryCard,
  CarouselSlide,
} from '../../types/constructor';
import { parseJsonObject } from '../../lib/parseJson';
import {
  extractNumericValue,
  clampPercent,
  parseNullableNumber,
  toUnitValue,
  toOptionalTrimmed,
} from './types';
import {
  createLocalId,
  isNavigationElementType,
  isTooltipElementType,
  isDescriptionElementType,
  isGalleryElementType,
  isCarouselElementType,
  isMediaElementType,
} from '../../lib/elementDefaults';

interface UseElementSettingsFormOptions {
  elementType: CanvasElementType | string;
}

interface FormState {
  // Common settings
  label: string;
  xPercent: string;
  yPercent: string;
  appearDelaySec: string;
  appearDurationSec: string;

  // CSS style settings
  width: string;
  height: string;
  minWidth: string;
  maxWidth: string;
  minHeight: string;
  maxHeight: string;
  margin: string;
  padding: string;
  gap: string;
  fontSize: string;
  lineHeight: string;
  fontWeight: string;
  border: string;
  borderRadius: string;
  opacity: string;
  boxShadow: string;
  display: string;
  position: string;
  justifyContent: string;
  alignItems: string;
  textAlign: string;
  zIndex: string;
  backgroundColor: string;
  color: string;

  // Effect settings
  appearAnimation: string;
  appearAnimationDuration: string;
  appearAnimationEasing: string;
  hoverScale: string;
  hoverOpacity: string;
  hoverBackgroundColor: string;
  hoverColor: string;
  hoverBoxShadow: string;
  hoverTransitionDuration: string;
  focusScale: string;
  focusOpacity: string;
  focusOutline: string;
  focusBoxShadow: string;
  activeScale: string;
  activeOpacity: string;
  activeBackgroundColor: string;

  // Navigation settings
  iconUrl: string;
  navLabel: string;
  navLabelFontFamily: string;
  navType: 'forward' | 'back';
  navDisabled: boolean;
  targetPageId: string;
  targetPageSlug: string;
  transitionVideoUrl: string;
  transitionReverseMode: 'auto_reverse' | 'separate_video';
  reverseVideoUrl: string;

  // Tooltip settings
  tooltipTitle: string;
  tooltipText: string;
  tooltipTitleFontFamily: string;
  tooltipTextFontFamily: string;

  // Description settings
  descriptionTitle: string;
  descriptionText: string;
  descriptionTitleFontSize: string;
  descriptionTextFontSize: string;
  descriptionTitleFontFamily: string;
  descriptionTextFontFamily: string;
  descriptionTitleColor: string;
  descriptionTextColor: string;

  // Media settings
  mediaUrl: string;
  mediaAutoplay: boolean;
  mediaLoop: boolean;
  mediaMuted: boolean;

  // Carousel settings
  carouselPrevIconUrl: string;
  carouselNextIconUrl: string;
  carouselCaptionFontFamily: string;

  // Gallery settings
  galleryTitleFontFamily: string;
  galleryTextFontFamily: string;

  // Complex arrays
  galleryCards: GalleryCard[];
  carouselSlides: CarouselSlide[];
}

const initialState: FormState = {
  label: '',
  xPercent: '0',
  yPercent: '0',
  appearDelaySec: '0',
  appearDurationSec: '',
  width: '',
  height: '',
  minWidth: '',
  maxWidth: '',
  minHeight: '',
  maxHeight: '',
  margin: '',
  padding: '',
  gap: '',
  fontSize: '',
  lineHeight: '',
  fontWeight: '',
  border: '',
  borderRadius: '',
  opacity: '',
  boxShadow: '',
  display: '',
  position: '',
  justifyContent: '',
  alignItems: '',
  textAlign: '',
  zIndex: '',
  backgroundColor: '',
  color: '',
  // Effect settings
  appearAnimation: '',
  appearAnimationDuration: '',
  appearAnimationEasing: '',
  hoverScale: '',
  hoverOpacity: '',
  hoverBackgroundColor: '',
  hoverColor: '',
  hoverBoxShadow: '',
  hoverTransitionDuration: '',
  focusScale: '',
  focusOpacity: '',
  focusOutline: '',
  focusBoxShadow: '',
  activeScale: '',
  activeOpacity: '',
  activeBackgroundColor: '',
  iconUrl: '',
  navLabel: '',
  navLabelFontFamily: '',
  navType: 'forward',
  navDisabled: false,
  targetPageId: '',
  targetPageSlug: '',
  transitionVideoUrl: '',
  transitionReverseMode: 'auto_reverse',
  reverseVideoUrl: '',
  tooltipTitle: '',
  tooltipText: '',
  tooltipTitleFontFamily: '',
  tooltipTextFontFamily: '',
  descriptionTitle: '',
  descriptionText: '',
  descriptionTitleFontSize: '',
  descriptionTextFontSize: '',
  descriptionTitleFontFamily: '',
  descriptionTextFontFamily: '',
  descriptionTitleColor: '',
  descriptionTextColor: '',
  mediaUrl: '',
  mediaAutoplay: false,
  mediaLoop: false,
  mediaMuted: false,
  carouselPrevIconUrl: '',
  carouselNextIconUrl: '',
  carouselCaptionFontFamily: '',
  galleryTitleFontFamily: '',
  galleryTextFontFamily: '',
  galleryCards: [],
  carouselSlides: [],
};

export function useElementSettingsForm(options: UseElementSettingsFormOptions) {
  const { elementType } = options;
  const [state, setState] = useState<FormState>(initialState);

  // Type detection using shared helpers from elementDefaults
  const isNavigationType = isNavigationElementType(elementType);
  const isTooltipType = isTooltipElementType(elementType);
  const isDescriptionType = isDescriptionElementType(elementType);
  const isGalleryType = isGalleryElementType(elementType);
  const isCarouselType = isCarouselElementType(elementType);
  const isMediaType = isMediaElementType(elementType);

  /**
   * Apply settings from JSON to form state
   */
  const applySettings = useCallback(
    (settingsValue?: string | Record<string, unknown>) => {
      const settings = parseJsonObject<Record<string, unknown>>(
        settingsValue,
        {},
      );

      setState({
        label: String(settings.label || ''),
        xPercent: String(settings.xPercent ?? 0),
        yPercent: String(settings.yPercent ?? 0),
        width: extractNumericValue(settings.width),
        height: extractNumericValue(settings.height),
        minWidth: extractNumericValue(settings.minWidth),
        maxWidth: extractNumericValue(settings.maxWidth),
        minHeight: extractNumericValue(settings.minHeight),
        maxHeight: extractNumericValue(settings.maxHeight),
        margin: String(settings.margin || ''),
        padding: String(settings.padding || ''),
        gap: String(settings.gap || ''),
        fontSize: String(settings.fontSize || ''),
        lineHeight: String(settings.lineHeight || ''),
        fontWeight: String(settings.fontWeight || ''),
        border: extractNumericValue(settings.border),
        borderRadius: extractNumericValue(settings.borderRadius),
        opacity: settings.opacity === 0 ? '0' : String(settings.opacity || ''),
        boxShadow: String(settings.boxShadow || ''),
        display: String(settings.display || ''),
        position: String(settings.position || ''),
        justifyContent: String(settings.justifyContent || ''),
        alignItems: String(settings.alignItems || ''),
        textAlign: String(settings.textAlign || ''),
        zIndex: String(settings.zIndex || ''),
        backgroundColor: String(settings.backgroundColor || ''),
        color: String(settings.color || ''),
        // Effect settings
        appearAnimation: String(settings.appearAnimation || ''),
        appearAnimationDuration: String(settings.appearAnimationDuration || ''),
        appearAnimationEasing: String(settings.appearAnimationEasing || ''),
        hoverScale: String(settings.hoverScale || ''),
        hoverOpacity: String(settings.hoverOpacity || ''),
        hoverBackgroundColor: String(settings.hoverBackgroundColor || ''),
        hoverColor: String(settings.hoverColor || ''),
        hoverBoxShadow: String(settings.hoverBoxShadow || ''),
        hoverTransitionDuration: String(settings.hoverTransitionDuration || ''),
        focusScale: String(settings.focusScale || ''),
        focusOpacity: String(settings.focusOpacity || ''),
        focusOutline: String(settings.focusOutline || ''),
        focusBoxShadow: String(settings.focusBoxShadow || ''),
        activeScale: String(settings.activeScale || ''),
        activeOpacity: String(settings.activeOpacity || ''),
        activeBackgroundColor: String(settings.activeBackgroundColor || ''),
        appearDelaySec: String(settings.appearDelaySec ?? 0),
        appearDurationSec:
          settings.appearDurationSec === null ||
          settings.appearDurationSec === undefined
            ? ''
            : String(settings.appearDurationSec),
        iconUrl: String(settings.iconUrl || ''),
        navLabel: String(settings.navLabel || ''),
        navLabelFontFamily: String(settings.navLabelFontFamily || ''),
        navType: settings.navType === 'back' ? 'back' : 'forward',
        navDisabled: Boolean(settings.navDisabled),
        targetPageId: String(settings.targetPageId || ''),
        targetPageSlug: String(settings.targetPageSlug || ''),
        transitionVideoUrl: String(settings.transitionVideoUrl || ''),
        transitionReverseMode:
          settings.transitionReverseMode === 'separate_video'
            ? 'separate_video'
            : 'auto_reverse',
        reverseVideoUrl: String(settings.reverseVideoUrl || ''),
        tooltipTitle: String(settings.tooltipTitle || ''),
        tooltipText: String(settings.tooltipText || ''),
        tooltipTitleFontFamily: String(settings.tooltipTitleFontFamily || ''),
        tooltipTextFontFamily: String(settings.tooltipTextFontFamily || ''),
        descriptionTitle: String(settings.descriptionTitle || ''),
        descriptionText: String(settings.descriptionText || ''),
        descriptionTitleFontSize: String(
          settings.descriptionTitleFontSize || '',
        ),
        descriptionTextFontSize: String(settings.descriptionTextFontSize || ''),
        descriptionTitleFontFamily: String(
          settings.descriptionTitleFontFamily || '',
        ),
        descriptionTextFontFamily: String(
          settings.descriptionTextFontFamily || '',
        ),
        descriptionTitleColor: String(settings.descriptionTitleColor || ''),
        descriptionTextColor: String(settings.descriptionTextColor || ''),
        mediaUrl: String(settings.mediaUrl || ''),
        mediaAutoplay: Boolean(settings.mediaAutoplay),
        mediaLoop: Boolean(settings.mediaLoop),
        mediaMuted: Boolean(settings.mediaMuted),
        carouselPrevIconUrl: String(settings.carouselPrevIconUrl || ''),
        carouselNextIconUrl: String(settings.carouselNextIconUrl || ''),
        carouselCaptionFontFamily: String(settings.carouselCaptionFontFamily || ''),
        galleryTitleFontFamily: String(settings.galleryTitleFontFamily || ''),
        galleryTextFontFamily: String(settings.galleryTextFontFamily || ''),
        galleryCards: Array.isArray(settings.galleryCards)
          ? settings.galleryCards.map(
              (card: Record<string, unknown>, index: number) => ({
                id: String(card?.id || createLocalId()),
                imageUrl: String(card?.imageUrl || ''),
                title: String(card?.title || `Card ${index + 1}`),
                description: String(card?.description || ''),
              }),
            )
          : [],
        carouselSlides: Array.isArray(settings.carouselSlides)
          ? settings.carouselSlides.map(
              (slide: Record<string, unknown>, index: number) => ({
                id: String(slide?.id || createLocalId()),
                imageUrl: String(slide?.imageUrl || ''),
                caption: String(slide?.caption || `Slide ${index + 1}`),
              }),
            )
          : [],
      });
    },
    [],
  );

  /**
   * Update a single field
   */
  const setField = useCallback(
    <K extends keyof FormState>(field: K, value: FormState[K]) => {
      setState((prev) => ({ ...prev, [field]: value }));
    },
    [],
  );

  /**
   * Update multiple fields at once
   */
  const setFields = useCallback((updates: Partial<FormState>) => {
    setState((prev) => ({ ...prev, ...updates }));
  }, []);

  /**
   * Get CSS style values for StyleSettingsSection
   */
  const getStyleValues = useCallback((): ElementStyleProperties => {
    return {
      width: state.width,
      height: state.height,
      minWidth: state.minWidth,
      maxWidth: state.maxWidth,
      minHeight: state.minHeight,
      maxHeight: state.maxHeight,
      margin: state.margin,
      padding: state.padding,
      gap: state.gap,
      fontSize: state.fontSize,
      lineHeight: state.lineHeight,
      fontWeight: state.fontWeight,
      border: state.border,
      borderRadius: state.borderRadius,
      opacity: state.opacity,
      boxShadow: state.boxShadow,
      display: state.display,
      position: state.position,
      justifyContent: state.justifyContent,
      alignItems: state.alignItems,
      textAlign: state.textAlign,
      zIndex: state.zIndex,
      backgroundColor: state.backgroundColor,
      color: state.color,
    };
  }, [state]);

  /**
   * Get effect values for EffectsSettingsSection
   */
  const getEffectValues = useCallback(() => {
    return {
      appearAnimation: state.appearAnimation,
      appearAnimationDuration: state.appearAnimationDuration,
      appearAnimationEasing: state.appearAnimationEasing,
      hoverScale: state.hoverScale,
      hoverOpacity: state.hoverOpacity,
      hoverBackgroundColor: state.hoverBackgroundColor,
      hoverColor: state.hoverColor,
      hoverBoxShadow: state.hoverBoxShadow,
      hoverTransitionDuration: state.hoverTransitionDuration,
      focusScale: state.focusScale,
      focusOpacity: state.focusOpacity,
      focusOutline: state.focusOutline,
      focusBoxShadow: state.focusBoxShadow,
      activeScale: state.activeScale,
      activeOpacity: state.activeOpacity,
      activeBackgroundColor: state.activeBackgroundColor,
    };
  }, [state]);

  /**
   * Gallery card operations
   */
  const addGalleryCard = useCallback(() => {
    setState((prev) => ({
      ...prev,
      galleryCards: [
        ...prev.galleryCards,
        {
          id: createLocalId(),
          imageUrl: '',
          title: `Card ${prev.galleryCards.length + 1}`,
          description: '',
        },
      ],
    }));
  }, []);

  const removeGalleryCard = useCallback((cardId: string) => {
    setState((prev) => ({
      ...prev,
      galleryCards: prev.galleryCards.filter((card) => card.id !== cardId),
    }));
  }, []);

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

  /**
   * Carousel slide operations
   */
  const addCarouselSlide = useCallback(() => {
    setState((prev) => ({
      ...prev,
      carouselSlides: [
        ...prev.carouselSlides,
        {
          id: createLocalId(),
          imageUrl: '',
          caption: `Slide ${prev.carouselSlides.length + 1}`,
        },
      ],
    }));
  }, []);

  const removeCarouselSlide = useCallback((slideId: string) => {
    setState((prev) => ({
      ...prev,
      carouselSlides: prev.carouselSlides.filter(
        (slide) => slide.id !== slideId,
      ),
    }));
  }, []);

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

  /**
   * Build settings JSON for saving
   */
  const buildSettingsJson = useCallback((): Record<string, unknown> => {
    const borderWidthValue = toUnitValue(state.border, 'px');
    const borderRadiusValue = toUnitValue(state.borderRadius, 'px');
    const settings: Record<string, unknown> = {
      label: state.label.trim(),
      xPercent: clampPercent(state.xPercent),
      yPercent: clampPercent(state.yPercent),
      border: borderWidthValue
        ? `${borderWidthValue} solid currentColor`
        : 'none',
      appearDelaySec:
        Number(state.appearDelaySec) >= 0 ? Number(state.appearDelaySec) : 0,
      appearDurationSec: parseNullableNumber(state.appearDurationSec),
    };

    // borderRadius: only include if has value (allows cascade from global defaults)
    if (borderRadiusValue) settings.borderRadius = borderRadiusValue;

    // Dimensional CSS properties
    const widthValue = toUnitValue(state.width, 'vw');
    const heightValue = toUnitValue(state.height, 'vh');
    const minWidthValue = toUnitValue(state.minWidth, 'vw');
    const maxWidthValue = toUnitValue(state.maxWidth, 'vw');
    const minHeightValue = toUnitValue(state.minHeight, 'vh');
    const maxHeightValue = toUnitValue(state.maxHeight, 'vh');

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

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

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

    // Additional CSS properties
    const backgroundColorValue = toOptionalTrimmed(state.backgroundColor);
    const colorValue = toOptionalTrimmed(state.color);

    if (backgroundColorValue) settings.backgroundColor = backgroundColorValue;
    if (colorValue) settings.color = colorValue;

    // Effect properties
    const appearAnimationValue = toOptionalTrimmed(state.appearAnimation);
    const appearAnimationDurationValue = toOptionalTrimmed(
      state.appearAnimationDuration,
    );
    const appearAnimationEasingValue = toOptionalTrimmed(
      state.appearAnimationEasing,
    );
    const hoverScaleValue = toOptionalTrimmed(state.hoverScale);
    const hoverOpacityValue = toOptionalTrimmed(state.hoverOpacity);
    const hoverBackgroundColorValue = toOptionalTrimmed(
      state.hoverBackgroundColor,
    );
    const hoverColorValue = toOptionalTrimmed(state.hoverColor);
    const hoverBoxShadowValue = toOptionalTrimmed(state.hoverBoxShadow);
    const hoverTransitionDurationValue = toOptionalTrimmed(
      state.hoverTransitionDuration,
    );
    const focusScaleValue = toOptionalTrimmed(state.focusScale);
    const focusOpacityValue = toOptionalTrimmed(state.focusOpacity);
    const focusOutlineValue = toOptionalTrimmed(state.focusOutline);
    const focusBoxShadowValue = toOptionalTrimmed(state.focusBoxShadow);
    const activeScaleValue = toOptionalTrimmed(state.activeScale);
    const activeOpacityValue = toOptionalTrimmed(state.activeOpacity);
    const activeBackgroundColorValue = toOptionalTrimmed(
      state.activeBackgroundColor,
    );

    if (appearAnimationValue) settings.appearAnimation = appearAnimationValue;
    if (appearAnimationDurationValue)
      settings.appearAnimationDuration = appearAnimationDurationValue;
    if (appearAnimationEasingValue)
      settings.appearAnimationEasing = appearAnimationEasingValue;
    if (hoverScaleValue) settings.hoverScale = hoverScaleValue;
    if (hoverOpacityValue) settings.hoverOpacity = hoverOpacityValue;
    if (hoverBackgroundColorValue)
      settings.hoverBackgroundColor = hoverBackgroundColorValue;
    if (hoverColorValue) settings.hoverColor = hoverColorValue;
    if (hoverBoxShadowValue) settings.hoverBoxShadow = hoverBoxShadowValue;
    if (hoverTransitionDurationValue)
      settings.hoverTransitionDuration = hoverTransitionDurationValue;
    if (focusScaleValue) settings.focusScale = focusScaleValue;
    if (focusOpacityValue) settings.focusOpacity = focusOpacityValue;
    if (focusOutlineValue) settings.focusOutline = focusOutlineValue;
    if (focusBoxShadowValue) settings.focusBoxShadow = focusBoxShadowValue;
    if (activeScaleValue) settings.activeScale = activeScaleValue;
    if (activeOpacityValue) settings.activeOpacity = activeOpacityValue;
    if (activeBackgroundColorValue)
      settings.activeBackgroundColor = activeBackgroundColorValue;

    // Navigation type settings
    if (isNavigationType) {
      settings.iconUrl = state.iconUrl.trim();
      settings.navLabel = state.navLabel.trim();
      settings.navLabelFontFamily = state.navLabelFontFamily.trim();
      settings.navType = state.navType;
      settings.navDisabled = state.navDisabled;
      settings.targetPageId = state.targetPageId.trim();
      settings.targetPageSlug = state.targetPageSlug.trim();
      settings.transitionVideoUrl = state.transitionVideoUrl.trim();
      settings.transitionReverseMode = state.transitionReverseMode;
      settings.reverseVideoUrl = state.reverseVideoUrl.trim();
    }

    // Tooltip type settings
    if (isTooltipType) {
      settings.iconUrl = state.iconUrl.trim();
      settings.tooltipTitle = state.tooltipTitle.trim();
      settings.tooltipText = state.tooltipText;
      settings.tooltipTitleFontFamily = state.tooltipTitleFontFamily.trim();
      settings.tooltipTextFontFamily = state.tooltipTextFontFamily.trim();
    }

    // Description type settings
    if (isDescriptionType) {
      settings.iconUrl = state.iconUrl.trim();
      settings.descriptionTitle = state.descriptionTitle.trim();
      settings.descriptionText = state.descriptionText;
      settings.descriptionTitleFontSize =
        state.descriptionTitleFontSize.trim() || '48px';
      settings.descriptionTextFontSize =
        state.descriptionTextFontSize.trim() || '36px';
      settings.descriptionTitleFontFamily =
        state.descriptionTitleFontFamily.trim() || 'inherit';
      settings.descriptionTextFontFamily =
        state.descriptionTextFontFamily.trim() || 'inherit';
      settings.descriptionTitleColor =
        state.descriptionTitleColor.trim() || '#000000';
      settings.descriptionTextColor =
        state.descriptionTextColor.trim() || '#4B5563';
    }

    // Gallery type settings
    if (isGalleryType) {
      settings.galleryCards = state.galleryCards.map((card, index) => ({
        id: String(card.id || createLocalId()),
        imageUrl: card.imageUrl.trim(),
        title: card.title.trim() || `Card ${index + 1}`,
        description: card.description,
      }));
      settings.galleryTitleFontFamily = state.galleryTitleFontFamily.trim();
      settings.galleryTextFontFamily = state.galleryTextFontFamily.trim();
    }

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

    // Media type settings
    if (isMediaType) {
      settings.mediaUrl = state.mediaUrl.trim();
      settings.mediaAutoplay = state.mediaAutoplay;
      settings.mediaLoop = state.mediaLoop;
      settings.mediaMuted = state.mediaMuted;
    }

    return settings;
  }, [
    state,
    isNavigationType,
    isTooltipType,
    isDescriptionType,
    isGalleryType,
    isCarouselType,
    isMediaType,
  ]);

  return {
    state,
    setField,
    setFields,
    applySettings,
    getStyleValues,
    getEffectValues,

    // Type checks
    isNavigationType,
    isTooltipType,
    isDescriptionType,
    isGalleryType,
    isCarouselType,
    isMediaType,

    // Gallery operations
    addGalleryCard,
    removeGalleryCard,
    updateGalleryCard,

    // Carousel operations
    addCarouselSlide,
    removeCarouselSlide,
    updateCarouselSlide,

    // Build JSON
    buildSettingsJson,
  };
}

export type { FormState };
