import {
  canonicalizePublicSectionBarePath,
  DEFAULT_PUBLIC_LOCALE,
  localizedExactPublicPath,
  PUBLIC_PAGE_PATHS,
  localizedSectionPublicPath,
  stripPublicLocalePrefix,
  withPublicLocalePrefix,
} from '~/utils/public-locales'

function cleanQuery(query = {}) {
  return Object.fromEntries(
    Object.entries(query).filter(([, value]) => value !== undefined && value !== null && value !== ''),
  )
}

const implementedPublicExactPaths = new Set([
  '/',
  '/rent',
  ...Object.values(PUBLIC_PAGE_PATHS)
    .map((paths) => stripPublicLocalePrefix(paths?.[DEFAULT_PUBLIC_LOCALE] || ''))
    .filter(Boolean),
])

const implementedPublicPathPrefixes = [
  '/locations/',
  '/news/',
  '/offers/',
  '/rent/',
  '/routes/',
  '/request/',
  '/track/',
  '/vehicles/',
]

export const RENT_TRIP_QUERY_KEYS = [
  'pickupLocationId',
  'dropoffLocationId',
  'pickupAt',
  'dropoffAt',
  'promoCode',
  'prefillExtra',
  'prefillExtras',
  'returnToSameLocation',
  'driverAge',
  'offerSlug',
  'vehicleId',
]

export function buildRentTripQuery({
  pickupLocationId,
  dropoffLocationId,
  pickupAt,
  dropoffAt,
  promoCode,
  prefillExtra,
  prefillExtras,
  returnToSameLocation,
  driverAge,
  offerSlug,
  vehicleId,
} = {}) {
  return cleanQuery({
    pickupLocationId,
    dropoffLocationId,
    pickupAt,
    dropoffAt,
    promoCode,
    prefillExtra,
    prefillExtras,
    returnToSameLocation,
    driverAge,
    offerSlug,
    vehicleId,
  })
}

function buildLocalizedRoutePath(path, locale = DEFAULT_PUBLIC_LOCALE) {
  return normalizePublicInternalPath(path, locale)
}

export function buildRentSearchRoute(query = {}, options = {}) {
  return {
    path: buildLocalizedRoutePath('/rent', options.locale),
    query: cleanQuery(query),
  }
}

export function buildRentExtrasRoute(vehicleGroupId, query = {}, options = {}) {
  const numericId = Number(vehicleGroupId || 0)

  return {
    path: buildLocalizedRoutePath(numericId > 0 ? `/rent/extras/${numericId}` : '/rent', options.locale),
    query: cleanQuery(query),
  }
}

export function buildRentCheckoutRoute(vehicleGroupId, query = {}, options = {}) {
  const numericId = Number(vehicleGroupId || 0)

  return {
    path: buildLocalizedRoutePath(numericId > 0 ? `/rent/checkout/${numericId}` : '/rent', options.locale),
    query: cleanQuery(query),
  }
}

export function buildRequestRoute(token, query = {}, options = {}) {
  const normalizedToken = String(token || '').trim()

  return {
    path: buildLocalizedRoutePath(normalizedToken ? `/request/${normalizedToken}` : '/request', options.locale),
    query: cleanQuery(query),
  }
}

export function buildTrackRoute(token, query = {}, options = {}) {
  const normalizedToken = String(token || '').trim()

  return {
    path: buildLocalizedRoutePath(normalizedToken ? `/track/${normalizedToken}` : '/track', options.locale),
    query: cleanQuery(query),
  }
}

export function normalizePublicInternalPath(path, locale = DEFAULT_PUBLIC_LOCALE) {
  const value = String(path || '').trim()

  if (!value || /^https?:\/\//.test(value) || value.startsWith('mailto:') || value.startsWith('tel:') || value.startsWith('#')) {
    return value
  }

  const match = value.match(/^([^?#]*)(.*)$/)
  const pathname = match?.[1] || value
  const suffix = match?.[2] || ''
  const barePath = stripPublicLocalePrefix(pathname)
  let normalized = barePath

  if (barePath === '/search') {
    normalized = '/rent'
  }

  if (barePath.startsWith('/extras/')) {
    normalized = barePath.replace('/extras/', '/rent/extras/')
  }

  if (barePath.startsWith('/checkout/')) {
    normalized = barePath.replace('/checkout/', '/rent/checkout/')
  }

  const localizedSectionPath = localizedSectionPublicPath(normalized, locale)

  if (localizedSectionPath) {
    return `${localizedSectionPath}${suffix}`
  }

  const localizedExactPath = localizedExactPublicPath(normalized, locale)

  if (localizedExactPath) {
    return `${localizedExactPath}${suffix}`
  }

  return `${withPublicLocalePrefix(normalized, locale)}${suffix}`
}

export function normalizeImplementedPublicInternalPath(path, locale = DEFAULT_PUBLIC_LOCALE) {
  const normalized = normalizePublicInternalPath(path, locale)

  if (!normalized || /^https?:\/\//.test(normalized) || normalized.startsWith('mailto:') || normalized.startsWith('tel:') || normalized.startsWith('#')) {
    return normalized
  }

  const barePath = stripPublicLocalePrefix(normalized)
  const canonicalBarePath = canonicalizePublicSectionBarePath(barePath)

  if (implementedPublicExactPaths.has(canonicalBarePath)) {
    return normalized
  }

  if (implementedPublicPathPrefixes.some((prefix) => canonicalBarePath.startsWith(prefix))) {
    return normalized
  }

  return null
}
