import type { WindowFrame } from '../../../components/window';
import type { PlanFilterStatus } from '../../../features/planBoard';

const WINDOW_LAYOUT_GAP = 18;
const MIN_WINDOW_WIDTH = 360;
const MIN_WINDOW_HEIGHT = 220;

export type WindowStageSize = {
  width: number;
  height: number;
};

export type WindowLayoutSelection = {
  instanceId: string;
};

export const HIDDEN_COMPONENT_IDS = ['search-command-modal', 'window-ui'];

export function getPlanStatusFromWindowSelection(selectionId: string): PlanFilterStatus | null {
  if (selectionId === 'page:plans:all') {
    return 'all';
  }

  if (selectionId === 'plan-status:in-progress') {
    return 'in-progress';
  }

  if (selectionId === 'plan-status:error') {
    return 'error';
  }

  if (selectionId === 'plan-status:done') {
    return 'done';
  }

  return null;
}

export function getDefaultWindowFrame(selectionId: string, index: number): WindowFrame {
  const isComponentSelection = selectionId.startsWith('component:');
  const isWidgetSelection = selectionId.startsWith('widget:');
  const isSampleSelection = isComponentSelection || isWidgetSelection;

  if (selectionId === 'page:preview:app') {
    return {
      x: 16,
      y: 16,
      width: 1240,
      height: 820,
    };
  }

  // Page windows need enough room for nested layouts, while sample windows start compact.
  if (selectionId.startsWith('page:')) {
    return {
      x: 20 + (index % 4) * 24,
      y: 16 + (index % 4) * 24,
      width: 960,
      height: 720,
    };
  }

  if (isWidgetSelection) {
    return {
      x: 0,
      y: 0,
      width: 100000,
      height: 100000,
    };
  }

  if (isSampleSelection) {
    return {
      x: 48 + (index % 5) * 24,
      y: 36 + (index % 5) * 24,
      width: 480,
      height: 360,
    };
  }

  return {
    x: 36 + (index % 5) * 28,
    y: 24 + (index % 5) * 28,
    width: 720,
    height: 520,
  };
}

export function buildCascadeWindowFrames(
  selections: WindowLayoutSelection[],
  stageSize: WindowStageSize,
): Record<string, WindowFrame> {
  // Keep the first window prominent and offset the rest without pushing them outside the stage.
  return Object.fromEntries(
    selections.map((selection, index) => {
      const width = Math.min(stageSize.width - 64, index === 0 ? 920 : 680);
      const height = Math.min(stageSize.height - 64, index === 0 ? 680 : 460);
      const x = Math.min(28 + (index % 6) * 36, Math.max(0, stageSize.width - width));
      const y = Math.min(24 + (index % 6) * 32, Math.max(0, stageSize.height - height));

      return [
        selection.instanceId,
        {
          x,
          y,
          width: Math.max(MIN_WINDOW_WIDTH, width),
          height: Math.max(MIN_WINDOW_HEIGHT, height),
        },
      ];
    }),
  );
}

export function buildGridWindowFrames(
  selections: WindowLayoutSelection[],
  stageSize: WindowStageSize,
): Record<string, WindowFrame> {
  if (selections.length === 0) {
    return {};
  }

  // Square-ish grids preserve usable window sizes across mixed page and sample selections.
  const count = selections.length;
  const columns = Math.max(1, Math.ceil(Math.sqrt(count)));
  const rows = Math.max(1, Math.ceil(count / columns));
  const cellWidth = (stageSize.width - WINDOW_LAYOUT_GAP * (columns + 1)) / columns;
  const cellHeight = (stageSize.height - WINDOW_LAYOUT_GAP * (rows + 1)) / rows;

  return Object.fromEntries(
    selections.map((selection, index) => {
      const column = index % columns;
      const row = Math.floor(index / columns);

      return [
        selection.instanceId,
        {
          x: Math.max(0, WINDOW_LAYOUT_GAP + column * (cellWidth + WINDOW_LAYOUT_GAP)),
          y: Math.max(0, WINDOW_LAYOUT_GAP + row * (cellHeight + WINDOW_LAYOUT_GAP)),
          width: Math.max(MIN_WINDOW_WIDTH, cellWidth),
          height: Math.max(MIN_WINDOW_HEIGHT, cellHeight),
        },
      ];
    }),
  );
}
