import type { MapPresentationProfile } from "./mapPresentationProfile.js";

export const TRANSPORT_STATION_REFERENCE_PROFILE_ID = "transport-stations.v1";

export type MapReferenceStationCategory = "metro" | "railway_terminal" | "railway_station";

export type MapReferenceLayer = {
  id: string;
  referenceProfileId: typeof TRANSPORT_STATION_REFERENCE_PROFILE_ID;
  category: MapReferenceStationCategory;
  presentationProfileId: string;
  visible: boolean;
};

const profileDefinitions = [
  {
    id: "map.reference.transport.metro.v1",
    title: "Метро",
    category: "metro",
    semanticTypes: ["map.station"],
    hideCameraHeightMeters: 10_000,
  },
  {
    id: "map.reference.transport.terminal.v1",
    title: "Вокзалы",
    category: "railway_terminal",
    semanticTypes: ["map.terminal"],
    hideCameraHeightMeters: 35_000,
  },
  {
    id: "map.reference.transport.railway-station.v1",
    title: "Станции РЖД",
    category: "railway_station",
    semanticTypes: ["map.station"],
    hideCameraHeightMeters: 15_000,
  },
] as const;

export const defaultMapReferenceLayers: readonly MapReferenceLayer[] = profileDefinitions.map((definition) => ({
  id: `reference.transport.${definition.category}`,
  referenceProfileId: TRANSPORT_STATION_REFERENCE_PROFILE_ID,
  category: definition.category,
  presentationProfileId: definition.id,
  visible: true,
}));

export const defaultMapReferencePresentationProfiles: readonly MapPresentationProfile[] = profileDefinitions.map((definition) => ({
  id: definition.id,
  version: "1.2.0",
  title: definition.title,
  semanticTypes: [...definition.semanticTypes],
  label: {
    mode: "attributes",
    fields: ["name", "official_name", "local_name"],
    fontWeight: 600,
    sizePx: 20,
    color: "#cccccc",
    outlineColor: "#0c0d12",
    outlineWidthPx: 1,
    backgroundColor: "#000000",
    backgroundOpacity: 1,
    paddingX: 6,
    paddingY: 3,
    maxLength: 80,
    offsetX: 15,
    offsetY: 0,
    hideCameraHeightMeters: definition.hideCameraHeightMeters,
  },
  target: {
    variant: "elevated-spike",
    stemHeightMeters: 500,
    headSizePx: 20,
    stemWidthPx: 2,
    outlineColor: "#ff00c8",
    outlineOpacity: 1,
    outlineWidthPx: 2,
    hideCameraHeightMeters: definition.hideCameraHeightMeters,
  },
  facets: [{
    id: "category",
    field: "category",
    label: "Категория",
    filterable: false,
    counter: false,
    values: [{ value: definition.category, label: definition.title, order: 0 }],
  }],
  styles: [{ id: "reference", color: "#ffffff", opacity: 1 }],
  classes: [{
    id: definition.category,
    label: definition.title,
    priority: 100,
    match: [{ field: "category", equals: definition.category }],
    styleId: "reference",
    renderable: true,
  }],
  defaultClassId: definition.category,
  sort: [{ field: "category", order: [definition.category] }],
}));

export function ensureMapReferencePresentationProfiles(profiles: MapPresentationProfile[]) {
  const ids = new Set(profiles.map((profile) => profile.id));
  return [
    ...profiles,
    ...defaultMapReferencePresentationProfiles
      .filter((profile) => !ids.has(profile.id))
      .map((profile) => structuredClone(profile) as MapPresentationProfile),
  ];
}

export function initialMapReferenceLayers(value?: MapReferenceLayer[]) {
  const byId = new Map((value ?? []).map((layer) => [layer.id, layer]));
  return defaultMapReferenceLayers.map((layer) => structuredClone(byId.get(layer.id) ?? layer));
}

export function isMapReferencePresentationProfile(profile: MapPresentationProfile) {
  return defaultMapReferencePresentationProfiles.some((candidate) => candidate.id === profile.id);
}
