import { useState, useId } from 'react';
import { SHIRT_COLORS, SHIRT_SIZES, formatUsd } from '../../constants/shirt';
import '../../styles/ShirtOptionsPanel.css';

/**
 * The first card in the right panel — controls that affect the *garment*,
 * not the design overlay: shirt color, size, and the live price.
 *
 * The shirt color drives the on-screen mockup only. The export endpoint
 * receives just the design overlay (no shirt body) since DTG / sublimation
 * production pipelines composite onto the chosen shirt downstream.
 *
 * Collapsed / expanded UX
 * ——————————————————————
 * The full color + size pickers consume meaningful vertical space at the
 * top of the right rail — space that, mid-edit, is more valuable for the
 * tools and layers panels below. We default to a compact summary that
 * shows the current color (small swatch + label), the current size, and
 * the price, with an expand affordance for when the user actually wants
 * to change shirt options. After expanding, the panel stays open until
 * the user collapses it again — we don't auto-collapse on selection,
 * which would punish users who want to compare a few options.
 *
 * The collapse state is component-local and resets on reload — each
 * fresh session of the editor starts collapsed since the user almost
 * always cares about the design first and the garment second.
 */
export function ShirtOptionsPanel({
  selectedColorId,
  onColorChange,
  selectedSize,
  onSizeChange,
  price,
}) {
  const [expanded, setExpanded] = useState(false);
  // Stable id for aria-controls / id pairing. useId is preferable over a
  // hardcoded string because if this component is ever rendered twice in
  // the same view (e.g. mobile bottom sheet + desktop sidebar mirroring),
  // each instance needs a distinct id.
  const contentId = useId();

  const selectedColor = SHIRT_COLORS.find((c) => c.id === selectedColorId) ?? SHIRT_COLORS[0];

  return (
    <section className={`shirt-options${expanded ? ' is-expanded' : ' is-collapsed'}`} aria-labelledby="shirt-options-heading">
      {/* The header is the toggle target. Wrapping it in a <button> means
          the entire row is clickable and keyboard-focusable. The price and
          summary chips inside the button are visual content; the button's
          aria-label carries the full state for screen readers. */}
      <button
        type="button"
        className="shirt-options__toggle"
        onClick={() => setExpanded((v) => !v)}
        aria-expanded={expanded}
        aria-controls={contentId}
        aria-label={`Shirt options. Currently ${selectedColor.label}, size ${selectedSize}, ${formatUsd(price)}. ${expanded ? 'Click to collapse.' : 'Click to change.'}`}
      >
        <header className="shirt-options__header">
          <h2 id="shirt-options-heading" className="shirt-options__title">
            <span className="shirt-options__title-icon" aria-hidden="true">👕</span>
            Shirt Options
            {/* Chevron renders in both expanded and collapsed states so
                users always see an affordance for the toggle. CSS
                rotates it 180° when the section is expanded — down
                arrow says "click to reveal", up arrow says "click to
                close". Sits immediately after the title so it reads as
                part of the disclosure widget rather than as a
                decoration on the price. */}
            <span className="shirt-options__chevron" aria-hidden="true">
              <svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
                <path d="M6 9l6 6 6-6" />
              </svg>
            </span>
          </h2>
          <div className="shirt-options__price" aria-hidden="true">
            {formatUsd(price)}
          </div>
        </header>

        {/* Compact summary chips — visible only when collapsed. Shows a
            mini swatch + the color label + the size, so the user can
            confirm the current selection at a glance without expanding. */}
        {!expanded && (
          <div className="shirt-options__summary" aria-hidden="true">
            <span
              className="shirt-options__summary-swatch"
              style={{
                '--swatch-color': selectedColor.hex,
                '--swatch-border': selectedColor.borderHint,
              }}
            />
            <span className="shirt-options__summary-text">
              {selectedColor.label} · Size {selectedSize}
            </span>
          </div>
        )}
      </button>

      {/* Expanded content. We always render the markup (rather than
          short-circuiting on `expanded`) so the CSS max-height transition
          has something to animate between. `aria-hidden` + visibility:hidden
          (in the CSS) on the collapsed state keep it out of the tab order
          and screen-reader tree when it's not visible. */}
      <div
        id={contentId}
        className="shirt-options__content"
        aria-hidden={!expanded}
      >
        <div className="shirt-options__row">
          <span className="shirt-options__label">Color</span>
          <div className="shirt-options__swatches" role="radiogroup" aria-label="Shirt color">
            {SHIRT_COLORS.map((c) => {
              const isSelected = c.id === selectedColorId;
              return (
                <button
                  key={c.id}
                  type="button"
                  role="radio"
                  aria-checked={isSelected}
                  aria-label={c.label}
                  className={`shirt-options__swatch${isSelected ? ' is-selected' : ''}`}
                  onClick={() => onColorChange?.(c.id)}
                  // The expanded controls are tabIndex=-1 when collapsed
                  // so keyboard users don't tab through invisible options.
                  tabIndex={expanded ? 0 : -1}
                  style={{
                    '--swatch-color': c.hex,
                    '--swatch-border': c.borderHint,
                  }}
                >
                  <span className="shirt-options__swatch-fill" />
                </button>
              );
            })}
          </div>
        </div>

        <div className="shirt-options__row">
          <span className="shirt-options__label">Size</span>
          <div className="shirt-options__sizes" role="radiogroup" aria-label="Shirt size">
            {SHIRT_SIZES.map((size) => {
              const isSelected = size === selectedSize;
              return (
                <button
                  key={size}
                  type="button"
                  role="radio"
                  aria-checked={isSelected}
                  className={`shirt-options__size${isSelected ? ' is-selected' : ''}`}
                  onClick={() => onSizeChange?.(size)}
                  tabIndex={expanded ? 0 : -1}
                >
                  {size}
                </button>
              );
            })}
          </div>
        </div>
      </div>
    </section>
  );
}
