/**
 * gameProfiles.ts — Source of truth for per-game UI adaptation.
 *
 * Every game-specific label, terminology, Steam app ID, management model,
 * stat field list, AND sidebar nav lives here. The dashboard, server cards,
 * wipe manager, sidebar, and any future multi-game surface should key off this
 * registry — never hard-code game-specific strings in components.
 *
 * Backend status: the backend has NO game field on licenses yet. Today every
 * license is implicitly Rust. This registry is ready: when the backend adds a
 * `game` column to `licenses` (or `server_config`), the frontend only needs to
 * read that field and call `useGameProfile(id)` — no component changes required.
 *
 * To add a new game: add a GameId union member and a corresponding entry in
 * GAME_PROFILES. Nothing else changes.
 */

// ---------------------------------------------------------------------------
// Nav structure — drives the per-game sidebar
// ---------------------------------------------------------------------------

/** A single sidebar nav item. route must be an existing panel route path. */
export interface NavItemDef {
  label: string
  route: string
  icon: string
  /** Permission key required to show this item (e.g. 'plugins.view'). Null = always visible. */
  permission: string | null
}

/** A labelled section grouping nav items in the sidebar. */
export interface NavSection {
  /** Section heading (eyebrow text). Empty string = no heading. */
  label: string
  items: NavItemDef[]
}

// ---------------------------------------------------------------------------
// Union types — exhaustive, never widen to string
// ---------------------------------------------------------------------------

/** Every supported game identifier. */
export type GameId = 'rust' | 'conan' | 'soulmask' | 'dune'

/** How the server process is managed. */
export type ManagementModel = 'process+rcon' | 'docker-compose'

/** Mod ecosystem the game uses. */
export type ModSystem = 'umod' | 'workshop' | 'none'

/** Primary console / remote-admin interface. */
export type ConsoleType = 'rcon' | 'rcon+ingame' | 'rcon+gm' | 'rabbitmq'

/**
 * How a "reset" is performed — each value maps to a distinct wipe code path.
 * Pipe-delimited strings intentionally encode composite operations.
 */
export type ResetModel =
  | 'map-bp-wipe'
  | 'wipe-world-structures+decay'
  | 'worlddb-delete+decay'
  | 'deep-desert-coriolis-seed'

/** Cross-server or character-sharing mechanism. */
export type ClusteringModel = 'none' | 'character-transfer' | 'main-client' | 'battlegroup'

// ---------------------------------------------------------------------------
// GameProfile shape
// ---------------------------------------------------------------------------

export interface GameTerminology {
  /** What the operator calls a reset / wipe. */
  reset: string
  /** What the operator calls plugins / mods (null if no mod system). */
  mods: string | null
  /** What the operator calls a player group / faction. */
  group: string
}

export interface GamePorts {
  game: number
  query: number
  rcon: number
  cluster?: number
}

export interface GameProfile {
  /** Human-readable game name. */
  label: string
  /** CSS design-token key — maps to data-game attr and --accent token. */
  accent: string
  managementModel: ManagementModel
  steamAppId: number | { windows: number; linux: number }
  /** Default ports (game-specific defaults; operator can override). */
  ports?: GamePorts
  mods: ModSystem
  console: ConsoleType
  resetModel: ResetModel
  clustering: ClusteringModel
  /** Available map names, if the game ships with named maps. */
  maps?: string[]
  terminology: GameTerminology
  /** Notable game-specific mechanics that affect server administration. */
  special?: string[]
  /**
   * Primary editable config file, relative to the instance root — prefilled in
   * the Server-page config editor as a hint (operator can change it). null if
   * the game has no single primary config file.
   */
  primaryConfigFile?: string | null
  /**
   * Stat field labels shown on server cards and the dashboard.
   * First entry is always Players; subsequent entries are game-specific.
   */
  statFields: [string, string, string]
  /**
   * Per-game sidebar navigation. Ordered list of sections, each with items.
   * Items MUST use only existing panel routes (see router/index.ts).
   * The sidebar renders exactly these sections for the active game.
   */
  nav: NavSection[]
}

// ---------------------------------------------------------------------------
// Registry
// ---------------------------------------------------------------------------

// ---------------------------------------------------------------------------
// Shared nav building blocks — reused across game nav definitions
// ---------------------------------------------------------------------------

const NAV_DASHBOARD: NavItemDef = { label: 'Dashboard', route: '/', icon: 'layout-dashboard', permission: null }
const NAV_FLEET: NavItemDef = { label: 'Fleet', route: '/fleet', icon: 'server-cog', permission: 'server.view' }
const NAV_SERVER: NavItemDef = { label: 'Server', route: '/server', icon: 'server', permission: 'server.view' }
const NAV_CONSOLE: NavItemDef = { label: 'Console', route: '/console', icon: 'terminal', permission: 'console.view' }
const NAV_PLAYERS: NavItemDef = { label: 'Players', route: '/players', icon: 'users', permission: 'players.view' }
const NAV_PLUGINS: NavItemDef = { label: 'Plugins (uMod)', route: '/plugins', icon: 'puzzle', permission: 'plugins.view' }
const NAV_FILES: NavItemDef = { label: 'File manager', route: '/files', icon: 'folder-open', permission: 'files.view' }
const NAV_PLUGIN_CONFIGS: NavItemDef = { label: 'Plugin configs', route: '/plugin-configs', icon: 'sliders', permission: null }
const NAV_SCHEDULES: NavItemDef = { label: 'Schedules', route: '/schedules', icon: 'calendar-clock', permission: 'schedules.view' }
const NAV_CHAT: NavItemDef = { label: 'Chat log', route: '/chat', icon: 'message-square', permission: 'chat.view' }
const NAV_ANALYTICS: NavItemDef = { label: 'Analytics', route: '/analytics', icon: 'bar-chart-3', permission: 'analytics.view' }
const NAV_ALERTS: NavItemDef = { label: 'Alerts', route: '/alerts', icon: 'triangle-alert', permission: 'alerts.view' }
const NAV_NOTIFICATIONS: NavItemDef = { label: 'Notifications', route: '/notifications', icon: 'bell', permission: 'notifications.view' }
const NAV_TEAM: NavItemDef = { label: 'Team', route: '/team', icon: 'users', permission: null }
const NAV_STORE: NavItemDef = { label: 'Store', route: '/store/config', icon: 'shopping-cart', permission: 'store.view' }
const NAV_MODULES: NavItemDef = { label: 'Modules', route: '/modules', icon: 'layers', permission: 'modules.view' }
const NAV_CHANGELOG: NavItemDef = { label: 'Changelog', route: '/changelog', icon: 'file-text', permission: 'changelog.view' }
const NAV_SETTINGS: NavItemDef = { label: 'Settings', route: '/settings', icon: 'settings', permission: 'settings.view' }
const NAV_MAPS: NavItemDef = { label: 'Maps', route: '/maps', icon: 'map', permission: 'maps.view' }

/** Full Rust / 'all' nav — superset used as fallback. */
const RUST_NAV: NavSection[] = [
  { label: '', items: [NAV_DASHBOARD] },
  {
    label: 'Server',
    items: [NAV_FLEET, NAV_SERVER, NAV_CONSOLE, NAV_PLAYERS, NAV_PLUGINS, NAV_FILES],
  },
  { label: 'Plugin configs', items: [NAV_PLUGIN_CONFIGS] },
  {
    label: 'Operations',
    items: [
      { label: 'Wipe', route: '/wipes', icon: 'trash-2', permission: 'wipes.view' },
      NAV_MAPS,
      NAV_SCHEDULES,
    ],
  },
  {
    label: 'Monitoring',
    items: [NAV_CHAT, NAV_ANALYTICS, NAV_ALERTS, NAV_NOTIFICATIONS],
  },
  {
    label: 'Management',
    items: [NAV_TEAM, NAV_STORE, NAV_MODULES, NAV_CHANGELOG, NAV_SETTINGS],
  },
]

export const GAME_PROFILES: Record<GameId, GameProfile> = {
  rust: {
    label: 'Rust',
    accent: 'rust',
    managementModel: 'process+rcon',
    steamAppId: 258550,
    mods: 'umod',
    console: 'rcon',
    resetModel: 'map-bp-wipe',
    clustering: 'none',
    terminology: {
      reset: 'Wipe',
      mods: 'Plugins',
      group: 'Team',
    },
    statFields: ['Players', 'uMod', 'Wipe'],
    primaryConfigFile: 'server/cfg/server.cfg',
    nav: RUST_NAV,
  },

  conan: {
    label: 'Conan Exiles',
    accent: 'conan',
    managementModel: 'process+rcon',
    steamAppId: 443030,
    ports: { game: 7777, query: 27015, rcon: 25575 },
    mods: 'workshop',
    console: 'rcon+ingame',
    // Player progress persists across world wipes — only structures are cleared.
    resetModel: 'wipe-world-structures+decay',
    clustering: 'character-transfer',
    maps: ['Exiled Lands', 'Isle of Siptah'],
    terminology: {
      reset: 'Wipe World',
      mods: 'Mods',
      group: 'Clan',
    },
    special: ['Clans', 'Thralls', 'Avatars', 'Purge', 'PvP windows'],
    statFields: ['Players', 'Clans', 'Purge'],
    primaryConfigFile: 'ConanSandbox/Saved/Config/LinuxServer/ServerSettings.ini',
    nav: [
      { label: '', items: [NAV_DASHBOARD] },
      {
        label: 'Server',
        // Conan: no uMod/Oxide; has RCON console, maps, players, files
        items: [NAV_FLEET, NAV_SERVER, NAV_CONSOLE, NAV_PLAYERS, NAV_FILES],
      },
      {
        label: 'Operations',
        items: [
          { label: 'Wipe World', route: '/wipes', icon: 'trash-2', permission: 'wipes.view' },
          NAV_MAPS,
          NAV_SCHEDULES,
        ],
      },
      {
        label: 'Monitoring',
        items: [NAV_CHAT, NAV_ANALYTICS, NAV_ALERTS, NAV_NOTIFICATIONS],
      },
      {
        label: 'Management',
        items: [NAV_TEAM, NAV_STORE, NAV_MODULES, NAV_CHANGELOG, NAV_SETTINGS],
      },
    ],
  },

  soulmask: {
    label: 'Soulmask',
    accent: 'soulmask',
    managementModel: 'process+rcon',
    // Different Steam app IDs per OS (uncommon — store this explicitly).
    steamAppId: { windows: 3017310, linux: 3017300 },
    ports: { game: 8777, query: 27015, rcon: 19000, cluster: 20000 },
    mods: 'workshop',
    console: 'rcon+gm',
    resetModel: 'worlddb-delete+decay',
    clustering: 'main-client',
    maps: ['Cloud Mist Forest', 'Shifting Sands'],
    terminology: {
      reset: 'World Reset',
      mods: 'Workshop Mods',
      group: 'Tribe',
    },
    special: ['Cluster', 'Tribes'],
    statFields: ['Players', 'Tribe', 'Mask'],
    primaryConfigFile: 'WS/Saved/GameplaySettings/GameXishu.json',
    nav: [
      { label: '', items: [NAV_DASHBOARD] },
      {
        label: 'Server',
        // Soulmask: no uMod/Oxide; has RCON+GM console, players, files
        items: [NAV_FLEET, NAV_SERVER, NAV_CONSOLE, NAV_PLAYERS, NAV_FILES],
      },
      {
        label: 'Operations',
        items: [
          { label: 'World Reset', route: '/wipes', icon: 'trash-2', permission: 'wipes.view' },
          NAV_SCHEDULES,
        ],
      },
      {
        label: 'Monitoring',
        items: [NAV_CHAT, NAV_ANALYTICS, NAV_ALERTS],
      },
      {
        label: 'Management',
        items: [NAV_TEAM, NAV_STORE, NAV_MODULES, NAV_CHANGELOG, NAV_SETTINGS],
      },
    ],
  },

  dune: {
    label: 'Dune: Awakening',
    accent: 'dune',
    managementModel: 'docker-compose',
    steamAppId: 4754530,
    mods: 'none',
    // Dune uses RabbitMQ for its admin messaging — not a standard RCON port.
    console: 'rabbitmq',
    resetModel: 'deep-desert-coriolis-seed',
    clustering: 'battlegroup',
    terminology: {
      reset: 'Deep Desert reset',
      mods: null,
      group: 'Guild',
    },
    special: ['Sietches', 'Deep Desert', 'Bases', 'Landsraad'],
    statFields: ['Players', 'Sietches', 'Control'],
    primaryConfigFile: null,
    nav: [
      { label: '', items: [NAV_DASHBOARD] },
      {
        label: 'Server',
        // Dune: no RCON (uses RabbitMQ); label console "Broadcast"; no maps route; no plugins
        items: [
          NAV_FLEET,
          NAV_SERVER,
          { label: 'Broadcast', route: '/console', icon: 'radio', permission: 'console.view' },
          NAV_PLAYERS,
          NAV_FILES,
        ],
      },
      {
        label: 'Operations',
        items: [
          { label: 'Deep Desert', route: '/wipes', icon: 'wind', permission: 'wipes.view' },
          NAV_SCHEDULES,
        ],
      },
      {
        label: 'Monitoring',
        items: [NAV_ANALYTICS, NAV_ALERTS],
      },
      {
        label: 'Management',
        items: [NAV_TEAM, NAV_STORE, NAV_CHANGELOG, NAV_SETTINGS],
      },
    ],
  },
} as const

// ---------------------------------------------------------------------------
// Helper
// ---------------------------------------------------------------------------

/**
 * Returns the GameProfile for the given id, falling back to Rust if the id is
 * unknown (forward-compatibility: unknown games show Rust defaults until their
 * profile is added).
 *
 * @example
 * const profile = useGameProfile('rust')
 * console.log(profile.terminology.reset) // 'Wipe'
 */
export function useGameProfile(id: string): GameProfile {
  return (GAME_PROFILES as Record<string, GameProfile>)[id] ?? GAME_PROFILES.rust
}
