import React from 'react';
import {
  BG_COLORS,
  SPACING_PRESETS,
  RADIUS_PRESETS,
  SHADOW_PRESETS,
} from '../../../constants/presets';
import {
  StylePanelProps,
  SectionLabel,
  ColorSwatchGrid,
  PresetButtonGrid,
  CollapsibleSection,
  ColorPickerField,
  labelStyle,
  inputStyle,
  sectionGap,
  useNodeProp,
  SpacingControl,
  BorderControl,
  BorderValue,
  buildBorderShorthand,
  AnimationControl,
  VisibilityControl,
} from './shared';
import { FeaturesEditor } from './FeaturesEditor';
import { ArrayItemFieldsEditor } from './ArrayItemFields';

/** Parses a border shorthand string ("2px solid #hex") produced by
 *  buildBorderShorthand() back into its parts for round-tripping through
 *  BorderControl. Anything that doesn't match (undefined/'none'/legacy
 *  hand-authored values) falls back to an empty/none border rather than
 *  throwing, since this is display-only -- the next edit always re-emits a
 *  clean shorthand via buildBorderShorthand(). */
function parseBorderShorthand(v: string | undefined): BorderValue {
  if (!v || v === 'none') return { width: '', style: 'none', color: '#000000' };
  const m = String(v).match(/^([\d.]+[a-z%]*)\s+(\w+)\s+(.+)$/);
  if (!m) return { width: '', style: 'none', color: '#000000' };
  return { width: m[1], style: m[2], color: m[3] };
}

const capSide = (s: string): string => s.charAt(0).toUpperCase() + s.slice(1);

/* ---------- SECTION-TYPE (Accordion, Tabs, Pricing, Testimonials, etc.) ---------- */
export const SectionTypePanel: React.FC<StylePanelProps & { typeName: string }> = ({ selectedId, nodeProps, typeName }) => {
  const { setProp, setPropStyle } = useNodeProp(selectedId);

  const style = nodeProps.style || {};

  // Find all string/number/boolean props
  const SKIP_PROPS = new Set([
    'style', 'children', 'cssId', 'cssClass',
    // Rendered via dedicated controls below (Animation/Visibility), not the
    // generic Content field dump -- otherwise they'd show up twice.
    'animation', 'animationDelay', 'hideOnDesktop', 'hideOnTablet', 'hideOnMobile',
  ]);
  const scalarProps = Object.entries(nodeProps).filter(
    ([key, val]) => !SKIP_PROPS.has(key) && (typeof val === 'string' || typeof val === 'number' || typeof val === 'boolean')
  );
  const colorProps = scalarProps.filter(([key]) => /color/i.test(key));
  const otherScalarProps = scalarProps.filter(([key]) => !/color/i.test(key));
  const arrayProps = Object.entries(nodeProps).filter(([key, val]) => !SKIP_PROPS.has(key) && Array.isArray(val));

  return (
    <>
      {/* Content props */}
      {otherScalarProps.length > 0 && (
        <CollapsibleSection title="Content">
          {otherScalarProps.map(([key, val]) => {
            const humanLabel = key.replace(/([A-Z])/g, ' $1').trim();
            if (typeof val === 'boolean') {
              return (
                <div key={key} style={sectionGap}>
                  <label style={{ ...labelStyle, display: 'flex', alignItems: 'center', gap: 6, cursor: 'pointer' }}>
                    <input type="checkbox" checked={val} onChange={(e) => setProp(key, e.target.checked)} />
                    {humanLabel}
                  </label>
                </div>
              );
            }
            if (typeof val === 'number') {
              return (
                <div key={key} style={sectionGap}>
                  <label style={labelStyle}>{humanLabel}</label>
                  <input type="number" value={val} onChange={(e) => setProp(key, parseFloat(e.target.value) || 0)} style={inputStyle} />
                </div>
              );
            }
            // String - use textarea for long values
            const isLong = String(val).length > 60;
            return (
              <div key={key} style={sectionGap}>
                <label style={labelStyle}>{humanLabel}</label>
                {isLong ? (
                  <textarea value={String(val)} onChange={(e) => setProp(key, e.target.value)} rows={3} style={{ ...inputStyle, resize: 'vertical' }} />
                ) : (
                  <input type="text" value={String(val)} onChange={(e) => setProp(key, e.target.value)} style={inputStyle} />
                )}
              </div>
            );
          })}
        </CollapsibleSection>
      )}

      {/* Color props */}
      {colorProps.length > 0 && (
        <CollapsibleSection title="Colors">
          {colorProps.map(([key, val]) => (
            <ColorPickerField key={key} label={key.replace(/([A-Z])/g, ' $1').trim()} value={String(val)} onChange={(v) => setProp(key, v)} />
          ))}
        </CollapsibleSection>
      )}

      {/* Array props (features, items, plans, testimonials, etc.) */}
      {arrayProps.map(([key, items]) => {
        // FeaturesGrid gets a dedicated editor (icon/image+upload/button per card),
        // robust to template features that lack the image/button keys.
        if (key === 'features') {
          return (
            <CollapsibleSection key={key} title="Features" defaultOpen>
              <FeaturesEditor selectedId={selectedId} features={items} />
            </CollapsibleSection>
          );
        }
        const arrayItems = items as any[];
        if (arrayItems.length === 0 && typeof arrayItems[0] !== 'object') return null;

        return <ArrayItemFieldsEditor key={key} selectedId={selectedId} propKey={key} items={arrayItems} />;
      })}

      {/* Style */}
      <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>Padding</SectionLabel>
          <PresetButtonGrid presets={SPACING_PRESETS} activeValue={style.padding as string} onSelect={(v) => setPropStyle('padding', v)} />
        </div>
        <div className="guided-section">
          <SectionLabel>Text Alignment</SectionLabel>
          <div className="preset-grid align-grid">
            {(['left', 'center', 'right'] as const).map((a) => (
              <button key={a} className={`preset-btn ${style.textAlign === a ? 'active' : ''}`} onClick={() => setPropStyle('textAlign', a)} title={a}>
                <i className={`fa fa-align-${a}`} />
              </button>
            ))}
          </div>
        </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: margin, padding, border, shadow, opacity */}
      <CollapsibleSection title="Spacing & Border" defaultOpen={false}>
        <SpacingControl
          label="Margin"
          value={{
            top: style.marginTop as string, right: style.marginRight as string,
            bottom: style.marginBottom as string, left: style.marginLeft as string,
          }}
          onChange={(side, v) => setPropStyle(`margin${capSide(side)}`, v)}
        />
        <SpacingControl
          label="Padding"
          value={{
            top: style.paddingTop as string, right: style.paddingRight as string,
            bottom: style.paddingBottom as string, left: style.paddingLeft as string,
          }}
          onChange={(side, v) => setPropStyle(`padding${capSide(side)}`, v)}
        />
        <BorderControl
          value={parseBorderShorthand(style.border as string)}
          onChange={(v) => setPropStyle('border', buildBorderShorthand(v))}
        />
        <div className="guided-section">
          <SectionLabel>Shadow</SectionLabel>
          <PresetButtonGrid presets={SHADOW_PRESETS} activeValue={style.boxShadow as string} onSelect={(v) => setPropStyle('boxShadow', v)} />
        </div>
        <div className="guided-section">
          <SectionLabel>Opacity</SectionLabel>
          <input
            type="range"
            min={0}
            max={100}
            value={style.opacity !== undefined ? Math.round(Number(style.opacity) * 100) : 100}
            onChange={(e) => setPropStyle('opacity', String(Number(e.target.value) / 100))}
            style={{ width: '100%' }}
          />
        </div>
      </CollapsibleSection>

      {/* Entrance animation */}
      <CollapsibleSection title="Animation" defaultOpen={false}>
        <AnimationControl
          value={{ animation: nodeProps.animation || 'none', animationDelay: nodeProps.animationDelay || '0' }}
          onChange={(v) => { setProp('animation', v.animation); setProp('animationDelay', v.animationDelay); }}
        />
      </CollapsibleSection>

      {/* Responsive visibility */}
      <CollapsibleSection title="Visibility" defaultOpen={false}>
        <VisibilityControl
          value={{
            hideOnDesktop: !!nodeProps.hideOnDesktop,
            hideOnTablet: !!nodeProps.hideOnTablet,
            hideOnMobile: !!nodeProps.hideOnMobile,
          }}
          onChange={(v) => {
            setProp('hideOnDesktop', !!v.hideOnDesktop);
            setProp('hideOnTablet', !!v.hideOnTablet);
            setProp('hideOnMobile', !!v.hideOnMobile);
          }}
        />
      </CollapsibleSection>
    </>
  );
};
