export const WORKBENCH_LAYOUT = {
  headerHeight: 56,
  desktopMinWidth: 1024,
  persistentConditionMinWidth: 1280,
  wideMinWidth: 1536,
  collapsedAgentWidth: 72,
  maxAgentWidth: 720,
  agentPanelLeftInset: 12,
  conditionPanelRightInset: 64,
  minimumAgentMapCorridor: 256,
  mapEdgeGap: 24,
  desktop: {
    agentWidth: 500,
    conditionWidth: 432,
    conditionExpandedWidth: 880,
    toolbarWidth: 48,
    tickerWidth: 420
  },
  wide: {
    agentWidth: 540,
    conditionWidth: 432,
    conditionExpandedWidth: 960,
    toolbarWidth: 48,
    tickerWidth: 460
  },
  mobileSheet: {
    halfViewportRatio: 0.52,
    fullTopGap: 68
  }
} as const;

export function clampAgentPanelWidth(
  width: number,
  viewportWidth: number,
  conditionExpanded = false
) {
  const minWidth = getAgentPanelDefaultWidth(viewportWidth, conditionExpanded);

  return Math.round(
    Math.min(Math.max(width, minWidth), getAgentPanelMaxWidth(viewportWidth, conditionExpanded))
  );
}

export function getAgentPanelDefaultWidth(viewportWidth: number, conditionExpanded = false) {
  const layout = getWorkbenchViewportLayout(viewportWidth);
  if (viewportWidth < WORKBENCH_LAYOUT.desktopMinWidth) {
    return layout.agentWidth;
  }

  const conditionWidth = conditionExpanded ? layout.conditionExpandedWidth : layout.conditionWidth;
  const collisionSafeWidth =
    viewportWidth -
    WORKBENCH_LAYOUT.agentPanelLeftInset -
    WORKBENCH_LAYOUT.mapEdgeGap -
    conditionWidth -
    WORKBENCH_LAYOUT.mapEdgeGap -
    layout.toolbarWidth;

  return Math.min(layout.agentWidth, collisionSafeWidth);
}

export function getAgentPanelMaxWidth(viewportWidth: number, conditionExpanded = false) {
  const layout = getWorkbenchViewportLayout(viewportWidth);
  const conditionWidth = conditionExpanded ? layout.conditionExpandedWidth : layout.conditionWidth;
  const defaultWidth = getAgentPanelDefaultWidth(viewportWidth, conditionExpanded);
  const widthWithMapCorridor =
    viewportWidth -
    WORKBENCH_LAYOUT.agentPanelLeftInset -
    WORKBENCH_LAYOUT.conditionPanelRightInset -
    conditionWidth -
    WORKBENCH_LAYOUT.minimumAgentMapCorridor;

  return Math.max(defaultWidth, Math.min(WORKBENCH_LAYOUT.maxAgentWidth, widthWithMapCorridor));
}

export type WorkbenchPanelState = {
  agentOpen: boolean;
  agentWidth?: number;
  conditionOpen: boolean;
  conditionExpanded?: boolean;
};

export type WorkbenchBasemapTone = "light" | "satellite" | "none";

export type WorkbenchViewportLayout = {
  agentWidth: number;
  conditionWidth: number;
  conditionExpandedWidth: number;
  toolbarWidth: number;
  tickerWidth: number;
};

export function getWorkbenchViewportLayout(viewportWidth: number): WorkbenchViewportLayout {
  return viewportWidth >= WORKBENCH_LAYOUT.wideMinWidth
    ? WORKBENCH_LAYOUT.wide
    : WORKBENCH_LAYOUT.desktop;
}

export function getWorkbenchBasemapTone(activeBaseLayerId: string): WorkbenchBasemapTone {
  if (activeBaseLayerId === "mapbox-light") {
    return "light";
  }

  if (activeBaseLayerId === "mapbox-satellite") {
    return "satellite";
  }

  return "none";
}

export function getWorkbenchCameraPadding(viewportWidth: number, panels: WorkbenchPanelState) {
  if (viewportWidth < WORKBENCH_LAYOUT.desktopMinWidth) {
    return { top: 72, right: 24, bottom: 72, left: 24 };
  }

  const layout = getWorkbenchViewportLayout(viewportWidth);
  const agentWidth = panels.agentOpen
    ? panels.agentWidth === undefined
      ? getAgentPanelDefaultWidth(
          viewportWidth,
          panels.conditionOpen && Boolean(panels.conditionExpanded)
        )
      : clampAgentPanelWidth(
          panels.agentWidth,
          viewportWidth,
          panels.conditionOpen && Boolean(panels.conditionExpanded)
        )
    : WORKBENCH_LAYOUT.collapsedAgentWidth;
  const conditionWidth = panels.conditionOpen
    ? panels.conditionExpanded
      ? layout.conditionExpandedWidth
      : layout.conditionWidth
    : 0;

  return {
    top: WORKBENCH_LAYOUT.headerHeight + 16,
    right: WORKBENCH_LAYOUT.mapEdgeGap + layout.toolbarWidth + conditionWidth,
    bottom: 32,
    left: WORKBENCH_LAYOUT.mapEdgeGap + agentWidth
  };
}

export function getWorkbenchLayoutCssVariables() {
  return {
    "--workbench-agent-width": `${WORKBENCH_LAYOUT.desktop.agentWidth}px`,
    "--workbench-agent-width-wide": `${WORKBENCH_LAYOUT.wide.agentWidth}px`,
    "--workbench-condition-width": `${WORKBENCH_LAYOUT.desktop.conditionWidth}px`,
    "--workbench-condition-width-wide": `${WORKBENCH_LAYOUT.wide.conditionWidth}px`,
    "--workbench-condition-expanded-width": `${WORKBENCH_LAYOUT.desktop.conditionExpandedWidth}px`,
    "--workbench-condition-expanded-width-wide": `${WORKBENCH_LAYOUT.wide.conditionExpandedWidth}px`,
    "--workbench-toolbar-width": `${WORKBENCH_LAYOUT.desktop.toolbarWidth}px`,
    "--workbench-ticker-width": `${WORKBENCH_LAYOUT.desktop.tickerWidth}px`,
    "--workbench-ticker-width-wide": `${WORKBENCH_LAYOUT.wide.tickerWidth}px`
  } as const;
}
