import { type NextMiddleware, NextResponse } from "next/server"

import { getPublicNextURL } from "@/server/utils"

import type { MiddlewareMatcher } from "@/types/middleware"

/*
    Middleware function to normalize date formats to support
    YYYY-MM-D and YYYY-MM-DD since the current web uses YYYY-MM-D
    in the URL as parameters (toDate and fromDate)
*/
const legacyDatePattern = /^([12]\d{3}-(0[1-9]|1[0-2])-([1-9]))$/

function normalizeDate(date: string): string {
  const datePattern = /^\d{4}-\d{1,2}-\d{1,2}$/
  if (datePattern.test(date)) {
    const [year, month, day] = date.split("-")
    return `${year}-${month.padStart(2, "0")}-${day.padStart(2, "0")}`
  }
  return date
}

export const middleware: NextMiddleware = (request) => {
  const url = getPublicNextURL(request)
  const fromDate = url.searchParams.get("fromdate")
  const toDate = url.searchParams.get("todate")
  const hasLegacyFromDate = fromDate ? legacyDatePattern.test(fromDate) : false
  const hasLegacyToDate = toDate ? legacyDatePattern.test(toDate) : false
  const legacyBookingCode = url.searchParams.get("bookingcode")

  const headers = new Headers(request.headers)

  if (!hasLegacyFromDate && !hasLegacyToDate && !legacyBookingCode) {
    headers.set("x-continue", "1")
    return NextResponse.next({
      headers,
    })
  }

  if (legacyBookingCode) {
    url.searchParams.delete("bookingcode")
    url.searchParams.set("bookingCode", legacyBookingCode)
  }

  if (fromDate && hasLegacyFromDate) {
    const normalizedFromDate = normalizeDate(fromDate)
    url.searchParams.set("fromdate", normalizedFromDate)
  }

  if (toDate && hasLegacyToDate) {
    const normalizedToDate = normalizeDate(toDate)
    url.searchParams.set("todate", normalizedToDate)
  }

  return NextResponse.redirect(url, {
    status: 308,
  })
}

export const matcher: MiddlewareMatcher = (request) => {
  return request.nextUrl.searchParams.size > 0
}
