import { useBackgroundRemoval } from '../../hooks/useBackgroundRemoval';

/**
 * "Remove background" control for the floating element toolbar.
 *
 * Lives under canvas/ rather than sidebar/ because it's rendered inside
 * ElementToolbar (a canvas-area component) and operates on the selected
 * canvas element.
 *
 * Render variants
 * ───────────────
 *   • compact (default) — renders as a `.el-toolbar__btn`-shaped button
 *     that fits alongside Flip H, Flip V, and Crop in the toolbar's
 *     action row. Vertical layout: icon glyph on top, small label
 *     below (label hidden on mobile via the same media query as the
 *     other action buttons). While the model is loading or the
 *     background is being removed, the button shows a spinner glyph
 *     and is disabled.
 *   • full — the original wide pill-shaped button. Currently unused
 *     by callers but kept around in case a future surface (e.g. a
 *     dedicated photo-actions panel) wants the more prominent
 *     treatment. Pass `variant="full"` to opt in.
 *
 * Why one component with a variant prop and not two
 * ─────────────────────────────────────────────────
 * The hook plumbing (useBackgroundRemoval) and the post-removal
 * geometry math (mapping the alpha bbox from source pixel space back
 * into canvas units, accounting for rotation) is the same regardless
 * of how the button is rendered. Splitting into two components would
 * mean duplicating that logic or extracting it into a hook anyway;
 * one component with a presentational switch keeps things compact.
 */
export function BackgroundRemovalButton({
  selectedElement,
  onUpdate,
  variant = 'compact',
}) {
  const { loading, progress, removeBackground } = useBackgroundRemoval();

  const handleRemoveBackground = async () => {
    if (!selectedElement || selectedElement.type !== 'image') return;
    // removeBackground handles model loading internally if needed.
    const result = await removeBackground(selectedElement.src);
    if (!result) return;

    const { url, bbox } = result;

    // Defensive bail — a zero-area bbox would produce NaN aspect
    // below. removeBackground shouldn't return one in practice (an
    // empty mask means everything was transparent already), but if it
    // does we skip the update rather than landing garbage geometry in
    // state.
    if (bbox.sw <= 0 || bbox.sh <= 0) return;

    // Scale the bg-removed subject to occupy the ORIGINAL element's
    // on-canvas bounding box, preserving the subject's aspect ratio
    // (letterboxing along whichever axis is needed). Previously we
    // tightened the bbox to wrap just the subject pixels, which made
    // the element visually shrink after bg removal — a 200×100 photo
    // of a pet on a busy background would collapse to a 60×40 pet,
    // forcing the user to manually resize it back up if they wanted
    // the subject at the same scale.
    //
    // Letterbox-fit logic is the same shape as `handleResetCrop`'s
    // "resized" branch in App.jsx:
    //
    //   subjectAspect > originalAspect : subject is relatively
    //     wider → fill the box's WIDTH, let the height shrink to
    //     match the subject's aspect.
    //
    //   subjectAspect ≤ originalAspect : subject is relatively
    //     taller (or square) → fill HEIGHT, let width shrink.
    //
    // The new (smaller-on-at-least-one-axis) bbox is then centered
    // inside the original bbox so the subject sits where the user
    // last saw it, not anchored to a corner.
    const oldW = selectedElement.width || 100;
    const oldH = selectedElement.height || 100;
    const subjectAspect = bbox.sw / bbox.sh;
    const originalAspect = oldW / oldH;

    let newW;
    let newH;
    if (subjectAspect > originalAspect) {
      newW = oldW;
      newH = oldW / subjectAspect;
    } else {
      newH = oldH;
      newW = oldH * subjectAspect;
    }

    // Center the new bbox inside the original. Konva rotates around
    // the element's (x, y) origin, not its visual center, so we
    // compute the centered offset in LOCAL (unrotated) coords first,
    // then rotate it into canvas coords to find the new top-left.
    // This preserves the visual center of the element through the bg
    // removal even when the element was rotated beforehand. Flip is
    // not specially handled; centering means the subject lands in
    // the same spot regardless of flip state.
    const rad = ((selectedElement.rotation || 0) * Math.PI) / 180;
    const cos = Math.cos(rad);
    const sin = Math.sin(rad);
    const localOffsetX = (oldW - newW) / 2;
    const localOffsetY = (oldH - newH) / 2;
    const newX = (selectedElement.x || 0) + localOffsetX * cos - localOffsetY * sin;
    const newY = (selectedElement.y || 0) + localOffsetX * sin + localOffsetY * cos;

    onUpdate(selectedElement.id, {
      src: url,
      x: newX,
      y: newY,
      width: newW,
      height: newH,
      // The bg-removed result is already cropped to its visible region,
      // so any prior `crop` (e.g. from a slot template) no longer maps.
      crop: undefined,
      // Pre/post-crop tracking from in-app crops also no longer applies
      // — the image source has changed, so those dimensions reference
      // an image that's gone. Clearing here mirrors the cleanup in
      // `handlePhotoEditComplete` over in App.jsx.
      preCrop: undefined,
      postCrop: undefined,
      bgRemoved: true,
    });
  };

  if (!selectedElement || selectedElement.type !== 'image') return null;

  // Compact: matches `.el-toolbar__btn` so it sits cleanly next to
  // Flip H / Flip V / Crop in the action row. SVG glyph is a small
  // "magic wand" — same metaphor as the original ✨ emoji but
  // rendered as a proper icon so it inherits currentColor for
  // hover/active states. While loading, the button shows a spinner
  // and disables itself; progress (0-100) is included in the
  // tooltip / aria-label so screen-reader users get a status read.
  if (variant === 'compact') {
    const label = loading
      ? (progress > 0 ? `Removing background (${progress}%)` : 'Removing background\u2026')
      : 'Remove background';
    return (
      <button
        type="button"
        onClick={handleRemoveBackground}
        disabled={loading}
        className={`el-toolbar__btn${loading ? ' el-toolbar__btn--busy' : ''}`}
        aria-label={label}
        title={label}
      >
        {loading ? (
          <span className="el-toolbar__spinner" aria-hidden="true" />
        ) : (
          <svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
            {/* Magic wand + sparkles — read as "make the background go
                away" without committing to any one literal "background"
                glyph. Matches the previous ✨ emoji metaphor. */}
            <path d="M15 4V2" />
            <path d="M15 16v-2" />
            <path d="M8 9h2" />
            <path d="M20 9h2" />
            <path d="M17.8 11.8L19 13" />
            <path d="M15 9h.01" />
            <path d="M17.8 6.2L19 5" />
            <path d="M3 21l9-9" />
            <path d="M12.2 6.2L11 5" />
          </svg>
        )}
        <span className="el-toolbar__btn-label">{loading ? 'Working\u2026' : 'Remove BG'}</span>
      </button>
    );
  }

  // Full (legacy) — wide pill button. Kept for completeness; no
  // current caller uses it. Same logic, different chrome.
  return (
    <div className="bg-removal-container">
      <button className="bg-removal-btn" onClick={handleRemoveBackground} disabled={loading}>
        {loading ? (
          <>
            <div className="spinner-small" />
            {progress > 0 ? `Loading: ${progress}%` : 'Removing Background...'}
          </>
        ) : (
          <>✨ Remove Background</>
        )}
      </button>
    </div>
  );
}
