import React from 'react';
import { SHADOW_PRESETS } from '../../../constants/presets';
import {
  SectionLabel,
  PresetButtonGrid,
  CollapsibleSection,
  SpacingControl,
  SpacingSide,
  BorderControl,
  BorderValue,
  buildBorderShorthand,
  AnimationControl,
  VisibilityControl,
  sectionGap,
  labelStyle,
} from './shared';

/* ==========================================================================
   Shared box-model / border+effects / animation+visibility sections for the
   CONTAINERS package's single shared panel (ContainerStylePanel, used for
   Container / Section / Columns). Kept local to this package (not in
   shared.tsx, which is foundation/import-only) since it's just DRY-ing the
   identical JSX block across those 3 components rather than a genuinely
   cross-package reusable control. Mirrors the equivalent helper in the
   media package (mediaBoxModel.tsx) -- same shape, independently duplicated
   per-package by design (packages are developed and merged in parallel).
   ========================================================================== */

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 --
 *  not arbitrary author-supplied CSS. */
export 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] };
}

export interface BoxModelSectionProps {
  style: Record<string, any>;
  setPropStyle: (prop: string, value: string) => void;
}

/** Margin + Padding, per-side, via the shared SpacingControl. */
export const BoxModelSection: React.FC<BoxModelSectionProps> = ({ style, setPropStyle }) => {
  const sideSetter = (kind: 'margin' | 'padding') => (side: SpacingSide, value: string) =>
    setPropStyle(`${kind}${capitalize(side)}`, value);

  return (
    <CollapsibleSection title="Spacing" defaultOpen={false}>
      <SpacingControl
        label="Margin"
        value={{ top: style.marginTop, right: style.marginRight, bottom: style.marginBottom, left: style.marginLeft }}
        onChange={sideSetter('margin')}
      />
      <SpacingControl
        label="Padding"
        value={{ top: style.paddingTop, right: style.paddingRight, bottom: style.paddingBottom, left: style.paddingLeft }}
        onChange={sideSetter('padding')}
      />
    </CollapsibleSection>
  );
};

/** style.opacity is stored as a CSS-length-free numeric string ("0.8") or
 *  may be blank/undefined (treated as fully opaque). Converts to a 0-100
 *  integer for the range input / label. */
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;
}

export interface BorderEffectsSectionProps {
  style: Record<string, any>;
  setPropStyle: (prop: string, value: string) => void;
}

/** Border (width/style/color) + box-shadow preset + opacity slider. */
export const BorderEffectsSection: React.FC<BorderEffectsSectionProps> = ({ style, setPropStyle }) => (
  <CollapsibleSection title="Border & Effects" defaultOpen={false}>
    <BorderControl
      value={parseBorderShorthand(style.border)}
      onChange={(v) => setPropStyle('border', buildBorderShorthand(v))}
    />
    <div className="guided-section">
      <SectionLabel>Shadow</SectionLabel>
      <PresetButtonGrid presets={SHADOW_PRESETS} activeValue={style.boxShadow} 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>
);

export interface AnimVisSectionProps {
  nodeProps: Record<string, any>;
  setProp: (key: string, value: any) => void;
}

/** Entrance animation + responsive hide toggles -- top-level props consumed
 *  directly by html-export.ts's buildDataAttrs (no toHtml change needed). */
export const AnimVisSection: React.FC<AnimVisSectionProps> = ({ nodeProps, setProp }) => (
  <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>
);
