/**
 * RuntimeElement Component
 *
 * Renders a single UI element with interactive effects at runtime.
 * Handles hover, focus, active states and positioning.
 * Delegates element styling and content to UiElementRenderer.
 */

import React from 'react';
import UiElementRenderer from './UiElements/UiElementRenderer';
import { useElementEffects } from '../hooks/useElementEffects';
import {
  buildTransitionStyle,
  buildAppearAnimationStyle,
  hasAnyEffects,
  type ElementEffectProperties,
} from '../lib/elementEffects';
import type { CanvasElement } from '../types/constructor';
import type { ResolvedTransitionSettings } from '../types/transition';
import type { PreloadCacheProvider } from '../hooks/video';

interface RuntimeElementProps {
  element: CanvasElement;
  onClick: () => void;
  /** Optional URL resolver for preloaded blob URLs */
  resolveUrl?: (url: string | undefined) => string;
  /** Gallery card click handler */
  onGalleryCardClick?: (cardIndex: number) => void;
  /** Letterbox styles for constraining fullscreen elements to canvas bounds */
  letterboxStyles?: React.CSSProperties;
  /** Page transition settings (for slide transition cascade in carousel/gallery) */
  pageTransitionSettings?: ResolvedTransitionSettings;
  /** Preload cache provider for video elements */
  preloadCache?: PreloadCacheProvider;
}

// Clamp position to canvas bounds (0-100%)
const clamp = (value: number, min: number, max: number) =>
  Math.min(Math.max(value, min), max);

const RuntimeElement: React.FC<RuntimeElementProps> = ({
  element,
  onClick,
  resolveUrl,
  onGalleryCardClick,
  letterboxStyles,
  pageTransitionSettings,
  preloadCache,
}) => {
  // Clamp coordinates to canvas bounds
  const xPercent = clamp(element.xPercent ?? 50, 0, 100);
  const yPercent = clamp(element.yPercent ?? 50, 0, 100);
  const rotation = element.rotation ?? 0;

  // Extract effect properties from element
  const effectProperties: Partial<ElementEffectProperties> = {
    appearAnimation: element.appearAnimation,
    appearAnimationDuration: element.appearAnimationDuration,
    appearAnimationEasing: element.appearAnimationEasing,
    hoverScale: element.hoverScale,
    hoverOpacity: element.hoverOpacity,
    hoverBackgroundColor: element.hoverBackgroundColor,
    hoverColor: element.hoverColor,
    hoverBoxShadow: element.hoverBoxShadow,
    hoverTransitionDuration: element.hoverTransitionDuration,
    focusScale: element.focusScale,
    focusOpacity: element.focusOpacity,
    focusOutline: element.focusOutline,
    focusBoxShadow: element.focusBoxShadow,
    activeScale: element.activeScale,
    activeOpacity: element.activeOpacity,
    activeBackgroundColor: element.activeBackgroundColor,
  };

  // Use effects hook for interactive states
  const { effectStyle, eventHandlers } = useElementEffects(effectProperties);

  // Build base position style
  let positionStyle: React.CSSProperties = {
    left: `${xPercent}%`,
    top: `${yPercent}%`,
    transform: `translate(-50%, -50%)${rotation ? ` rotate(${rotation}deg)` : ''}`,
  };

  // Merge transform if effect style has transform
  if (effectStyle.transform) {
    // Preserve the translate and rotation, add effect transform
    positionStyle.transform = `translate(-50%, -50%)${rotation ? ` rotate(${rotation}deg)` : ''} ${effectStyle.transform}`;
    // Remove transform from effectStyle to avoid double application
    const { transform, ...restEffectStyle } = effectStyle;
    positionStyle = { ...positionStyle, ...restEffectStyle };
  } else {
    positionStyle = { ...positionStyle, ...effectStyle };
  }

  // Add transition if element has any effects
  if (hasAnyEffects(effectProperties)) {
    const transitionStyle = buildTransitionStyle(effectProperties);
    positionStyle = { ...positionStyle, ...transitionStyle };
  }

  // Add appear animation if configured
  if (effectProperties.appearAnimation) {
    const animationStyle = buildAppearAnimationStyle(effectProperties);
    positionStyle = { ...positionStyle, ...animationStyle };
  }

  return (
    <div
      className='absolute cursor-pointer'
      style={positionStyle}
      onClick={onClick}
      tabIndex={0}
      {...eventHandlers}
    >
      <UiElementRenderer
        element={element}
        resolveUrl={resolveUrl}
        onGalleryCardClick={onGalleryCardClick}
        letterboxStyles={letterboxStyles}
        pageTransitionSettings={pageTransitionSettings}
        preloadCache={preloadCache}
      />
    </div>
  );
};

export default RuntimeElement;
