/**
 * ElementEditorPanel Component
 *
 * Renders the element editor sidebar in the constructor.
 * Handles element settings, background settings, and transition creation.
 */

import React from 'react';
import {
  ElementSettingsTabsCompact,
  StyleSettingsSectionCompact,
  EffectsSettingsSectionCompact,
  CommonSettingsSectionCompact,
  TooltipSettingsSectionCompact,
  DescriptionSettingsSectionCompact,
  MediaSettingsSectionCompact,
  GallerySettingsSectionCompact,
  CarouselSettingsSectionCompact,
  GalleryCarouselSettingsSectionCompact,
  extractNumericValue,
} from '../ElementSettings';
import BackgroundSettingsEditor from './BackgroundSettingsEditor';
import CreateTransitionForm from './CreateTransitionForm';
import ElementEditorHeader from './ElementEditorHeader';
import NavigationSettingsSectionCompact from '../ElementSettings/NavigationSettingsSectionCompact';
import {
  normalizeAppearDelaySec,
  normalizeAppearDurationSec,
  isNavigationElementType,
  isTooltipElementType,
  isDescriptionElementType,
  isGalleryElementType,
  isCarouselElementType,
  isMediaElementType,
  isVideoPlayerElementType,
} from '../../lib/elementDefaults';
import type {
  CanvasElement,
  CanvasElementType,
  GalleryCard,
  GalleryInfoSpan,
  CarouselSlide,
} from '../../types/constructor';

type NavigationElementType = Extract<
  CanvasElementType,
  'navigation_next' | 'navigation_prev'
>;

type EditorMenuItem =
  | 'none'
  | 'background_image'
  | 'background_video'
  | 'background_audio'
  | 'create_transition';

type TourPage = {
  id: string;
  name?: string;
  slug?: string;
  sort_order?: number;
};

interface AssetOption {
  value: string;
  label: string;
}

interface ElementEditorPanelProps {
  // Refs and positioning
  elementEditorRef: React.RefObject<HTMLDivElement | null>;
  position: { x: number; y: number };
  isCollapsed: boolean;
  onToggleCollapse: () => void;
  onDragStart: (event: React.MouseEvent) => void;

  // Editor state
  title: string;
  activeTab: 'general' | 'css' | 'effects';
  onTabChange: (tab: 'general' | 'css' | 'effects') => void;

  // Selected element
  selectedElement: CanvasElement | null;
  selectedMenuItem: EditorMenuItem;
  onRemoveElement: () => void;
  onUpdateElement: (patch: Partial<CanvasElement>) => void;

  // Background settings
  backgroundImageUrl: string;
  backgroundVideoUrl: string;
  backgroundAudioUrl: string;
  onBackgroundImageChange: (value: string) => void;
  onBackgroundVideoChange: (value: string) => void;
  onBackgroundAudioChange: (value: string) => void;

  // Transition creation
  newTransitionName: string;
  newTransitionVideoUrl: string;
  newTransitionSupportsReverse: boolean;
  isCreatingTransition: boolean;
  onNewTransitionNameChange: (value: string) => void;
  onNewTransitionVideoUrlChange: (value: string) => void;
  onNewTransitionSupportsReverseChange: (value: boolean) => void;
  onCreateTransition: () => void;

  // Duration notes
  backgroundVideoDurationNote: string;
  backgroundAudioDurationNote: string;
  newTransitionDurationNote: string;
  selectedMediaDurationNote: string;
  selectedTransitionDurationNote: string;

  // Asset options
  backgroundImageAssetOptions: AssetOption[];
  videoAssetOptions: AssetOption[];
  audioAssetOptions: AssetOption[];
  transitionVideoAssetOptions: AssetOption[];
  iconAssetOptions: AssetOption[];
  imageAssetOptions: AssetOption[];

  // Navigation settings
  allowedNavigationTypes: NavigationElementType[];
  pages: TourPage[];
  activePageId: string;
  onPreviewTransition: (direction: 'forward' | 'back') => void;

  // Gallery/Carousel operations
  galleryCards: {
    add: () => void;
    update: (cardId: string, patch: Partial<GalleryCard>) => void;
    remove: (cardId: string) => void;
  };
  galleryInfoSpans: {
    add: () => void;
    update: (spanId: string, text: string) => void;
    remove: (spanId: string) => void;
  };
  carouselSlides: {
    add: () => void;
    update: (slideId: string, patch: Partial<CarouselSlide>) => void;
    remove: (slideId: string) => void;
  };

  // Navigation type normalization
  normalizeNavigationType: (
    element: CanvasElement,
    nextType: NavigationElementType,
  ) => CanvasElement;

  // Duration resolver
  getDuration: (url: string) => number | undefined;
}

/**
 * Handle CSS property changes with unit conversion
 */
const handleCssPropertyChange = (
  prop: string,
  value: string | number | boolean,
  onUpdateElement: (patch: Partial<CanvasElement>) => void,
) => {
  const numericProps = [
    'width',
    'height',
    'minWidth',
    'maxWidth',
    'minHeight',
    'maxHeight',
    'border',
    'borderRadius',
  ];

  const getUnit = (p: string) => {
    if (['width', 'minWidth', 'maxWidth'].includes(p)) return 'vw';
    if (['height', 'minHeight', 'maxHeight'].includes(p)) return 'vh';
    if (['border', 'borderRadius'].includes(p)) return 'px';
    return '';
  };

  if (numericProps.includes(prop)) {
    const trimmed = String(value || '').trim();
    if (prop === 'border') {
      onUpdateElement({
        [prop]: trimmed ? `${trimmed}px solid currentColor` : 'none',
      });
    } else if (prop === 'borderRadius') {
      onUpdateElement({
        [prop]: trimmed ? `${trimmed}px` : undefined,
      });
    } else {
      const unit = getUnit(prop);
      onUpdateElement({
        [prop]: trimmed ? `${trimmed}${unit}` : undefined,
      });
    }
  } else {
    onUpdateElement({
      [prop]: value || undefined,
    });
  }
};

export function ElementEditorPanel({
  elementEditorRef,
  position,
  isCollapsed,
  onToggleCollapse,
  onDragStart,
  title,
  activeTab,
  onTabChange,
  selectedElement,
  selectedMenuItem,
  onRemoveElement,
  onUpdateElement,
  backgroundImageUrl,
  backgroundVideoUrl,
  backgroundAudioUrl,
  onBackgroundImageChange,
  onBackgroundVideoChange,
  onBackgroundAudioChange,
  newTransitionName,
  newTransitionVideoUrl,
  newTransitionSupportsReverse,
  isCreatingTransition,
  onNewTransitionNameChange,
  onNewTransitionVideoUrlChange,
  onNewTransitionSupportsReverseChange,
  onCreateTransition,
  backgroundVideoDurationNote,
  backgroundAudioDurationNote,
  newTransitionDurationNote,
  selectedMediaDurationNote,
  selectedTransitionDurationNote,
  backgroundImageAssetOptions,
  videoAssetOptions,
  audioAssetOptions,
  transitionVideoAssetOptions,
  iconAssetOptions,
  imageAssetOptions,
  allowedNavigationTypes,
  pages,
  activePageId,
  onPreviewTransition,
  galleryCards,
  galleryInfoSpans,
  carouselSlides,
  normalizeNavigationType,
  getDuration,
}: ElementEditorPanelProps) {
  return (
    <div
      ref={elementEditorRef}
      className={`fixed z-40 ${isCollapsed ? 'w-[260px]' : 'w-[380px]'} max-h-[calc(100vh-2rem)] overflow-auto rounded-lg border border-gray-200 bg-white/95 p-3 shadow-xl`}
      style={{ left: position.x, top: position.y }}
    >
      <ElementEditorHeader
        title={title}
        isCollapsed={isCollapsed}
        showRemoveButton={Boolean(selectedElement)}
        onToggleCollapse={onToggleCollapse}
        onRemove={onRemoveElement}
        onDragStart={onDragStart}
      />

      {!isCollapsed && (
        <>
          {selectedMenuItem === 'background_image' && (
            <BackgroundSettingsEditor
              type='image'
              value={backgroundImageUrl}
              options={backgroundImageAssetOptions}
              onChange={(value) => {
                onBackgroundImageChange(value);
                if (value) onBackgroundVideoChange('');
              }}
            />
          )}

          {selectedMenuItem === 'background_video' && (
            <BackgroundSettingsEditor
              type='video'
              value={backgroundVideoUrl}
              options={videoAssetOptions}
              durationNote={backgroundVideoDurationNote}
              onChange={(value) => {
                onBackgroundVideoChange(value);
                if (value) onBackgroundImageChange('');
              }}
            />
          )}

          {selectedMenuItem === 'background_audio' && (
            <BackgroundSettingsEditor
              type='audio'
              value={backgroundAudioUrl}
              options={audioAssetOptions}
              durationNote={backgroundAudioDurationNote}
              onChange={onBackgroundAudioChange}
            />
          )}

          {selectedMenuItem === 'create_transition' && (
            <CreateTransitionForm
              name={newTransitionName}
              videoUrl={newTransitionVideoUrl}
              supportsReverse={newTransitionSupportsReverse}
              videoOptions={transitionVideoAssetOptions}
              durationNote={newTransitionDurationNote}
              isCreating={isCreatingTransition}
              onNameChange={onNewTransitionNameChange}
              onVideoUrlChange={onNewTransitionVideoUrlChange}
              onSupportsReverseChange={onNewTransitionSupportsReverseChange}
              onSubmit={onCreateTransition}
            />
          )}

          {selectedElement && (
            <>
              <ElementSettingsTabsCompact
                activeTab={activeTab}
                onTabChange={(tab) =>
                  onTabChange(tab as 'general' | 'css' | 'effects')
                }
                tabs={[
                  { id: 'general', label: 'General' },
                  { id: 'css', label: 'CSS' },
                  { id: 'effects', label: 'Effects' },
                ]}
              />

              {activeTab === 'general' && (
                <>
                  <CommonSettingsSectionCompact
                    label={selectedElement.label}
                    xPercent={String(selectedElement.xPercent ?? 50)}
                    yPercent={String(selectedElement.yPercent ?? 50)}
                    appearDelaySec={String(selectedElement.appearDelaySec ?? 0)}
                    appearDurationSec={
                      selectedElement.appearDurationSec != null
                        ? String(selectedElement.appearDurationSec)
                        : ''
                    }
                    showPosition={false}
                    onChange={(prop, value) => {
                      if (prop === 'label') {
                        onUpdateElement({ label: value });
                      } else if (prop === 'appearDelaySec') {
                        onUpdateElement({
                          appearDelaySec: normalizeAppearDelaySec(value),
                        });
                      } else if (prop === 'appearDurationSec') {
                        onUpdateElement({
                          appearDurationSec: normalizeAppearDurationSec(value),
                        });
                      }
                    }}
                  />

                  {isNavigationElementType(selectedElement.type) && (
                    <NavigationSettingsSectionCompact
                      type={
                        selectedElement.type as
                          | 'navigation_next'
                          | 'navigation_prev'
                      }
                      navType={selectedElement.navType}
                      navLabel={selectedElement.navLabel || ''}
                      navLabelFontFamily={selectedElement.navLabelFontFamily || ''}
                      navDisabled={selectedElement.navDisabled || false}
                      iconUrl={selectedElement.iconUrl || ''}
                      targetPageSlug={selectedElement.targetPageSlug || ''}
                      transitionVideoUrl={
                        selectedElement.transitionVideoUrl || ''
                      }
                      transitionReverseMode={
                        selectedElement.transitionReverseMode || 'auto_reverse'
                      }
                      reverseVideoUrl={selectedElement.reverseVideoUrl || ''}
                      allowedNavigationTypes={allowedNavigationTypes}
                      iconAssetOptions={iconAssetOptions}
                      transitionVideoOptions={transitionVideoAssetOptions}
                      pages={pages}
                      activePageId={activePageId}
                      selectedMediaDurationNote={selectedMediaDurationNote}
                      selectedTransitionDurationNote={
                        selectedTransitionDurationNote
                      }
                      onChange={(prop, value) => {
                        if (prop === 'type') {
                          const nextType = value as NavigationElementType;
                          onUpdateElement(
                            normalizeNavigationType(selectedElement, nextType),
                          );
                        } else if (prop === 'transitionVideoUrl') {
                          const nextVideoUrl = value as string;
                          const resolvedDuration = getDuration(nextVideoUrl);
                          onUpdateElement({
                            transitionVideoUrl: nextVideoUrl,
                            transitionDurationSec:
                              resolvedDuration || undefined,
                          });
                        } else if (prop === 'targetPageSlug') {
                          onUpdateElement({
                            targetPageSlug: value as string,
                            targetPageId: '',
                          });
                        } else {
                          onUpdateElement({
                            [prop]: value,
                          });
                        }
                      }}
                      onPreviewTransition={onPreviewTransition}
                    />
                  )}

                  {selectedElement &&
                    isTooltipElementType(selectedElement.type) && (
                      <TooltipSettingsSectionCompact
                        iconUrl={selectedElement.iconUrl || ''}
                        tooltipTitle={selectedElement.tooltipTitle || ''}
                        tooltipText={selectedElement.tooltipText || ''}
                        tooltipTitleFontFamily={
                          selectedElement.tooltipTitleFontFamily || ''
                        }
                        tooltipTextFontFamily={
                          selectedElement.tooltipTextFontFamily || ''
                        }
                        iconAssetOptions={iconAssetOptions}
                        onChange={(prop, value) =>
                          onUpdateElement({ [prop]: value })
                        }
                      />
                    )}

                  {selectedElement &&
                    isDescriptionElementType(selectedElement.type) && (
                      <DescriptionSettingsSectionCompact
                        iconUrl={selectedElement.iconUrl || ''}
                        descriptionTitle={
                          selectedElement.descriptionTitle || ''
                        }
                        descriptionText={selectedElement.descriptionText || ''}
                        descriptionTitleFontSize={
                          selectedElement.descriptionTitleFontSize || '48px'
                        }
                        descriptionTextFontSize={
                          selectedElement.descriptionTextFontSize || '36px'
                        }
                        descriptionTitleFontFamily={
                          selectedElement.descriptionTitleFontFamily ||
                          'inherit'
                        }
                        descriptionTextFontFamily={
                          selectedElement.descriptionTextFontFamily || 'inherit'
                        }
                        descriptionTitleColor={
                          selectedElement.descriptionTitleColor || '#000000'
                        }
                        descriptionTextColor={
                          selectedElement.descriptionTextColor || '#4B5563'
                        }
                        iconAssetOptions={iconAssetOptions}
                        onChange={(prop, value) =>
                          onUpdateElement({ [prop]: value })
                        }
                      />
                    )}

                  {selectedElement &&
                    isMediaElementType(selectedElement.type) && (
                      <MediaSettingsSectionCompact
                        mediaType={
                          isVideoPlayerElementType(selectedElement.type)
                            ? 'video'
                            : 'audio'
                        }
                        mediaUrl={selectedElement.mediaUrl || ''}
                        mediaAutoplay={Boolean(selectedElement.mediaAutoplay)}
                        mediaLoop={Boolean(selectedElement.mediaLoop)}
                        mediaMuted={Boolean(selectedElement.mediaMuted)}
                        videoAssetOptions={videoAssetOptions}
                        audioAssetOptions={audioAssetOptions}
                        onChange={(prop, value) =>
                          onUpdateElement({ [prop]: value })
                        }
                      />
                    )}

                  {selectedElement &&
                    isGalleryElementType(selectedElement.type) && (
                      <>
                        <GallerySettingsSectionCompact
                          galleryHeaderImageUrl={
                            selectedElement.galleryHeaderImageUrl || ''
                          }
                          galleryTitle={selectedElement.galleryTitle || ''}
                          galleryInfoSpans={
                            selectedElement.galleryInfoSpans || []
                          }
                          galleryColumns={selectedElement.galleryColumns || 3}
                          galleryTitleFontFamily={
                            selectedElement.galleryTitleFontFamily || ''
                          }
                          galleryTextFontFamily={
                            selectedElement.galleryTextFontFamily || ''
                          }
                          galleryCards={selectedElement.galleryCards || []}
                          imageAssetOptions={imageAssetOptions}
                          onUpdateHeader={(patch) => onUpdateElement(patch)}
                          onAddInfoSpan={galleryInfoSpans.add}
                          onUpdateInfoSpan={galleryInfoSpans.update}
                          onRemoveInfoSpan={galleryInfoSpans.remove}
                          onAddCard={galleryCards.add}
                          onUpdateCard={galleryCards.update}
                          onRemoveCard={galleryCards.remove}
                        />
                        <GalleryCarouselSettingsSectionCompact
                          prevIconUrl={
                            selectedElement.galleryCarouselPrevIconUrl || ''
                          }
                          nextIconUrl={
                            selectedElement.galleryCarouselNextIconUrl || ''
                          }
                          backIconUrl={
                            selectedElement.galleryCarouselBackIconUrl || ''
                          }
                          backLabel={
                            selectedElement.galleryCarouselBackLabel || ''
                          }
                          prevWidth={
                            selectedElement.galleryCarouselPrevWidth || ''
                          }
                          prevHeight={
                            selectedElement.galleryCarouselPrevHeight || ''
                          }
                          nextWidth={
                            selectedElement.galleryCarouselNextWidth || ''
                          }
                          nextHeight={
                            selectedElement.galleryCarouselNextHeight || ''
                          }
                          backWidth={
                            selectedElement.galleryCarouselBackWidth || ''
                          }
                          backHeight={
                            selectedElement.galleryCarouselBackHeight || ''
                          }
                          iconAssetOptions={iconAssetOptions}
                          onUpdateElement={onUpdateElement}
                        />
                      </>
                    )}

                  {selectedElement &&
                    isCarouselElementType(selectedElement.type) && (
                      <CarouselSettingsSectionCompact
                        carouselSlides={selectedElement.carouselSlides || []}
                        carouselPrevIconUrl={
                          selectedElement.carouselPrevIconUrl || ''
                        }
                        carouselNextIconUrl={
                          selectedElement.carouselNextIconUrl || ''
                        }
                        carouselCaptionFontFamily={
                          selectedElement.carouselCaptionFontFamily || ''
                        }
                        iconAssetOptions={iconAssetOptions}
                        imageAssetOptions={imageAssetOptions}
                        onUpdateElement={onUpdateElement}
                        onAddSlide={carouselSlides.add}
                        onUpdateSlide={carouselSlides.update}
                        onRemoveSlide={carouselSlides.remove}
                      />
                    )}
                </>
              )}

              {/* CSS Styles Tab */}
              {activeTab === 'css' && (
                <StyleSettingsSectionCompact
                  values={{
                    width: extractNumericValue(selectedElement.width),
                    height: extractNumericValue(selectedElement.height),
                    minWidth: extractNumericValue(selectedElement.minWidth),
                    maxWidth: extractNumericValue(selectedElement.maxWidth),
                    minHeight: extractNumericValue(selectedElement.minHeight),
                    maxHeight: extractNumericValue(selectedElement.maxHeight),
                    margin: selectedElement.margin || '',
                    padding: selectedElement.padding || '',
                    gap: selectedElement.gap || '',
                    fontSize: selectedElement.fontSize || '',
                    lineHeight: selectedElement.lineHeight || '',
                    fontWeight: selectedElement.fontWeight || '',
                    border: extractNumericValue(selectedElement.border),
                    borderRadius: extractNumericValue(
                      selectedElement.borderRadius,
                    ),
                    opacity: selectedElement.opacity || '',
                    boxShadow: selectedElement.boxShadow || '',
                    display: selectedElement.display || '',
                    position: selectedElement.position || '',
                    justifyContent: selectedElement.justifyContent || '',
                    alignItems: selectedElement.alignItems || '',
                    textAlign: selectedElement.textAlign || '',
                    zIndex: selectedElement.zIndex || '',
                    backgroundColor: selectedElement.backgroundColor || '',
                    color: selectedElement.color || '',
                  }}
                  onChange={(prop, value) =>
                    handleCssPropertyChange(prop, value, onUpdateElement)
                  }
                />
              )}

              {/* Effects Tab */}
              {activeTab === 'effects' && (
                <EffectsSettingsSectionCompact
                  values={{
                    appearAnimation: selectedElement.appearAnimation || '',
                    appearAnimationDuration:
                      selectedElement.appearAnimationDuration || '',
                    appearAnimationEasing:
                      selectedElement.appearAnimationEasing || '',
                    hoverScale: selectedElement.hoverScale || '',
                    hoverOpacity: selectedElement.hoverOpacity || '',
                    hoverBackgroundColor:
                      selectedElement.hoverBackgroundColor || '',
                    hoverColor: selectedElement.hoverColor || '',
                    hoverBoxShadow: selectedElement.hoverBoxShadow || '',
                    hoverTransitionDuration:
                      selectedElement.hoverTransitionDuration || '',
                    focusScale: selectedElement.focusScale || '',
                    focusOpacity: selectedElement.focusOpacity || '',
                    focusOutline: selectedElement.focusOutline || '',
                    focusBoxShadow: selectedElement.focusBoxShadow || '',
                    activeScale: selectedElement.activeScale || '',
                    activeOpacity: selectedElement.activeOpacity || '',
                    activeBackgroundColor:
                      selectedElement.activeBackgroundColor || '',
                  }}
                  onChange={(prop, value) => {
                    onUpdateElement({
                      [prop]: value || undefined,
                    });
                  }}
                />
              )}
            </>
          )}
        </>
      )}
    </div>
  );
}

export default ElementEditorPanel;
