export type CoordinateSystem = 'GCJ02'

export type DictionaryStatus = 'enabled' | 'disabled'
export type ContentRightsStatus = 'cleared' | 'restricted' | 'unknown'
export type ReviewStatus = 'pending' | 'approved' | 'rejected'
export type PublishStatus = 'draft' | 'published' | 'offline'
export type OpeningHoursStatus = 'known' | 'unknown' | 'by_appointment' | 'temporarily_closed'
export type RecommendationSource = 'official_editorial' | 'poc_default'
export type DatasetCoverageScope = 'reviewed_sample' | 'authoritative_baseline'

export interface GeoPoint {
  longitude: number
  latitude: number
}

export interface MapViewport extends GeoPoint {
  scale: number
}

export interface PoiCategory {
  code: string
  name: string
  markerIcon: string
  selectedMarkerIcon: string
  sortOrder: number
  status: DictionaryStatus
}

export interface PoiTag {
  code: string
  name: string
  sortOrder: number
  status: DictionaryStatus
  synonyms?: string[]
}

export interface PoiImageAsset {
  id: string
  url: string
  source: string
  sourceReference: string | null
  copyrightStatus: ContentRightsStatus
  licenseEvidence: string
  reviewedBy: string
  reviewedAt: string
  updatedAt: string
  /** POC placeholder assets are valid for development, but not for final image acceptance. */
  isPlaceholder?: boolean
  alt: string
}

export interface PoiOpeningHours {
  status: OpeningHoursStatus
  displayText: string | null
  note: string | null
  sourceUpdatedAt: string | null
}

export interface Poi {
  id: string
  name: string
  aliases?: string[]
  categoryCode: string
  tagCodes: string[]
  longitude: number
  latitude: number
  coordinateSystem: CoordinateSystem
  coverImageId: string
  imageIds: string[]
  summary: string
  description: string
  address: string
  openingHours: PoiOpeningHours
  recommendationIndex: number
  recommendationSource: RecommendationSource
  recommendationConfiguredBy: string
  recommendationUpdatedAt: string
  streetCode: string | null
  dataSource: string
  sourceReference: string | null
  contentRightsStatus: ContentRightsStatus
  contentRightsEvidence: string
  reviewStatus: ReviewStatus
  publishStatus: PublishStatus
  reviewedBy: string | null
  reviewedAt: string | null
  updatedAt: string
}

export interface PoiDatasetMeta {
  datasetVersion: string
  generatedAt: string
  reviewedBy: string[]
  coverageScope: DatasetCoverageScope
  coverageLabel: string
  authoritativeBaselineProvided: boolean
  canClaimFullCoverage: boolean
  disclaimer: string
  defaultViewport: MapViewport
}

export interface PoiDataset {
  meta: PoiDatasetMeta
  categories: PoiCategory[]
  tags: PoiTag[]
  images: PoiImageAsset[]
  pois: Poi[]
}

export interface PoiFilter {
  categoryCode?: string | null
  tagCodes?: string[]
}

export interface PoiResolved extends Poi {
  category: PoiCategory
  tags: PoiTag[]
  coverImage: PoiImageAsset
  images: PoiImageAsset[]
  openingHoursText: string
}

export interface PoiSummary {
  id: string
  name: string
  categoryCode: string
  categoryName: string
  tagCodes: string[]
  tags: PoiTag[]
  longitude: number
  latitude: number
  coordinateSystem: CoordinateSystem
  coverImage: PoiImageAsset
  summary: string
  description: string
  address: string
  recommendationIndex: number
  recommendationSource: RecommendationSource
  openingHoursText: string
}

export type PoiValidationErrorCode =
  | 'DUPLICATE_ID'
  | 'DATASET_STRUCTURE_INVALID'
  | 'REQUIRED_FIELD_MISSING'
  | 'CATEGORY_INVALID'
  | 'TAG_INVALID'
  | 'COORDINATE_INVALID'
  | 'COORDINATE_SYSTEM_INVALID'
  | 'OUTSIDE_TARGET_AREA'
  | 'IMAGE_INVALID'
  | 'COPYRIGHT_NOT_CLEARED'
  | 'OPENING_HOURS_INVALID'
  | 'RECOMMENDATION_INVALID'
  | 'POTENTIAL_COORDINATE_OVERLAP'
  | 'REVIEW_NOT_APPROVED'
  | 'PUBLISH_STATUS_INVALID'
  | 'POC_PLACEHOLDER_ASSET'

export interface PoiValidationIssue {
  code: PoiValidationErrorCode
  severity: 'error' | 'warning'
  path: string
  poiId?: string
  message: string
}

export interface PoiDatasetValidationResult {
  isDatasetUsable: boolean
  isValid: boolean
  issues: PoiValidationIssue[]
  validPois: Poi[]
  invalidPoiIds: string[]
}

export interface PoiRepository {
  getDatasetMeta: () => PoiDatasetMeta
  getCategories: () => PoiCategory[]
  getTags: () => PoiTag[]
  getPublishedPois: (filter?: PoiFilter) => PoiResolved[]
  getPoiSummaries: (filter?: PoiFilter) => PoiSummary[]
  getPoiById: (poiId: string) => PoiResolved | null
}
