import type { OverlayType } from '../types/layout';

export type AsukaResponsiveBreakpoint = 'mobile' | 'tablet' | 'desktop';
export type AsukaResponsivePreset = 'auto' | 'off' | 'compact' | 'mobile-first';
export type AsukaResponsiveMobileOverlayMode = 'fullscreen' | 'modal' | 'drawer' | 'preserve';
export type AsukaResponsiveTabletPanelMode = 'drawer' | 'modal' | 'preserve';
export type AsukaResponsiveBottomNavZone = 'left' | 'right';

export interface AsukaResponsiveConfig {
  /** Enable responsive layout adaptations. Defaults to true. */
  enabled?: boolean;
  /** Convenience preset. `off` disables all adaptations. */
  preset?: AsukaResponsivePreset;
  /** Max shell width considered mobile. Defaults to 640px. */
  mobileMaxWidth?: number;
  /** Max shell width considered tablet. Defaults to 960px. */
  tabletMaxWidth?: number;
  /** Number of left/right items shown directly in mobile bottom navigation. Defaults to 5. */
  maxVisibleMobileItems?: number;
  /** Move left/right zones into the mobile bottom navigation. Defaults to true. */
  moveSideZonesToBottomNav?: boolean;
  /** Convert small overlays to fullscreen modals on mobile. Defaults to false. */
  fullscreenOverlaysOnMobile?: boolean;
  /** Render side zones as compact rails and open their modules as drawers on tablet. Defaults to true. */
  drawerPanelsOnTablet?: boolean;
  /** Add safe-area padding to mobile navigation and fullscreen overlays. Defaults to true. */
  safeArea?: boolean;
  /** Responsive behavior for non-inline overlays on mobile. Defaults to `preserve`. */
  mobileOverlayMode?: AsukaResponsiveMobileOverlayMode;
  /** Responsive behavior for non-inline side-zone overlays on tablet. Defaults to `drawer`. */
  tabletPanelMode?: AsukaResponsiveTabletPanelMode;
  /** Side zones moved into the mobile bottom navigation. Defaults to `['left', 'right']`. */
  bottomNavZones?: AsukaResponsiveBottomNavZone[];
}

export interface NormalizedAsukaResponsiveConfig {
  enabled: boolean;
  preset: AsukaResponsivePreset;
  mobileMaxWidth: number;
  tabletMaxWidth: number;
  maxVisibleMobileItems: number;
  moveSideZonesToBottomNav: boolean;
  fullscreenOverlaysOnMobile: boolean;
  drawerPanelsOnTablet: boolean;
  safeArea: boolean;
  mobileOverlayMode: AsukaResponsiveMobileOverlayMode;
  tabletPanelMode: AsukaResponsiveTabletPanelMode;
  bottomNavZones: AsukaResponsiveBottomNavZone[];
}

export const DEFAULT_RESPONSIVE_CONFIG: NormalizedAsukaResponsiveConfig = {
  enabled: true,
  preset: 'auto',
  mobileMaxWidth: 640,
  tabletMaxWidth: 960,
  maxVisibleMobileItems: 5,
  moveSideZonesToBottomNav: true,
  fullscreenOverlaysOnMobile: false,
  drawerPanelsOnTablet: true,
  safeArea: true,
  mobileOverlayMode: 'preserve',
  tabletPanelMode: 'drawer',
  bottomNavZones: ['left', 'right'],
};

const toFiniteNumber = (value: unknown, fallback: number, min = 1): number => {
  const n = Number(value);
  if (!Number.isFinite(n)) return fallback;
  return Math.max(min, Math.floor(n));
};

const normalizeMobileOverlayMode = (value: unknown): AsukaResponsiveMobileOverlayMode =>
  value === 'modal' || value === 'drawer' || value === 'preserve' || value === 'fullscreen'
    ? value
    : DEFAULT_RESPONSIVE_CONFIG.mobileOverlayMode;

const normalizeTabletPanelMode = (value: unknown): AsukaResponsiveTabletPanelMode =>
  value === 'modal' || value === 'preserve' || value === 'drawer'
    ? value
    : DEFAULT_RESPONSIVE_CONFIG.tabletPanelMode;

const normalizeBottomNavZones = (value: unknown): AsukaResponsiveBottomNavZone[] => {
  if (!Array.isArray(value)) return [...DEFAULT_RESPONSIVE_CONFIG.bottomNavZones];
  const zones = value.filter((zone): zone is AsukaResponsiveBottomNavZone => zone === 'left' || zone === 'right');
  return zones.length > 0 ? Array.from(new Set(zones)) : [...DEFAULT_RESPONSIVE_CONFIG.bottomNavZones];
};

export function normalizeResponsiveConfig(input?: AsukaResponsiveConfig | null): NormalizedAsukaResponsiveConfig {
  const raw = (input && typeof input === 'object' ? input : {}) as AsukaResponsiveConfig;
  const preset = (raw.preset === 'off' || raw.preset === 'compact' || raw.preset === 'mobile-first' || raw.preset === 'auto')
    ? raw.preset
    : DEFAULT_RESPONSIVE_CONFIG.preset;

  const mobilePreset = preset === 'mobile-first';
  const compactPreset = preset === 'compact';

  const mobileMaxWidth = toFiniteNumber(raw.mobileMaxWidth, mobilePreset ? 768 : DEFAULT_RESPONSIVE_CONFIG.mobileMaxWidth, 240);
  const tabletMaxWidth = Math.max(
    mobileMaxWidth,
    toFiniteNumber(raw.tabletMaxWidth, mobilePreset ? 1100 : DEFAULT_RESPONSIVE_CONFIG.tabletMaxWidth, mobileMaxWidth),
  );

  const hasExplicitMobileOverlayMode = raw.mobileOverlayMode === 'modal' ||
    raw.mobileOverlayMode === 'drawer' ||
    raw.mobileOverlayMode === 'preserve' ||
    raw.mobileOverlayMode === 'fullscreen';
  const mobileOverlayMode = hasExplicitMobileOverlayMode
    ? normalizeMobileOverlayMode(raw.mobileOverlayMode)
    : raw.fullscreenOverlaysOnMobile === true
      ? 'fullscreen'
      : DEFAULT_RESPONSIVE_CONFIG.mobileOverlayMode;

  return {
    enabled: preset === 'off' ? false : raw.enabled !== false,
    preset,
    mobileMaxWidth,
    tabletMaxWidth,
    maxVisibleMobileItems: toFiniteNumber(raw.maxVisibleMobileItems, compactPreset ? 4 : DEFAULT_RESPONSIVE_CONFIG.maxVisibleMobileItems, 1),
    moveSideZonesToBottomNav: raw.moveSideZonesToBottomNav !== false,
    fullscreenOverlaysOnMobile: raw.fullscreenOverlaysOnMobile === true || mobileOverlayMode !== 'preserve',
    drawerPanelsOnTablet: raw.drawerPanelsOnTablet !== false,
    safeArea: raw.safeArea !== false,
    mobileOverlayMode,
    tabletPanelMode: normalizeTabletPanelMode(raw.tabletPanelMode),
    bottomNavZones: normalizeBottomNavZones(raw.bottomNavZones),
  };
}

export function getResponsiveBreakpoint(width: number, config: NormalizedAsukaResponsiveConfig): AsukaResponsiveBreakpoint {
  if (!config.enabled) return 'desktop';
  const w = Number.isFinite(Number(width)) ? Number(width) : Number.POSITIVE_INFINITY;
  if (w <= config.mobileMaxWidth) return 'mobile';
  if (w <= config.tabletMaxWidth) return 'tablet';
  return 'desktop';
}

export function transformOverlayTypeForBreakpoint(
  type: OverlayType,
  breakpoint: AsukaResponsiveBreakpoint,
  config: NormalizedAsukaResponsiveConfig | AsukaResponsiveConfig | null | undefined,
): OverlayType {
  const normalized = normalizeResponsiveConfig(config as any);
  if (!normalized.enabled || type === 'inline') return type;

  if (breakpoint === 'mobile' && normalized.fullscreenOverlaysOnMobile) {
    if (normalized.mobileOverlayMode === 'preserve') return type;
    if (
      type === 'floating' ||
      type === 'popover' ||
      type === 'drawer' ||
      type === 'panel-left' ||
      type === 'panel-right' ||
      type === 'panel-top' ||
      type === 'panel-bottom'
    ) {
      return normalized.mobileOverlayMode === 'drawer' ? 'drawer' : 'modal';
    }
    if (type === 'modal') return 'modal';
  }

  if (breakpoint === 'tablet' && normalized.drawerPanelsOnTablet) {
    if (
      type === 'floating' ||
      type === 'popover' ||
      type === 'panel-left' ||
      type === 'panel-right' ||
      type === 'panel-top' ||
      type === 'panel-bottom'
    ) {
      if (normalized.tabletPanelMode === 'preserve') return type;
      return normalized.tabletPanelMode === 'modal' ? 'modal' : 'drawer';
    }
  }

  return type;
}

export function shouldUseFullscreenOverlayForBreakpoint(
  type: OverlayType,
  breakpoint: AsukaResponsiveBreakpoint,
  config: NormalizedAsukaResponsiveConfig | AsukaResponsiveConfig | null | undefined,
): boolean {
  const normalized = normalizeResponsiveConfig(config as any);
  if (!normalized.enabled) return false;
  return breakpoint === 'mobile' && normalized.mobileOverlayMode === 'fullscreen' && type === 'modal';
}
