/**
 * AlignmentBar — spatial alignment and distribution tools.
 *
 * Appears when 1+ objects are selected.
 * Provides align (left/center/right/top/middle/bottom),
 * distribute (horizontal/vertical, 2+ selected),
 * and center-on-artboard.
 */

import { useCallback, useMemo } from 'react';
import type { ArtboardConfig, CanvasObject } from '../../types/canvas';
import type { BoundingRect, PositionUpdate } from '../../utils/alignment';
import {
  alignLeft,
  alignCenter,
  alignRight,
  alignTop,
  alignMiddle,
  alignBottom,
  distributeHorizontal,
  distributeVertical,
  centerOnArtboard,
} from '../../utils/alignment';
import { toPx } from '../../utils/artboardShapes';

// -- Helpers ------------------------------------------------------------------

function toBoundingRect(obj: CanvasObject): BoundingRect {
  let w: number, h: number;
  switch (obj.type) {
    case 'rect':
    case 'image':
      w = obj.width;
      h = obj.height;
      break;
    case 'circle':
      w = obj.radius * 2;
      h = obj.radius * 2;
      break;
    case 'ellipse':
      w = obj.radiusX * 2;
      h = obj.radiusY * 2;
      break;
    case 'line': {
      const xs = obj.points.filter((_, i) => i % 2 === 0);
      const ys = obj.points.filter((_, i) => i % 2 === 1);
      w = Math.max(...xs) - Math.min(...xs);
      h = Math.max(...ys) - Math.min(...ys);
      break;
    }
    case 'text':
      w = obj.width;
      h = obj.fontSize * obj.lineHeight;
      break;
  }
  return { id: obj.id, x: obj.x, y: obj.y, width: w, height: h };
}

// -- Props --------------------------------------------------------------------

export interface AlignmentBarProps {
  objects: CanvasObject[];
  selectedIds: string[];
  artboard: ArtboardConfig | null;
  onUpdateObject: (id: string, changes: Partial<CanvasObject>) => void;
}

// -- Component ----------------------------------------------------------------

export default function AlignmentBar({
  objects,
  selectedIds,
  artboard,
  onUpdateObject,
}: AlignmentBarProps) {
  const selectedObjects = useMemo(
    () => objects.filter((o) => selectedIds.includes(o.id)),
    [objects, selectedIds],
  );

  const applyUpdates = useCallback(
    (updates: PositionUpdate[]) => {
      for (const u of updates) {
        onUpdateObject(u.id, { x: u.x, y: u.y });
      }
    },
    [onUpdateObject],
  );

  const rects = useMemo(
    () => selectedObjects.map(toBoundingRect),
    [selectedObjects],
  );

  if (selectedIds.length === 0) return null;

  const hasMultiple = selectedIds.length >= 2;

  return (
    <div className="alignment-bar" data-testid="alignment-bar">
      {/* Alignment buttons */}
      <div className="alignment-bar-group" data-testid="align-group">
        <button
          type="button"
          className="alignment-btn"
          onClick={() => applyUpdates(alignLeft(rects))}
          title="Align left"
          aria-label="Align left"
        >
          ⬱
        </button>
        <button
          type="button"
          className="alignment-btn"
          onClick={() => applyUpdates(alignCenter(rects))}
          title="Align center"
          aria-label="Align center horizontally"
        >
          ⬌
        </button>
        <button
          type="button"
          className="alignment-btn"
          onClick={() => applyUpdates(alignRight(rects))}
          title="Align right"
          aria-label="Align right"
        >
          ⬲
        </button>
        <button
          type="button"
          className="alignment-btn"
          onClick={() => applyUpdates(alignTop(rects))}
          title="Align top"
          aria-label="Align top"
        >
          ⬑
        </button>
        <button
          type="button"
          className="alignment-btn"
          onClick={() => applyUpdates(alignMiddle(rects))}
          title="Align middle"
          aria-label="Align middle vertically"
        >
          ⬍
        </button>
        <button
          type="button"
          className="alignment-btn"
          onClick={() => applyUpdates(alignBottom(rects))}
          title="Align bottom"
          aria-label="Align bottom"
        >
          ⬐
        </button>
      </div>

      {/* Distribute buttons (only when 2+ selected) */}
      {hasMultiple && (
        <div className="alignment-bar-group" data-testid="distribute-group">
          <button
            type="button"
            className="alignment-btn"
            onClick={() => applyUpdates(distributeHorizontal(rects))}
            title="Distribute horizontally"
            aria-label="Distribute horizontally"
          >
            ⟺
          </button>
          <button
            type="button"
            className="alignment-btn"
            onClick={() => applyUpdates(distributeVertical(rects))}
            title="Distribute vertically"
            aria-label="Distribute vertically"
          >
            ⟷
          </button>
        </div>
      )}

      {/* Center on artboard */}
      {artboard && (
        <div className="alignment-bar-group" data-testid="center-group">
          <button
            type="button"
            className="alignment-btn"
            onClick={() => {
              const artW = toPx(artboard.width, artboard.unit);
              const artH = toPx(artboard.height, artboard.unit);
              applyUpdates(centerOnArtboard(rects, artW, artH));
            }}
            title="Center on artboard"
            aria-label="Center on artboard"
          >
            ⊹
          </button>
        </div>
      )}
    </div>
  );
}
