import React from 'react';
import { useEditor } from '@craftjs/core';
import {
  BG_COLORS,
  RADIUS_PRESETS,
} from '../../../constants/presets';
import {
  StylePanelProps,
  SectionLabel,
  ColorSwatchGrid,
  PresetButtonGrid,
  CollapsibleSection,
  ColorPickerField,
  ArrayPropEditor,
  SizeControl,
  AspectRatioControl,
  labelStyle,
  inputStyle,
  smallInputStyle,
  sectionGap,
  useNodeProp,
} from './shared';
import { AssetPicker } from '../../../ui/AssetPicker';
import { BoxModelSection, BorderEffectsSection, AnimVisSection } from './mediaBoxModel';

const GALLERY_COLUMN_PRESETS = [
  { label: '2', value: '2' },
  { label: '3', value: '3' },
  { label: '4', value: '4' },
  { label: '5', value: '5' },
];

/* ---------- MEDIA (Video / Gallery / Map / Slider) ---------- */
export const MediaStylePanel: React.FC<StylePanelProps> = ({ selectedId, nodeProps }) => {
  const { actions } = useEditor();
  const { setProp, setPropStyle } = useNodeProp(selectedId);

  const style = nodeProps.style || {};

  // Same crop-fills-by-default + no stale-height-conflict treatment as
  // ImageStylePanel (see there for the full rationale): applying a ratio
  // defaults objectFit to 'cover' when unset, and clears height so Width +
  // ratio + cover is the single source of truth for the box.
  const applyAspectRatio = (v: string) => {
    setPropStyle('aspectRatio', v);
    if (v) {
      if (!style.objectFit) setPropStyle('objectFit', 'cover');
      setPropStyle('height', '');
    }
  };

  return (
    <>
      {/* Video source -- upload/browse/paste-URL (paste-URL still handles
          YouTube/Vimeo; upload/browse handle files via detectVideoType's
          serve_asset resolution). */}
      {nodeProps.videoUrl !== undefined && (
        <div className="guided-section">
          <SectionLabel>Video Source</SectionLabel>
          <AssetPicker
            mediaType="video"
            value={nodeProps.videoUrl || ''}
            onChange={(url) => setProp('videoUrl', url)}
            variant="full"
            placeholder="Or paste a YouTube/Vimeo/.mp4 URL..."
          />
        </div>
      )}

      {/* Video size -- width + aspect ratio for the video frame. */}
      {nodeProps.videoUrl !== undefined && (
        <>
          <SizeControl
            label="Width"
            value={(style.width as string) || ''}
            onChange={(v) => setPropStyle('width', v)}
          />
          {/* NOTE: unlike ImageStylePanel, there is no separate Height control
              here to gate on aspect-ratio -- VideoBlock's <video>/iframe size
              themselves from `width` + `aspectRatio` directly (see
              VideoBlock.tsx), not from an outer-wrapper height, so adding one
              would reintroduce the exact empty-space bug this fix targets. */}
          <AspectRatioControl
            value={(style.aspectRatio as string) || ''}
            onChange={applyAspectRatio}
          />
        </>
      )}

      {/* Poster image (optional, file-type videos only in practice but
          harmless to offer whenever the component has a poster prop). */}
      {nodeProps.poster !== undefined && (
        <div className="guided-section">
          <SectionLabel>Poster Image (optional)</SectionLabel>
          <AssetPicker
            mediaType="image"
            value={nodeProps.poster || ''}
            onChange={(url) => setProp('poster', url)}
            variant="full"
          />
        </div>
      )}

      {/* Map URL */}
      {nodeProps.embedUrl !== undefined && nodeProps.videoUrl === undefined && (
        <div style={sectionGap}>
          <label style={labelStyle}>Embed URL</label>
          <input type="text" value={nodeProps.embedUrl || ''} onChange={(e) => setProp('embedUrl', e.target.value)} placeholder="Google Maps embed URL" style={inputStyle} />
        </div>
      )}

      {/* Map address */}
      {nodeProps.address !== undefined && (
        <div style={sectionGap}>
          <label style={labelStyle}>Address</label>
          <input type="text" value={nodeProps.address || ''} onChange={(e) => setProp('address', e.target.value)} placeholder="123 Main St..." style={inputStyle} />
        </div>
      )}

      {/* Video options */}
      {nodeProps.autoplay !== undefined && (
        <div style={sectionGap}>
          <label style={{ ...labelStyle, display: 'flex', alignItems: 'center', gap: 6, cursor: 'pointer' }}>
            <input type="checkbox" checked={nodeProps.autoplay || false} onChange={(e) => setProp('autoplay', e.target.checked)} />
            Autoplay
          </label>
        </div>
      )}
      {nodeProps.loop !== undefined && (
        <div style={sectionGap}>
          <label style={{ ...labelStyle, display: 'flex', alignItems: 'center', gap: 6, cursor: 'pointer' }}>
            <input type="checkbox" checked={nodeProps.loop || false} onChange={(e) => setProp('loop', e.target.checked)} />
            Loop
          </label>
        </div>
      )}
      {nodeProps.controls !== undefined && (
        <div style={sectionGap}>
          <label style={{ ...labelStyle, display: 'flex', alignItems: 'center', gap: 6, cursor: 'pointer' }}>
            <input type="checkbox" checked={nodeProps.controls !== false} onChange={(e) => setProp('controls', e.target.checked)} />
            Show Controls
          </label>
        </div>
      )}

      {/* Gallery layout -- columns + lightbox (existing-but-previously-unexposed props). */}
      {nodeProps.images !== undefined && Array.isArray(nodeProps.images) && (
        <>
          <div className="guided-section">
            <SectionLabel>Columns</SectionLabel>
            <PresetButtonGrid
              presets={GALLERY_COLUMN_PRESETS}
              activeValue={String(nodeProps.columns ?? 3)}
              onSelect={(v) => setProp('columns', Number(v))}
            />
          </div>
          <div style={sectionGap}>
            <label style={{ ...labelStyle, display: 'flex', alignItems: 'center', gap: 6, cursor: 'pointer' }}>
              <input type="checkbox" checked={!!nodeProps.lightbox} onChange={(e) => setProp('lightbox', e.target.checked)} />
              Enable Lightbox
            </label>
          </div>
        </>
      )}

      {/* Gallery items */}
      {nodeProps.images !== undefined && Array.isArray(nodeProps.images) && (
        <CollapsibleSection title="Images">
          <ArrayPropEditor
            selectedId={selectedId}
            propKey="images"
            items={nodeProps.images}
            renderItem={(item: any, index: number) => (
              <div style={{ display: 'flex', flexDirection: 'column', gap: 3 }}>
                {item.src !== undefined && (
                  <AssetPicker
                    variant="compact"
                    value={item.src || ''}
                    onChange={(url) => {
                      actions.setProp(selectedId, (props: any) => {
                        const updated = [...(props.images || [])];
                        updated[index] = { ...updated[index], src: url };
                        props.images = updated;
                      });
                    }}
                  />
                )}
                {item.caption !== undefined && (
                  <input type="text" value={item.caption || ''} onChange={(e) => {
                    actions.setProp(selectedId, (props: any) => {
                      const updated = [...(props.images || [])];
                      updated[index] = { ...updated[index], caption: e.target.value };
                      props.images = updated;
                    });
                  }} placeholder="Caption" style={smallInputStyle} />
                )}
              </div>
            )}
            emptyItem={{ src: '', caption: '' }}
          />
        </CollapsibleSection>
      )}

      {/* Slides */}
      {nodeProps.slides !== undefined && Array.isArray(nodeProps.slides) && (
        <CollapsibleSection title="Slides">
          <ArrayPropEditor
            selectedId={selectedId}
            propKey="slides"
            items={nodeProps.slides}
            renderItem={(item: any, index: number) => (
              <div style={{ display: 'flex', flexDirection: 'column', gap: 3 }}>
                {item.heading !== undefined && (
                  <input type="text" value={item.heading || ''} onChange={(e) => {
                    actions.setProp(selectedId, (props: any) => {
                      const updated = [...(props.slides || [])];
                      updated[index] = { ...updated[index], heading: e.target.value };
                      props.slides = updated;
                    });
                  }} placeholder="Heading" style={smallInputStyle} />
                )}
                {item.text !== undefined && (
                  <textarea value={item.text || ''} onChange={(e) => {
                    actions.setProp(selectedId, (props: any) => {
                      const updated = [...(props.slides || [])];
                      updated[index] = { ...updated[index], text: e.target.value };
                      props.slides = updated;
                    });
                  }} placeholder="Text" rows={2} style={{ ...smallInputStyle, resize: 'vertical' }} />
                )}
                {item.imageSrc !== undefined && (
                  <AssetPicker
                    variant="compact"
                    value={item.imageSrc || ''}
                    onChange={(url) => {
                      actions.setProp(selectedId, (props: any) => {
                        const updated = [...(props.slides || [])];
                        updated[index] = { ...updated[index], imageSrc: url };
                        props.slides = updated;
                      });
                    }}
                  />
                )}
              </div>
            )}
            emptyItem={{ type: 'image', imageSrc: '', heading: 'New Slide', text: '', bgColor: '' }}
          />
        </CollapsibleSection>
      )}

      {/* Overlay */}
      {nodeProps.overlayColor !== undefined && (
        <CollapsibleSection title="Overlay" defaultOpen={false}>
          <ColorPickerField label="Color" value={nodeProps.overlayColor || '#000000'} onChange={(v) => setProp('overlayColor', v)} />
          {nodeProps.overlayOpacity !== undefined && (
            <div style={sectionGap}>
              <label style={labelStyle}>Opacity: {nodeProps.overlayOpacity ?? 0}%</label>
              <input type="range" min={0} max={100} value={nodeProps.overlayOpacity ?? 0} onChange={(e) => setProp('overlayOpacity', parseInt(e.target.value))} style={{ width: '100%' }} />
            </div>
          )}
        </CollapsibleSection>
      )}

      {/* Background & radius */}
      <CollapsibleSection title="Style" defaultOpen={false}>
        <div className="guided-section">
          <SectionLabel>Background</SectionLabel>
          <ColorSwatchGrid colors={BG_COLORS} activeValue={style.backgroundColor} onSelect={(v: string) => setPropStyle('backgroundColor', v)} />
        </div>
        <div className="guided-section">
          <SectionLabel>Border Radius</SectionLabel>
          <PresetButtonGrid presets={RADIUS_PRESETS} activeValue={style.borderRadius as string} onSelect={(v) => setPropStyle('borderRadius', v)} />
        </div>
      </CollapsibleSection>

      {/* Box model + animation/visibility rollout (Video/Gallery/Map/Slider
          all carry these props now, so it's safe to render unconditionally). */}
      <BoxModelSection style={style} setPropStyle={setPropStyle} />
      <BorderEffectsSection style={style} setPropStyle={setPropStyle} />
      <AnimVisSection nodeProps={nodeProps} setProp={setProp} />
    </>
  );
};
