import { NextResponse } from "next/server"
import { getDistance as getDistanceFromTable } from "@/lib/distance"

const OPENROUTE_API_KEY = process.env.OPENROUTE_API_KEY
const HOME_COORDINATES = { lat: 55.8089, lng: 11.4955 } // 4550 Asnæs

// Postal code prefix to city name for better geocoding
const POSTAL_TO_CITY: Record<string, string> = {
  "1": "København",
  "2": "København",
  "30": "Helsingør",
  "31": "Hornbæk",
  "32": "Helsinge",
  "33": "Frederiksværk",
  "34": "Hillerød",
  "35": "Værløse",
  "36": "Frederikssund",
  "40": "Roskilde",
  "41": "Ringsted",
  "42": "Slagelse",
  "43": "Holbæk",
  "44": "Kalundborg",
  "45": "Nykøbing Sjælland",
  "46": "Køge",
  "47": "Næstved",
  "48": "Nykøbing Falster",
  "49": "Nakskov",
  "50": "Odense",
  "51": "Odense",
  "52": "Odense",
  "55": "Middelfart",
  "56": "Faaborg",
  "57": "Svendborg",
  "58": "Nyborg",
}

function getCityFromPostalCode(postalCode: string): string {
  // Try full prefix first (2 digits), then first digit
  return (
    POSTAL_TO_CITY[postalCode.slice(0, 2)] || POSTAL_TO_CITY[postalCode.slice(0, 1)] || "Denmark"
  )
}

interface OpenRouteResponse {
  features: {
    geometry: {
      coordinates: number[]
    }
  }[]
}

interface DirectionsResponse {
  routes: {
    summary: {
      distance: number // meters
    }
  }[]
}

async function geocodeAddress(
  address: string | null,
  postalCode: string
): Promise<{ lat: number; lng: number } | null> {
  if (!OPENROUTE_API_KEY) return null

  try {
    // Build search text from address and city (postal codes don't work well with OpenRouteService)
    const city = getCityFromPostalCode(postalCode)
    let searchText: string
    if (address && address.trim()) {
      searchText = `${address}, ${city}, Denmark`
    } else {
      searchText = `${city}, Denmark`
    }

    const url = `https://api.openrouteservice.org/geocode/search?api_key=${OPENROUTE_API_KEY}&text=${encodeURIComponent(searchText)}&boundary.country=DK&size=1`
    const response = await fetch(url, { headers: { Accept: "application/json" } })

    if (!response.ok) return null

    const data: OpenRouteResponse = await response.json()
    if (!data.features?.[0]?.geometry?.coordinates) return null

    const [lng, lat] = data.features[0].geometry.coordinates
    return { lat, lng }
  } catch {
    return null
  }
}

async function getRouteDistance(
  from: { lat: number; lng: number },
  to: { lat: number; lng: number }
): Promise<number | null> {
  if (!OPENROUTE_API_KEY) return null

  try {
    const url = `https://api.openrouteservice.org/v2/directions/driving-car?api_key=${OPENROUTE_API_KEY}&start=${from.lng},${from.lat}&end=${to.lng},${to.lat}`
    const response = await fetch(url, { headers: { Accept: "application/geo+json" } })

    if (!response.ok) return null

    const data = await response.json()
    const distance = data.features?.[0]?.properties?.summary?.distance
    if (!distance) return null

    // Convert meters to km and double for round trip
    return Math.round((distance / 1000) * 2)
  } catch {
    return null
  }
}

export async function GET(request: Request) {
  const { searchParams } = new URL(request.url)
  const postalCode = searchParams.get("postalCode")
  const address = searchParams.get("address")

  if (!postalCode || !/^\d{4}$/.test(postalCode)) {
    return NextResponse.json({ error: "Invalid postal code" }, { status: 400 })
  }

  // Try OpenRouteService first if API key is configured
  if (OPENROUTE_API_KEY) {
    const destination = await geocodeAddress(address, postalCode)
    if (destination) {
      const distance = await getRouteDistance(HOME_COORDINATES, destination)
      if (distance !== null) {
        return NextResponse.json({
          distance,
          source: "openrouteservice",
          postalCode,
        })
      }
    }
  }

  // Fall back to postal code table
  const distance = getDistanceFromTable(postalCode)
  return NextResponse.json({
    distance,
    source: "table",
    postalCode,
  })
}
