import React, { CSSProperties } from 'react';
import { useNode, UserComponent } from '@craftjs/core';
import { cssPropsToString } from '../../utils/style-helpers';
import { SettingsTabs } from '../../ui/SettingsTabs';
import { BorderControl } from '../../ui/BorderControl';
import { AdvancedTab } from '../../ui/AdvancedTab';
import { AnchorIdField } from '../../ui/AnchorIdField';

interface ContainerProps {
  style?: CSSProperties;
  tag?: 'div' | 'section' | 'article' | 'header' | 'footer' | 'main';
  children?: React.ReactNode;
  cssId?: string;
  cssClass?: string;
  anchorId?: string;
  hideOnDesktop?: boolean;
  hideOnTablet?: boolean;
  hideOnMobile?: boolean;
  animation?: string;
  animationDelay?: string;
  fullWidth?: boolean;
  contentWidth?: 'boxed' | 'full';
}

// Map textAlign to a flex alignItems value so block-level children (images,
// columns, sections) align horizontally — textAlign alone only affects inline
// content. Returns undefined when no alignment is set so we leave layout as
// normal block flow.
const flexAlignFromTextAlign = (textAlign: CSSProperties['textAlign']): CSSProperties => {
  if (textAlign === 'center') return { display: 'flex', flexDirection: 'column', alignItems: 'center' };
  if (textAlign === 'right') return { display: 'flex', flexDirection: 'column', alignItems: 'flex-end' };
  if (textAlign === 'left') return { display: 'flex', flexDirection: 'column', alignItems: 'flex-start' };
  return {};
};

export const Container: UserComponent<ContainerProps> = ({
  style = {},
  tag = 'div',
  children,
  fullWidth = false,
  contentWidth = 'full',
  anchorId,
}) => {
  const { connectors: { connect, drag } } = useNode();

  const needsBoxedWrapper = contentWidth === 'boxed';
  const flexStyles = flexAlignFromTextAlign(style.textAlign);

  const outerStyle: CSSProperties = {
    minHeight: '40px',
    ...style,
    ...(fullWidth ? { width: '100vw', marginLeft: 'calc(-50vw + 50%)' } : {}),
    ...(needsBoxedWrapper ? {} : flexStyles),
  };

  const el = React.createElement(
    tag,
    {
      ref: (ref: HTMLElement | null): void => { if (ref) connect(drag(ref)); },
      style: outerStyle,
      'data-craft-container': 'true',
      id: anchorId || undefined,
    },
    needsBoxedWrapper
      ? React.createElement('div', { style: { maxWidth: '1200px', margin: '0 auto', ...flexStyles } }, children)
      : children,
  );

  return el;
};

/* ---------- Settings panel ---------- */

const cLabelStyle: React.CSSProperties = {
  fontSize: 11, fontWeight: 600, color: '#a1a1aa', display: 'block', marginBottom: 6,
  textTransform: 'uppercase', letterSpacing: '0.3px',
};
const cInputStyle: React.CSSProperties = {
  width: '100%', padding: '5px 8px', background: '#27272a', color: '#e4e4e7',
  border: '1px solid #3f3f46', borderRadius: 4, fontSize: 11,
};
const cPresetBtnStyle = (active: boolean): React.CSSProperties => ({
  padding: '3px 8px', fontSize: 11, borderRadius: 4, cursor: 'pointer',
  border: '1px solid #3f3f46', background: active ? '#3b82f6' : '#27272a', color: active ? '#fff' : '#e4e4e7',
});
const cSwatchStyle = (color: string, active: boolean): React.CSSProperties => ({
  width: 24, height: 24, borderRadius: 4, border: '1px solid #3f3f46', backgroundColor: color, cursor: 'pointer',
  outline: active ? '2px solid #3b82f6' : 'none', outlineOffset: 1,
});

const cToggleBtnStyle = (active: boolean): React.CSSProperties => ({
  flex: 1, padding: '5px 8px', fontSize: 11, borderRadius: 4, cursor: 'pointer',
  border: '1px solid #3f3f46',
  background: active ? '#3b82f6' : '#27272a',
  color: active ? '#fff' : '#e4e4e7',
  fontWeight: active ? 600 : 400,
  textAlign: 'center',
});

const ContainerSettings: React.FC = () => {
  const { actions: { setProp }, props } = useNode((node) => ({
    props: node.data.props as ContainerProps,
  }));

  const bgColors = ['transparent', '#ffffff', '#f9fafb', '#f1f5f9', '#1f2937', '#111827', '#0f172a', '#3b82f6', '#10b981', '#8b5cf6', '#ec4899', '#f59e0b'];
  const gradients = [
    { label: 'None', value: 'none' },
    { label: 'Purple', value: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)' },
    { label: 'Blue', value: 'linear-gradient(135deg, #4facfe 0%, #00f2fe 100%)' },
    { label: 'Sunset', value: 'linear-gradient(135deg, #fa709a 0%, #fee140 100%)' },
    { label: 'Dark', value: 'linear-gradient(135deg, #0f172a 0%, #1e3a5f 100%)' },
    { label: 'Green', value: 'linear-gradient(135deg, #43e97b 0%, #38f9d7 100%)' },
  ];
  const alignPresets = [
    { label: 'Left', value: 'left', icon: 'fa-align-left' },
    { label: 'Center', value: 'center', icon: 'fa-align-center' },
    { label: 'Right', value: 'right', icon: 'fa-align-right' },
  ];

  const currentBg = props.style?.backgroundColor || '';
  const currentBgImage = props.style?.backgroundImage || '';

  return (
    <SettingsTabs
      general={
        <div style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
          <AnchorIdField />
          {/* Tag */}
          <div>
            <label style={cLabelStyle}>HTML Element</label>
            <select
              value={props.tag || 'div'}
              onChange={(e) => setProp((p: ContainerProps) => { p.tag = e.target.value as ContainerProps['tag']; })}
              style={cInputStyle}
            >
              {['div', 'section', 'article', 'header', 'footer', 'main'].map((t) => (
                <option key={t} value={t}>&lt;{t}&gt;</option>
              ))}
            </select>
          </div>

          {/* Full Width */}
          <div>
            <label style={{ ...cLabelStyle, display: 'flex', alignItems: 'center', gap: 6, textTransform: 'none', fontWeight: 500, cursor: 'pointer' }}>
              <input
                type="checkbox"
                checked={props.fullWidth || false}
                onChange={(e) => setProp((p: ContainerProps) => { p.fullWidth = e.target.checked; })}
              />
              Full Width
            </label>
            <span style={{ fontSize: 10, color: '#71717a', lineHeight: '1.3', display: 'block', marginTop: 2 }}>
              Breaks out of parent constraints to fill the viewport width
            </span>
          </div>

          {/* Content Width */}
          <div>
            <label style={cLabelStyle}>Content Width</label>
            <div style={{ display: 'flex', gap: 4 }}>
              <button
                onClick={() => setProp((p: ContainerProps) => { p.contentWidth = 'full'; })}
                style={cToggleBtnStyle((props.contentWidth || 'full') === 'full')}
              >
                Full
              </button>
              <button
                onClick={() => setProp((p: ContainerProps) => { p.contentWidth = 'boxed'; })}
                style={cToggleBtnStyle(props.contentWidth === 'boxed')}
              >
                Boxed (1200px)
              </button>
            </div>
            <span style={{ fontSize: 10, color: '#71717a', lineHeight: '1.3', display: 'block', marginTop: 4 }}>
              {props.contentWidth === 'boxed'
                ? 'Content is centered with a max-width of 1200px'
                : 'Content fills the full container width'}
            </span>
          </div>
        </div>
      }
      style={
        <div style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
          {/* Background Color */}
          <div>
            <label style={cLabelStyle}>Background Color</label>
            <div style={{ display: 'flex', gap: 4, flexWrap: 'wrap' }}>
              {bgColors.map((c) => (
                <button key={c} onClick={() => setProp((p: ContainerProps) => { p.style = { ...p.style, backgroundColor: c, backgroundImage: 'none' }; })}
                  style={cSwatchStyle(c === 'transparent' ? '#fff' : c, currentBg === c)} title={c} />
              ))}
            </div>
          </div>

          {/* Background Gradient */}
          <div>
            <label style={cLabelStyle}>Gradient</label>
            <div style={{ display: 'flex', gap: 4, flexWrap: 'wrap' }}>
              {gradients.map((g) => (
                <button key={g.value} onClick={() => setProp((p: ContainerProps) => {
                  p.style = { ...p.style, backgroundImage: g.value === 'none' ? 'none' : g.value, backgroundColor: 'transparent' };
                })} style={{
                  width: 32, height: 24, borderRadius: 4, cursor: 'pointer',
                  border: currentBgImage === g.value ? '2px solid #3b82f6' : '1px solid #3f3f46',
                  background: g.value === 'none' ? '#27272a' : g.value,
                }} title={g.label} />
              ))}
            </div>
          </div>

          {/* Background Image */}
          <div>
            <label style={cLabelStyle}>Background Image</label>
            <input type="text" placeholder="Image URL..."
              value={(props.style?.backgroundImage || '').replace(/^url\(['"]?|['"]?\)$/g, '')}
              onChange={(e) => {
                const val = e.target.value.trim();
                setProp((p: ContainerProps) => {
                  p.style = { ...p.style, backgroundImage: val ? `url('${val}')` : 'none', backgroundSize: 'cover', backgroundPosition: 'center' };
                });
              }}
              style={cInputStyle} />
            <div style={{ display: 'flex', gap: 4, marginTop: 4 }}>
              {['cover', 'contain', 'auto'].map((s) => (
                <button key={s} onClick={() => setProp((p: ContainerProps) => { p.style = { ...p.style, backgroundSize: s }; })}
                  style={cPresetBtnStyle(props.style?.backgroundSize === s)}>{s}</button>
              ))}
              {['center', 'top', 'bottom'].map((pos) => (
                <button key={pos} onClick={() => setProp((p: ContainerProps) => { p.style = { ...p.style, backgroundPosition: pos }; })}
                  style={cPresetBtnStyle(props.style?.backgroundPosition === pos)}>{pos}</button>
              ))}
            </div>
          </div>

          {/* Overlay */}
          <div>
            <label style={cLabelStyle}>Overlay Color</label>
            <div style={{ display: 'flex', gap: 4, alignItems: 'center' }}>
              <input type="color" value={props.style?.['--overlayColor' as keyof CSSProperties] || '#000000'}
                onChange={(e) => setProp((p: ContainerProps) => { p.style = { ...p.style, ['--overlayColor' as keyof CSSProperties]: e.target.value }; })}
                style={{ width: 32, height: 24, border: 'none', background: 'none', cursor: 'pointer' }} />
              <span style={{ fontSize: 11, color: '#71717a' }}>Overlay (via CSS custom property)</span>
            </div>
          </div>

          {/* Parallax */}
          <div>
            <label style={{ ...cLabelStyle, display: 'flex', alignItems: 'center', gap: 6, textTransform: 'none', fontWeight: 500 }}>
              <input type="checkbox"
                checked={props.style?.backgroundAttachment === 'fixed'}
                onChange={(e) => setProp((p: ContainerProps) => { p.style = { ...p.style, backgroundAttachment: e.target.checked ? 'fixed' : 'scroll' }; })} />
              Parallax Effect
            </label>
          </div>

          {/* Text Alignment */}
          <div>
            <label style={cLabelStyle}>Content Alignment</label>
            <div style={{ display: 'flex', gap: 4 }}>
              {alignPresets.map((a) => (
                <button key={a.value} onClick={() => setProp((p: ContainerProps) => { p.style = { ...p.style, textAlign: a.value as any }; })}
                  style={{ ...cPresetBtnStyle(props.style?.textAlign === a.value), flex: 1 }}>
                  <i className={`fa ${a.icon}`} />
                </button>
              ))}
            </div>
          </div>

          {/* Border */}
          <BorderControl
            style={props.style || {}}
            onChange={(updates) => setProp((p: ContainerProps) => { p.style = { ...p.style, ...updates }; })}
          />
        </div>
      }
      advanced={
        <AdvancedTab
          style={props.style || {}}
          onStyleChange={(updates) => setProp((p: ContainerProps) => { p.style = { ...p.style, ...updates }; })}
          showTagSelector
          tag={props.tag || 'div'}
          onTagChange={(tag) => setProp((p: ContainerProps) => { p.tag = tag as ContainerProps['tag']; })}
          cssId={props.cssId || ''}
          onCssIdChange={(id) => setProp((p: ContainerProps) => { p.cssId = id; })}
          cssClass={props.cssClass || ''}
          onCssClassChange={(cls) => setProp((p: ContainerProps) => { p.cssClass = cls; })}
          hideOnDesktop={props.hideOnDesktop}
          onHideOnDesktopChange={(v) => setProp((p: ContainerProps) => { p.hideOnDesktop = v; })}
          hideOnTablet={props.hideOnTablet}
          onHideOnTabletChange={(v) => setProp((p: ContainerProps) => { p.hideOnTablet = v; })}
          hideOnMobile={props.hideOnMobile}
          onHideOnMobileChange={(v) => setProp((p: ContainerProps) => { p.hideOnMobile = v; })}
          animation={props.animation}
          onAnimationChange={(v) => setProp((p: ContainerProps) => { p.animation = v; })}
          animationDelay={props.animationDelay}
          onAnimationDelayChange={(v) => setProp((p: ContainerProps) => { p.animationDelay = v; })}
        />
      }
    />
  );
};

/* ---------- Craft config ---------- */

Container.craft = {
  displayName: 'Container',
  props: {
    style: { padding: '20px', minHeight: '100px' },
    tag: 'div',
    fullWidth: false,
    contentWidth: 'full',
    anchorId: '',
  },
  rules: {
    canDrag: () => true,
    canMoveIn: () => true,
    canMoveOut: () => true,
  },
  related: {
    settings: ContainerSettings,
  },
};

/* ---------- HTML export ---------- */

(Container as any).toHtml = (props: ContainerProps, childrenHtml: string) => {
  const esc = (s: any) => String(s ?? "").replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
  const tag = props.tag || 'div';
  const isBoxed = props.contentWidth === 'boxed';
  const flexStyles = flexAlignFromTextAlign(props.style?.textAlign);

  const outerCss: CSSProperties = {
    ...props.style,
    ...(isBoxed ? {} : flexStyles),
  };

  if (props.fullWidth) {
    outerCss.width = '100vw';
    outerCss.marginLeft = 'calc(-50vw + 50%)';
  }

  const styleStr = cssPropsToString(outerCss);
  const idAttr = props.anchorId ? ` id="${esc(props.anchorId)}"` : '';

  if (isBoxed) {
    const innerStyle = cssPropsToString({ maxWidth: '1200px', margin: '0 auto', ...flexStyles });
    return { html: `<${tag}${idAttr}${styleStr ? ` style="${styleStr}"` : ''}><div${innerStyle ? ` style="${innerStyle}"` : ''}>${childrenHtml}</div></${tag}>` };
  }

  return { html: `<${tag}${idAttr}${styleStr ? ` style="${styleStr}"` : ''}>${childrenHtml}</${tag}>` };
};
