import {
  ADMIN_REGION_IDS,
  ADMIN_REGION_LABELS,
  CITY_DEFINITIONS,
  ISLAND_GROUP_IDS,
  ISLAND_GROUP_LABELS,
  REGION_WIDE_DEFINITIONS,
  type AdminRegionId,
  type IslandGroupId,
} from './data';

export {
  ADMIN_REGION_IDS,
  ADMIN_REGION_LABELS,
  CITY_DEFINITIONS,
  ISLAND_GROUP_IDS,
  ISLAND_GROUP_LABELS,
  REGION_WIDE_DEFINITIONS,
  type AdminRegionId,
  type IslandGroupId,
} from './data';

/** @deprecated Use DAVAO_REGION_CITIES — kept for backward compatibility */
export const DAVAO_REGION_CITIES = CITY_DEFINITIONS.filter((c) => c.adminRegion === 'DAVAO').map(
  (c) => c.key
) as readonly string[];

export const CITY_SERVICE_AREAS = CITY_DEFINITIONS.map((c) => c.key) as readonly string[];

export const REGION_WIDE_SERVICE_AREAS = REGION_WIDE_DEFINITIONS.map((r) => r.key) as readonly string[];

export const WORKER_SELECTABLE_SERVICE_AREAS = [...CITY_SERVICE_AREAS] as const;

export type WorkerSelectableServiceArea = (typeof WORKER_SELECTABLE_SERVICE_AREAS)[number];

export const SERVICE_AREA_VALUES = [
  ...CITY_SERVICE_AREAS,
  ...REGION_WIDE_SERVICE_AREAS,
] as const;

export type ServiceArea = (typeof SERVICE_AREA_VALUES)[number];

export const SERVICE_AREA_LABELS = Object.fromEntries([
  ...CITY_DEFINITIONS.map((c) => [c.key, c.label]),
  ...REGION_WIDE_DEFINITIONS.map((r) => [r.key, r.label]),
]) as Record<ServiceArea, string>;

export const REGION_SLUGS = Object.fromEntries([
  ...CITY_DEFINITIONS.map((c) => [c.key, c.slug]),
  ...REGION_WIDE_DEFINITIONS.map((r) => [r.key, r.slug]),
]) as Record<ServiceArea, string>;

export const SLUG_TO_SERVICE_AREA: Record<string, ServiceArea> = Object.fromEntries([
  ...Object.entries(REGION_SLUGS).map(([area, slug]) => [slug, area as ServiceArea]),
  // Legacy aliases
  ['metro-manila', 'ENTIRE_NCR'],
]) as Record<string, ServiceArea>;

export const DEFAULT_REGION_SLUG = REGION_SLUGS.ENTIRE_PHILIPPINES;

const citiesByAdminRegion = ADMIN_REGION_IDS.reduce(
  (acc, id) => {
    acc[id] = CITY_DEFINITIONS.filter((c) => c.adminRegion === id).map((c) => c.key as ServiceArea);
    return acc;
  },
  {} as Record<AdminRegionId, ServiceArea[]>
);

const citiesByIslandGroup = ISLAND_GROUP_IDS.reduce(
  (acc, id) => {
    acc[id] = CITY_DEFINITIONS.filter((c) => c.islandGroup === id).map((c) => c.key as ServiceArea);
    return acc;
  },
  {} as Record<IslandGroupId, ServiceArea[]>
);

const adminRegionWideKey: Record<AdminRegionId, ServiceArea> = {
  NCR: 'ENTIRE_NCR',
  CAR: 'ENTIRE_CAR',
  ILOCOS: 'ENTIRE_ILOCOS',
  CAGAYAN_VALLEY: 'ENTIRE_CAGAYAN_VALLEY',
  CENTRAL_LUZON: 'ENTIRE_CENTRAL_LUZON',
  CALABARZON: 'ENTIRE_CALABARZON',
  MIMAROPA: 'ENTIRE_MIMAROPA',
  BICOL: 'ENTIRE_BICOL',
  WESTERN_VISAYAS: 'ENTIRE_WESTERN_VISAYAS',
  CENTRAL_VISAYAS: 'ENTIRE_CENTRAL_VISAYAS',
  EASTERN_VISAYAS: 'ENTIRE_EASTERN_VISAYAS',
  ZAMBOANGA_PENINSULA: 'ENTIRE_ZAMBOANGA_PENINSULA',
  NORTHERN_MINDANAO: 'ENTIRE_NORTHERN_MINDANAO',
  DAVAO: 'ENTIRE_DAVAO_REGION',
  SOCCSKSARGEN: 'ENTIRE_SOCCSKSARGEN',
  CARAGA: 'ENTIRE_CARAGA',
  BARMM: 'ENTIRE_BARMM',
};

const islandGroupWideKey: Record<IslandGroupId, ServiceArea> = {
  LUZON: 'ENTIRE_LUZON',
  VISAYAS: 'ENTIRE_VISAYAS',
  MINDANAO: 'ENTIRE_MINDANAO',
};

const CITY_AREAS = CITY_SERVICE_AREAS as ServiceArea[];

/** Parse enum key, URL slug, or display label into a ServiceArea. */
export function parseServiceArea(input: string | null | undefined): ServiceArea | null {
  if (!input?.trim()) return null;
  const trimmed = input.trim();
  const slugKey = trimmed.toLowerCase();
  if (SLUG_TO_SERVICE_AREA[slugKey]) return SLUG_TO_SERVICE_AREA[slugKey];

  const enumKey = trimmed.toUpperCase().replace(/-/g, '_') as ServiceArea;
  if (SERVICE_AREA_LABELS[enumKey]) return enumKey;

  const fromLabel = Object.entries(SERVICE_AREA_LABELS).find(
    ([, label]) => label.toLowerCase() === slugKey
  );
  return fromLabel ? (fromLabel[0] as ServiceArea) : null;
}

export function serviceAreaToSlug(area: ServiceArea): string {
  return REGION_SLUGS[area];
}

/** Cities included when browsing a given region (country, island, admin region, or city). */
export function serviceAreasForFilter(area: ServiceArea): ServiceArea[] {
  if (area === 'ENTIRE_PHILIPPINES') {
    return [...CITY_AREAS];
  }

  const islandDef = REGION_WIDE_DEFINITIONS.find((r) => r.key === area && r.kind === 'island');
  if (islandDef?.islandGroup) {
    return [...citiesByIslandGroup[islandDef.islandGroup]];
  }

  const adminDef = REGION_WIDE_DEFINITIONS.find((r) => r.key === area && r.kind === 'admin');
  if (adminDef?.adminRegion) {
    return [...citiesByAdminRegion[adminDef.adminRegion]];
  }

  return [area];
}

/** City labels for job location text matching when browsing a region-wide area. */
export function cityLabelsForBrowseArea(area: ServiceArea): string[] {
  return serviceAreasForFilter(area).map((city) => SERVICE_AREA_LABELS[city]);
}

export function isEntireRegion(area: ServiceArea): boolean {
  return area.startsWith('ENTIRE_');
}

/** Browse context that shows all workers/jobs (no area narrowing). */
export function isShowAllBrowseArea(area: ServiceArea | null | undefined): boolean {
  return !area || area === 'ENTIRE_PHILIPPINES';
}

export function getAdminRegionForCity(city: ServiceArea): AdminRegionId | null {
  const def = CITY_DEFINITIONS.find((c) => c.key === city);
  return def?.adminRegion ?? null;
}

export function getIslandGroupForCity(city: ServiceArea): IslandGroupId | null {
  const def = CITY_DEFINITIONS.find((c) => c.key === city);
  return def?.islandGroup ?? null;
}

export interface RegionOptionGroup {
  id: string;
  label: string;
  options: { area: ServiceArea; slug: string; label: string }[];
}

/** Grouped region picker options — country → islands → admin regions → cities. */
export function buildRegionOptionGroups(): RegionOptionGroup[] {
  const countryOptions = REGION_WIDE_DEFINITIONS.filter((r) => r.kind === 'country').map((r) => ({
    area: r.key as ServiceArea,
    slug: r.slug,
    label: r.label,
  }));

  const islandOptions = REGION_WIDE_DEFINITIONS.filter((r) => r.kind === 'island').map((r) => ({
    area: r.key as ServiceArea,
    slug: r.slug,
    label: r.label,
  }));

  const groups: RegionOptionGroup[] = [
    { id: 'country', label: 'Philippines', options: countryOptions },
    { id: 'islands', label: 'Island groups', options: islandOptions },
  ];

  for (const adminId of ADMIN_REGION_IDS) {
    const regionWide = adminRegionWideKey[adminId];
    const cities = CITY_DEFINITIONS.filter((c) => c.adminRegion === adminId);
    groups.push({
      id: adminId,
      label: ADMIN_REGION_LABELS[adminId],
      options: [
        {
          area: regionWide,
          slug: REGION_SLUGS[regionWide],
          label: SERVICE_AREA_LABELS[regionWide],
        },
        ...cities.map((c) => ({
          area: c.key as ServiceArea,
          slug: c.slug,
          label: c.label,
        })),
      ],
    });
  }

  return groups;
}

/** Flat list for backward compatibility — country, islands, then all admin regions and cities. */
export const REGION_OPTIONS = buildRegionOptionGroups().flatMap((g) => g.options);

/** Worker service area picker — cities grouped by admin region. */
export function buildWorkerServiceAreaGroups(): RegionOptionGroup[] {
  return ADMIN_REGION_IDS.map((adminId) => ({
    id: adminId,
    label: ADMIN_REGION_LABELS[adminId],
    options: CITY_DEFINITIONS.filter((c) => c.adminRegion === adminId).map((c) => ({
      area: c.key as ServiceArea,
      slug: c.slug,
      label: c.label,
    })),
  })).filter((g) => g.options.length > 0);
}

export const WORKER_SERVICE_AREA_GROUPS = buildWorkerServiceAreaGroups();

/** Coordinates for map display — cities and region-wide centers. */
export const SERVICE_AREA_COORDINATES: Record<string, { lat: number; lng: number }> =
  Object.fromEntries([
    ...CITY_DEFINITIONS.map((c) => [c.key, { lat: c.lat, lng: c.lng }]),
    ...REGION_WIDE_DEFINITIONS.map((r) => [r.key, { lat: r.lat, lng: r.lng }]),
  ]);

export { adminRegionWideKey, islandGroupWideKey, citiesByAdminRegion, citiesByIslandGroup };
