import type { Widget } from './types';

// A widget is "inside" a container when its centre falls within the container's
// bounds. Containers are decorative frames that do not re-parent widgets, so
// membership is purely geometric.
export function centreInside(w: Widget, c: Widget): boolean {
  const cx = w.x + w.w / 2, cy = w.y + w.h / 2;
  return cx >= c.x && cx <= c.x + c.w && cy >= c.y && cy <= c.y + c.h;
}

// Expand a set of widget ids to also include every widget geometrically inside
// any container among them — transitively, so a moved container carries nested
// containers and their contents too. Used when starting a move (drag or arrow
// nudge) so dragging a container drags the widgets sitting on it. Membership is
// snapshotted by the caller at move start; widgets are never re-parented.
export function withContainedWidgets(ids: string[], widgets: Widget[]): string[] {
  const byId = new Map(widgets.map(w => [w.id, w]));
  const result = new Set(ids);
  let changed = true;
  while (changed) {
    changed = false;
    for (const id of [...result]) {
      const c = byId.get(id);
      if (!c || c.type !== 'container') continue;
      for (const w of widgets) {
        if (w.id !== c.id && !result.has(w.id) && centreInside(w, c)) {
          result.add(w.id);
          changed = true;
        }
      }
    }
  }
  return [...result];
}

// The tab index a widget is assigned to (option 'tab', default 0).
export function widgetTab(w: Widget): number {
  return parseInt(w.options['tab'] ?? '0', 10) || 0;
}

// Container panes operating in tabbed mode.
export function tabPanes(widgets: Widget[]): Widget[] {
  return widgets.filter(w => w.type === 'container' && w.options['variant'] === 'tabs');
}

// The tabbed container that geometrically contains this widget, if any.
export function containingTabPane(w: Widget, widgets: Widget[]): Widget | null {
  return tabPanes(widgets).find(c => c.id !== w.id && centreInside(w, c)) ?? null;
}

// Parse the comma-separated tab labels of a tabbed container (never empty).
export function tabLabels(c: Widget): string[] {
  const t = (c.options['tabs'] ?? 'Tab 1,Tab 2')
    .split(',').map(s => s.trim()).filter(s => s !== '');
  return t.length ? t : ['Tab 1'];
}
