import React, { CSSProperties } from 'react';
import {
  TEXT_COLORS,
  FONT_FAMILIES,
  TEXT_SIZES,
  FONT_WEIGHTS,
  LINE_HEIGHTS,
  LETTER_SPACINGS,
  SHADOW_PRESETS,
} from '../../../constants/presets';
import {
  StylePanelProps,
  SectionLabel,
  ColorSwatchGrid,
  PresetButtonGrid,
  NumericUnitInput,
  CollapsibleSection,
  SpacingControl,
  SpacingSide,
  BorderControl,
  BorderValue,
  buildBorderShorthand,
  AnimationControl,
  VisibilityControl,
  sectionGap,
  labelStyle,
  useNodeProp,
} from './shared';

/* Text-transform is a small fixed enum with no natural home in the shared
   foundation presets (constants/presets.ts is import-only for this
   package), so it lives here as a package-local preset list. */
const TEXT_TRANSFORMS: { label: string; value: string }[] = [
  { label: 'None', value: 'none' },
  { label: 'UPPER', value: 'uppercase' },
  { label: 'lower', value: 'lowercase' },
  { label: 'Capitalize', value: 'capitalize' },
];

function capitalize(s: string): string {
  return s.charAt(0).toUpperCase() + s.slice(1);
}

/** Parses a `border` shorthand string (e.g. "2px solid #ff0000") back into
 *  the {width,style,color} shape BorderControl edits. Only needs to
 *  round-trip values this same panel produced via buildBorderShorthand. */
function parseBorderShorthand(v: string | undefined): BorderValue {
  if (!v || v === 'none') return { width: '', style: 'none', color: '#000000' };
  const m = String(v).trim().match(/^(\d+(?:\.\d+)?(?:px|em|rem)?)\s+(\w+)\s+(.+)$/);
  if (!m) return { width: '', style: 'none', color: '#000000' };
  return { width: m[1], style: m[2], color: m[3] };
}

/** style.opacity is a CSS-length-free numeric string ("0.8") or blank
 *  (treated as fully opaque). Converts to a 0-100 integer for the UI. */
function opacityPercent(v: unknown): number {
  if (v === undefined || v === null || v === '') return 100;
  const n = parseFloat(String(v));
  return Number.isFinite(n) ? Math.round(n * 100) : 100;
}

/* ---------- TEXT ---------- */
export const TextStylePanel: React.FC<StylePanelProps> = ({ selectedId, nodeProps }) => {
  const style: CSSProperties = nodeProps.style || {};

  const { setProp, setPropStyle } = useNodeProp(selectedId);

  const isItalic = style.fontStyle === 'italic';
  const isUnderline = style.textDecoration === 'underline';

  return (
    <>
      <div className="guided-section">
        <SectionLabel>Text Color</SectionLabel>
        <ColorSwatchGrid
          colors={TEXT_COLORS}
          activeValue={style.color as string}
          onSelect={(v) => setPropStyle('color', v)}
        />
      </div>
      <div className="guided-section">
        <SectionLabel>Font Family</SectionLabel>
        <PresetButtonGrid
          presets={FONT_FAMILIES}
          activeValue={style.fontFamily as string}
          onSelect={(v) => setPropStyle('fontFamily', v)}
        />
      </div>
      <div className="guided-section">
        <SectionLabel>Text Size</SectionLabel>
        <PresetButtonGrid
          presets={TEXT_SIZES}
          activeValue={style.fontSize as string}
          onSelect={(v) => setPropStyle('fontSize', v)}
        />
        <div style={{ marginTop: 6 }}>
          <NumericUnitInput
            value={TEXT_SIZES.some((p) => p.value === style.fontSize) ? '' : ((style.fontSize as string) || '')}
            onChange={(v) => setPropStyle('fontSize', v)}
            units={['px', 'em', 'rem', '%']}
            placeholder="custom"
            testId="text-fontsize-custom"
          />
        </div>
      </div>
      <div className="guided-section">
        <SectionLabel>Font Weight</SectionLabel>
        <PresetButtonGrid
          presets={FONT_WEIGHTS}
          activeValue={String(style.fontWeight || '')}
          onSelect={(v) => setPropStyle('fontWeight', v)}
        />
      </div>
      <div className="guided-section">
        <SectionLabel>Style</SectionLabel>
        <div style={{ display: 'flex', gap: 6 }}>
          <button
            type="button"
            className={`preset-btn ${isItalic ? 'active' : ''}`}
            style={{ flex: 1, fontStyle: 'italic' }}
            onClick={() => setPropStyle('fontStyle', isItalic ? 'normal' : 'italic')}
            title="Italic"
          >
            <i className="fa fa-italic" /> Italic
          </button>
          <button
            type="button"
            className={`preset-btn ${isUnderline ? 'active' : ''}`}
            style={{ flex: 1, textDecoration: 'underline' }}
            onClick={() => setPropStyle('textDecoration', isUnderline ? 'none' : 'underline')}
            title="Underline"
          >
            <i className="fa fa-underline" /> Underline
          </button>
        </div>
      </div>
      <div className="guided-section">
        <SectionLabel>Text Transform</SectionLabel>
        <PresetButtonGrid
          presets={TEXT_TRANSFORMS}
          activeValue={(style.textTransform as string) || 'none'}
          onSelect={(v) => setPropStyle('textTransform', v === 'none' ? '' : v)}
        />
      </div>
      <div className="guided-section">
        <SectionLabel>Line Height</SectionLabel>
        <PresetButtonGrid
          presets={LINE_HEIGHTS}
          activeValue={String(style.lineHeight || '')}
          onSelect={(v) => setPropStyle('lineHeight', v)}
        />
      </div>
      <div className="guided-section">
        <SectionLabel>Letter Spacing</SectionLabel>
        <PresetButtonGrid
          presets={LETTER_SPACINGS}
          activeValue={String(style.letterSpacing || '')}
          onSelect={(v) => setPropStyle('letterSpacing', v)}
        />
      </div>
      <div className="guided-section">
        <SectionLabel>Alignment</SectionLabel>
        <div className="preset-grid align-grid">
          {(['left', 'center', 'right', 'justify'] 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>

      {/* Box model + border/effects + animation/visibility rollout */}
      <CollapsibleSection title="Spacing" 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: SpacingSide, v: string) => setPropStyle(`margin${capitalize(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: SpacingSide, v: string) => setPropStyle(`padding${capitalize(side)}`, v)}
        />
      </CollapsibleSection>
      <CollapsibleSection title="Border & Effects" defaultOpen={false}>
        <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 style={sectionGap}>
          <label style={labelStyle}>Opacity: {opacityPercent(style.opacity)}%</label>
          <input
            type="range"
            min={0}
            max={100}
            value={opacityPercent(style.opacity)}
            onChange={(e) => setPropStyle('opacity', String(Number(e.target.value) / 100))}
            style={{ width: '100%' }}
          />
        </div>
      </CollapsibleSection>
      <CollapsibleSection title="Animation & Visibility" defaultOpen={false}>
        <AnimationControl
          value={{ animation: nodeProps.animation || 'none', animationDelay: nodeProps.animationDelay }}
          onChange={(v) => { setProp('animation', v.animation); setProp('animationDelay', v.animationDelay); }}
        />
        <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>
    </>
  );
};
