import type { GuideModelFloorAsset, GuideModelRenderPackage, GuideModelSource, GuideRenderPoi } from '@/domain/guideModel' import { formatNavFloorLabel } from '@/data/adapters/navAssetsAdapter' import { defaultStaticNavAssetsProvider, type StaticNavAssetsProvider, type StaticNavPoiPayload } from '@/data/providers/staticNavAssetsProvider' const toRenderPoi = (poi: StaticNavPoiPayload): GuideRenderPoi => ({ id: poi.id, name: poi.name, floorId: poi.floorId, primaryCategory: poi.primaryCategory, primaryCategoryZh: poi.primaryCategoryZh, iconType: poi.iconType || poi.primaryCategory, positionGltf: poi.positionGltf }) export interface GuideModelRepository extends GuideModelSource {} export class StaticGuideModelRepository implements GuideModelRepository { constructor(private readonly provider: StaticNavAssetsProvider = defaultStaticNavAssetsProvider) {} async loadPackage(): Promise { const [manifest, floorIndex] = await Promise.all([ this.provider.loadManifest(), this.provider.loadFloorIndex() ]) const floors: GuideModelFloorAsset[] = [...floorIndex.floors] .sort((a, b) => a.order - b.order) .map((floor) => ({ floorId: floor.floorId, label: formatNavFloorLabel(floor.floorId), order: floor.order, modelUrl: this.provider.assetUrl(floor.modelAsset) })) return { overviewModelUrl: this.provider.assetUrl(manifest.assets.overviewModel.asset), floors } } async loadFloorPois(floorId: string) { const floorIndex = await this.provider.loadFloorIndex() const floor = floorIndex.floors.find((item) => item.floorId === floorId) if (!floor) return [] const pois = await this.provider.loadFloorPois(floor.poiDataAsset) return pois .map(toRenderPoi) .filter((poi) => Array.isArray(poi.positionGltf) && poi.positionGltf.length === 3) } } export const guideModelRepository = new StaticGuideModelRepository()