import { fileURLToPath } from "node:url"

import * as Sentry from "@sentry/nextjs"
import createJiti from "jiti"

import { findMyBooking } from "./constants/routes/findMyBooking.js"
import { login, logout } from "./constants/routes/handleAuth.js"
import { myPages } from "./constants/routes/myPages.js"
import { myStay, preliminaryReceipt } from "./constants/routes/myStay.js"

const jiti = createJiti(fileURLToPath(import.meta.url))
jiti("./env/server")
jiti("./env/client")

/** @type {import('next').NextConfig} */
const nextConfig = {
  env: {
    BRANCH: process.env.BRANCH || "local",
    GIT_SHA: process.env.COMMIT_REF || "",
  },
  poweredByHeader: false,
  eslint: { ignoreDuringBuilds: true },
  trailingSlash: false,
  experimental: {
    serverActions: {
      allowedOrigins: [
        "*--web-scandic-hotels.netlify.app",
        "develop--web-scandic-hotels.netlify.app",
        "stage--web-scandic-hotels.netlify.app",
        "test--web-scandic-hotels.netlify.app",
        "master--web-scandic-hotels.netlify.app",
        "*.scandichotels.com",
      ],
    },
    swcPlugins: [
      [
        "@swc/plugin-formatjs",
        {
          ast: true,
        },
      ],
    ],
  },
  images: {
    minimumCacheTTL: 2678400, // 31 days
    deviceSizes: [320, 420, 768, 1024, 1200, 2400],
    imageSizes: [200, 400, 800, 1200, 1920],
    remotePatterns: [
      {
        protocol: "https",
        hostname: "eu-images.contentstack.com",
        pathname: "/v3/assets/**",
      },
      {
        protocol: "https",
        hostname: "scandichotels.com",
      },
      {
        protocol: "https",
        hostname: "*.scandichotels.com",
      },
      // Tripadvisor CDN for award images
      {
        protocol: "https",
        hostname: "static.tacdn.com",
      },
    ],
  },

  logging: {
    fetches: {
      fullUrl: true,
    },
  },

  output: "standalone",

  webpack: function (config) {
    config.module.rules.push(
      {
        test: /\.(graphql|gql)/,
        exclude: /node_modules/,
        loader: "graphql-tag/loader",
      },
      {
        test: /\.svg$/,
        use: ["@svgr/webpack"],
      }
    )

    return config
  },

  // https://nextjs.org/docs/app/api-reference/next-config-js/redirects#header-cookie-and-query-matching
  redirects() {
    // Param checks needs to be split as Next.js handles everything
    // in the missing array as AND, therefore they need to be separate
    // to handle when one or more are missing.
    //
    // Docs: all missing items must not match for the redirect to be applied.
    return [
      {
        // ----------------------------------------
        // hotel (hotelId) param missing
        // ----------------------------------------
        source: "/:lang/hotelreservation/details",
        destination: "/:lang/hotelreservation/select-rate",
        missing: [
          {
            key: "hotel",
            type: "query",
            value: undefined,
          },
        ],
        permanent: false,
      },
      {
        // ----------------------------------------
        // hotel (hotelId) param has to be an integer
        // ----------------------------------------
        source: "/:lang/hotelreservation/details",
        destination: "/:lang/hotelreservation/select-rate",
        missing: [
          {
            key: "hotel",
            type: "query",
            value: "^[0-9]+$",
          },
        ],
        permanent: false,
      },
      {
        // ----------------------------------------
        // fromdate param missing
        // ----------------------------------------
        source: "/:lang/hotelreservation/details",
        destination: "/:lang/hotelreservation/select-rate",
        missing: [
          {
            key: "fromdate",
            type: "query",
            value: undefined,
          },
        ],
        permanent: false,
      },
      {
        // ----------------------------------------
        // fromdate param has to be a date
        // ----------------------------------------
        source: "/:lang/hotelreservation/details",
        destination: "/:lang/hotelreservation/select-rate",
        missing: [
          {
            key: "fromdate",
            type: "query",
            value: "^([12]\\d{3}-(0[1-9]|1[0-2])-(0?[1-9]|[12]\\d|3[01]))$",
          },
        ],
        permanent: false,
      },
      {
        // ----------------------------------------
        // todate param missing
        // ----------------------------------------
        source: "/:lang/hotelreservation/details",
        destination: "/:lang/hotelreservation/select-rate",
        missing: [
          {
            key: "todate",
            type: "query",
            value: undefined,
          },
        ],
        permanent: false,
      },
      {
        // ----------------------------------------
        // todate param has to be a date
        // ----------------------------------------
        source: "/:lang/hotelreservation/details",
        destination: "/:lang/hotelreservation/select-rate",
        missing: [
          {
            key: "todate",
            type: "query",
            value: "^([12]\\d{3}-(0[1-9]|1[0-2])-(0?[1-9]|[12]\\d|3[01]))$",
          },
        ],
        permanent: false,
      },
      {
        // ----------------------------------------
        // room[0].adults param missing
        // ----------------------------------------
        source: "/:lang/hotelreservation/details",
        destination: "/:lang/hotelreservation/select-rate",
        missing: [
          {
            key: "room[0].adults",
            type: "query",
            value: undefined,
          },
        ],
        permanent: false,
      },
      {
        // ----------------------------------------
        // room[0].adults param has to be an integer
        // ----------------------------------------
        source: "/:lang/hotelreservation/details",
        destination: "/:lang/hotelreservation/select-rate",
        missing: [
          {
            key: "room[0].adults",
            type: "query",
            value: "^[0-9]+$",
          },
        ],
        permanent: false,
      },
      {
        // ----------------------------------------
        // room[0].ratecode param missing
        // ----------------------------------------
        source: "/:lang/hotelreservation/details",
        destination: "/:lang/hotelreservation/select-rate",
        missing: [
          {
            key: "room[0].ratecode",
            type: "query",
            value: undefined,
          },
        ],
        permanent: false,
      },
      {
        // ----------------------------------------
        // room[0].roomtype param missing
        // ----------------------------------------
        source: "/:lang/hotelreservation/details",
        destination: "/:lang/hotelreservation/select-rate",
        missing: [
          {
            key: "room[0].roomtype",
            type: "query",
            value: undefined,
          },
        ],
        permanent: false,
      },
    ]
  },

  rewrites() {
    return {
      beforeFiles: [
        { source: login.da, destination: "/da/login" },
        { source: login.de, destination: "/de/login" },
        { source: login.fi, destination: "/fi/login" },
        { source: login.no, destination: "/no/login" },
        { source: login.sv, destination: "/sv/login" },
        { source: logout.da, destination: "/da/logout" },
        { source: logout.de, destination: "/de/logout" },
        { source: logout.fi, destination: "/fi/logout" },
        { source: logout.no, destination: "/no/logout" },
        { source: logout.sv, destination: "/sv/logout" },
        {
          source: `${myPages.en}/:path*`,
          destination: `/en/my-pages/:path*`,
        },
        {
          source: `${myPages.da}/:path*`,
          destination: `/da/my-pages/:path*`,
        },
        {
          source: `${myPages.de}/:path*`,
          destination: `/de/my-pages/:path*`,
        },
        {
          source: `${myPages.fi}/:path*`,
          destination: `/fi/my-pages/:path*`,
        },
        {
          source: `${myPages.no}/:path*`,
          destination: `/no/my-pages/:path*`,
        },
        {
          source: `${myPages.sv}/:path*`,
          destination: `/sv/my-pages/:path*`,
        },
        {
          source: "/:lang/hotelreservation/payment-callback/:status",
          destination:
            "/:lang/hotelreservation/payment-callback?status=:status",
        },
        // Find my booking
        {
          source: findMyBooking.en,
          destination: "/en/hotelreservation/get-booking",
        },
        {
          source: findMyBooking.da,
          destination: "/da/hotelreservation/get-booking",
        },
        {
          source: findMyBooking.de,
          destination: "/de/hotelreservation/get-booking",
        },
        {
          source: findMyBooking.fi,
          destination: "/fi/hotelreservation/get-booking",
        },
        {
          source: findMyBooking.no,
          destination: "/no/hotelreservation/get-booking",
        },
        {
          source: findMyBooking.sv,
          destination: "/sv/hotelreservation/get-booking",
        },
        // My stay
        {
          source: `${myStay.en}`,
          destination: "/en/hotelreservation/my-stay",
        },
        {
          source: `${myStay.sv}`,
          destination: "/sv/hotelreservation/my-stay",
        },
        {
          source: `${myStay.da}`,
          destination: "/da/hotelreservation/my-stay",
        },
        {
          source: `${myStay.de}`,
          destination: "/de/hotelreservation/my-stay",
        },
        {
          source: `${myStay.fi}`,
          destination: "/fi/hotelreservation/my-stay",
        },
        {
          source: `${myStay.no}`,
          destination: "/no/hotelreservation/my-stay",
        },
        // My stay receipt
        {
          source: `${preliminaryReceipt.en}`,
          destination: "/en/hotelreservation/my-stay/receipt",
        },
        {
          source: `${preliminaryReceipt.sv}`,
          destination: "/sv/hotelreservation/my-stay/receipt",
        },
        {
          source: `${preliminaryReceipt.da}`,
          destination: "/da/hotelreservation/my-stay/receipt",
        },
        {
          source: `${preliminaryReceipt.de}`,
          destination: "/de/hotelreservation/my-stay/receipt",
        },
        {
          source: `${preliminaryReceipt.fi}`,
          destination: "/fi/hotelreservation/my-stay/receipt",
        },
        {
          source: `${preliminaryReceipt.no}`,
          destination: "/no/hotelreservation/my-stay/receipt",
        },
        {
          source: `/sitemap-:id(\\d{1,}).xml`,
          destination: `/sitemap/:id`,
        },
        {
          source: `/sitemap-index.xml`,
          destination: `/sitemap`,
        },
      ],
    }
  },
}

export default Sentry.withSentryConfig(nextConfig, {
  org: "scandic-hotels",
  project: "scandic-web",
  enabled: process.env.NODE_ENV !== "development",
  authToken: process.env.SENTRY_AUTH_TOKEN,

  // Only print logs for uploading source maps in CI
  silent: !process.env.CI,

  // Upload a larger set of source maps for prettier stack traces (increases build time)
  widenClientFileUpload: true,

  // Automatically annotate React components to show their full name in breadcrumbs and session replay
  reactComponentAnnotation: {
    enabled: true,
  },

  hideSourceMaps: true,
  disableLogger: true,
})
