import { resolveOrganizationModel } from './resolve'
import type { OrganizationModelBuiltinIconToken } from './icons'
import { projectOrganizationSurfaces, type OrganizationSurfaceProjection } from './surface-projection'
import type { DeepPartial, OrganizationModel } from './types'

export type FoundationSurfaceType = 'page' | 'dashboard' | 'graph' | 'detail' | 'list' | 'settings'

export type FoundationSurfaceIcon = Extract<
  OrganizationModelBuiltinIconToken,
  | 'feature.dashboard'
  | 'feature.crm'
  | 'feature.lead-gen'
  | 'feature.projects'
  | 'feature.operations'
  | 'feature.settings'
>

export type FoundationNavigationSurface = Omit<OrganizationSurfaceProjection, 'icon' | 'surfaceType'> & {
  icon?: FoundationSurfaceIcon | OrganizationModelBuiltinIconToken | string
  surfaceType: FoundationSurfaceType
}

export interface FoundationOrganizationModel extends Omit<OrganizationModel, 'navigation'> {
  navigation: {
    defaultSurfaceId: string
    homeLabel: string
    quickAccessSurfaceIds: readonly string[]
    surfaces: FoundationNavigationSurface[]
  }
}

export interface FoundationBranding {
  organizationName: string
  productName: string
  shortName: string
}

export function createFoundationOrganizationModel(override: DeepPartial<OrganizationModel>): {
  canonical: OrganizationModel
  model: FoundationOrganizationModel
  homeLabel: string
  quickAccessSurfaceIds: readonly string[]
  getOrganizationSurface: (surfaceId: string) => FoundationNavigationSurface | undefined
} {
  const canonical = resolveOrganizationModel(override)
  const navigationSurfaces: FoundationNavigationSurface[] = projectOrganizationSurfaces(canonical)
  const defaultSurface = navigationSurfaces.find((surface) => surface.path === '/') ?? navigationSurfaces[0]
  const homeLabel = defaultSurface?.label ?? 'Dashboard'
  const quickAccessSurfaceIds = navigationSurfaces
    .filter((surface) => surface.id !== defaultSurface?.id && surface.surfaceType !== 'settings')
    .slice(0, 4)
    .map((surface) => surface.id)

  const model: FoundationOrganizationModel = {
    ...canonical,
    navigation: {
      defaultSurfaceId: defaultSurface?.id ?? '',
      homeLabel,
      quickAccessSurfaceIds: [...quickAccessSurfaceIds],
      surfaces: navigationSurfaces
    }
  }

  function getOrganizationSurface(surfaceId: string): FoundationNavigationSurface | undefined {
    return model.navigation.surfaces.find((candidate) => candidate.id === surfaceId)
  }

  return {
    canonical,
    model,
    homeLabel,
    quickAccessSurfaceIds,
    getOrganizationSurface
  }
}
