import { createEnv } from "@t3-oss/env-nextjs"
import { z } from "zod"

import { getLiveStatus } from "./getLiveStatus"
import { isLangLive } from "./isLangLive"

import type { Lang } from "../constants/languages"

const TWENTYFOUR_HOURS = 24 * 60 * 60

const _env = createEnv({
  /**
   * Due to t3-env only checking typeof window === "undefined"
   * and Netlify running Deno, window is never "undefined"
   * https://github.com/t3-oss/t3-env/issues/154
   */
  isServer: typeof window === "undefined" || "Deno" in window,
  server: {
    APPLICATION_INSIGHTS_CONNECTION_STRING: z.string().optional(),
    ADOBE_SCRIPT_SRC: z.string().optional(),
    ADOBE_SDK_SCRIPT_SRC: z.string().optional(),
    ENABLE_GTMSCRIPT: z
      .string()
      // only allow "true" or "false"
      .refine((s) => s === "true" || s === "false")
      // transform to boolean
      .transform((s) => s === "true")
      .default("false"),
    API_BASEURL: z.string(),
    BUILD_ID: z.string().default("64rYXBu8o2eHp0Jf"),
    CMS_ACCESS_TOKEN: z.string(),
    CMS_API_KEY: z.string(),
    CMS_ENVIRONMENT: z.enum(["development", "production", "stage", "test"]),
    CMS_PREVIEW_TOKEN: z.string(),
    CMS_PREVIEW_URL: z.string(),
    CMS_URL: z.string(),
    CMS_BRANCH: z.enum(["development", "production"]),
    CURITY_CLIENT_ID_USER: z.string().default("scandichotels-web"),
    CURITY_CLIENT_ID_SERVICE: z.string().default("scandichotels-web-backend"),
    CURITY_CLIENT_SECRET_SERVICE: z.string(),
    CURITY_CLIENT_SECRET_USER: z.string(),
    CURITY_ISSUER_USER: z.string(),
    CURITY_ISSUER_SERVICE: z.string(),
    CYPRESS_BASE_URL: z.string().default("http://127.0.0.1:3000"),
    ENVTEST: z.string().optional(),
    // https://env.t3.gg/docs/recipes#booleans
    NEXTAUTH_DEBUG: z
      .string()
      .refine((s) => s === "true" || s === "false")
      .transform((s) => s === "true")
      .default("false"),
    NEXTAUTH_REDIRECT_PROXY_URL: z.string().optional(),
    NEXTAUTH_SECRET: z.string(),
    NEXTAUTH_URL: z.string().default(""),
    AUTH_URL: z.string().default(""),
    NODE_ENV: z.enum(["development", "test", "production"]),
    PRINT_QUERY: z
      .string()
      .refine((s) => s === "true" || s === "false")
      .transform((s) => s === "true")
      .default("false"),
    PUBLIC_URL: z.string().default(""),
    REVALIDATE_SECRET: z.string(),
    SITEMAP_SYNC_SECRET: z.string(),
    SALESFORCE_PREFERENCE_BASE_URL: z.string(),
    SEAMLESS_LOGIN_DA: z
      .string()
      .transform((s) => replaceTopLevelDomain(s, "dk")),
    SEAMLESS_LOGIN_DE: z
      .string()
      .transform((s) => replaceTopLevelDomain(s, "de")),
    SEAMLESS_LOGIN_EN: z
      .string()
      .transform((s) => replaceTopLevelDomain(s, "com")),
    SEAMLESS_LOGIN_FI: z
      .string()
      .transform((s) => replaceTopLevelDomain(s, "fi")),
    SEAMLESS_LOGIN_NO: z
      .string()
      .transform((s) => replaceTopLevelDomain(s, "no")),
    SEAMLESS_LOGIN_SV: z
      .string()
      .transform((s) => replaceTopLevelDomain(s, "se")),
    SEAMLESS_LOGOUT_DA: z
      .string()
      .transform((s) => replaceTopLevelDomain(s, "dk")),
    SEAMLESS_LOGOUT_DE: z
      .string()
      .transform((s) => replaceTopLevelDomain(s, "de")),
    SEAMLESS_LOGOUT_EN: z
      .string()
      .transform((s) => replaceTopLevelDomain(s, "com")),
    SEAMLESS_LOGOUT_FI: z
      .string()
      .transform((s) => replaceTopLevelDomain(s, "fi")),
    SEAMLESS_LOGOUT_NO: z
      .string()
      .transform((s) => replaceTopLevelDomain(s, "no")),
    SEAMLESS_LOGOUT_SV: z
      .string()
      .transform((s) => replaceTopLevelDomain(s, "se")),
    SHOW_SIGNUP_FLOW: z
      .string()
      // only allow "true" or "false"
      .refine((s) => s === "true" || s === "false")
      // transform to boolean
      .transform((s) => s === "true")
      .default("false"),
    WEBVIEW_ENCRYPTION_KEY: z.string(),
    BOOKING_ENCRYPTION_KEY: z.string(),
    GOOGLE_STATIC_MAP_KEY: z.string(),
    GOOGLE_STATIC_MAP_SIGNATURE_SECRET: z.string(),
    GOOGLE_DYNAMIC_MAP_ID: z.string(),
    GOOGLE_STATIC_MAP_ID: z.string(),
    ENABLE_BOOKING_WIDGET: z
      .string()
      // only allow "true" or "false"
      .refine((s) => s === "true" || s === "false")
      // transform to boolean
      .transform((s) => s === "true")
      .default("false"),
    ENABLE_SURPRISES: z
      .string()
      // only allow "true" or "false"
      .refine((s) => s === "true" || s === "false")
      // transform to boolean
      .transform((s) => s === "true")
      .default("false"),
    ENABLE_DTMC: z
      .string()
      // only allow "true" or "false"
      .refine((s) => s === "true" || s === "false")
      // transform to boolean
      .transform((s) => s === "true")
      .default("false"),
    SHOW_SITE_WIDE_ALERT: z
      .string()
      // only allow "true" or "false"
      .refine((s) => s === "true" || s === "false")
      // transform to boolean
      .transform((s) => s === "true")
      .default("false"),
    USE_NEW_REWARD_MODEL: z
      .string()
      // only allow "true" or "false"
      .refine((s) => s === "true" || s === "false")
      // transform to boolean
      .transform((s) => s === "true")
      .default("false"),
    SENTRY_ENVIRONMENT: z.string().default("development"),
    SENTRY_SERVER_SAMPLERATE: z.coerce.number().default(0.001),

    // TODO: remove defaults for SAS value when we know that netlify has 'room' for it
    SAS_API_ENDPOINT: z.string().default(""),
    SAS_AUTH_ENDPOINT: z.string().default(""),
    SAS_OCP_APIM: z.string().default(""),
    SAS_AUTH_CLIENTID: z.string().default(""),
    SAS_ENABLED: z
      .string()
      .refine((s) => s === "1" || s === "0")
      .transform((s) => s === "1")
      .default("0"),
    SAS_POINT_TRANSFER_ENABLED: z
      .string()
      // only allow "true" or "false"
      .refine((s) => s === "true" || s === "false")
      // transform to boolean
      .transform((s) => s === "true")
      .default("false"),
    CACHE_TIME_HOTELS: z.coerce
      .number()
      .default(TWENTYFOUR_HOURS)
      .transform((val) =>
        process.env.CMS_ENVIRONMENT === "test" ? 5 * 60 : val
      ),
    CACHE_TIME_CITY_SEARCH: z.coerce
      .number()
      .default(10 * 60)
      .transform((val) => (process.env.CMS_ENVIRONMENT === "test" ? 60 : val)),
    REDIS_API_HOST: z.string().optional(),
    REDIS_API_KEY: z.string().optional(),
    BRANCH:
      process.env.NODE_ENV !== "development"
        ? z.string()
        : z.string().optional().default("dev"),
    GIT_SHA: z.string().optional(),
    ENABLE_WARMUP_HOTEL: z
      .string()
      // only allow "true" or "false"
      .refine((s) => s === "true" || s === "false")
      // transform to boolean
      .transform((s) => s === "true")
      .default("true"),
    WARMUP_TOKEN: z.string().optional(),
    /**
     * Include the languages that should be hidden for the next release
     * Should be in the format of "en,da,de,fi,no,sv" or empty
     */
    NEW_SITE_LIVE_FOR_LANGS: z
      .string()
      .regex(/^([a-z]{2},)*([a-z]{2}){0,1}$/)
      .transform((val) => {
        return val.split(",")
      })
      .default(""),
    CAMPAIGN_PAGES_ENABLED: z
      .string()
      .refine((s) => s === "1" || s === "0")
      .transform((s) => s === "1")
      .default("0"),
  },
  emptyStringAsUndefined: true,
  runtimeEnv: {
    APPLICATION_INSIGHTS_CONNECTION_STRING:
      process.env.APPLICATION_INSIGHTS_CONNECTION_STRING,
    ADOBE_SCRIPT_SRC: process.env.ADOBE_SCRIPT_SRC,
    ADOBE_SDK_SCRIPT_SRC: process.env.ADOBE_SDK_SCRIPT_SRC,
    ENABLE_GTMSCRIPT: process.env.ENABLE_GTMSCRIPT,
    API_BASEURL: process.env.API_BASEURL,
    BUILD_ID: process.env.BUILD_ID,
    CMS_ACCESS_TOKEN: process.env.CMS_ACCESS_TOKEN,
    CMS_API_KEY: process.env.CMS_API_KEY,
    CMS_ENVIRONMENT: process.env.CMS_ENVIRONMENT,
    CMS_PREVIEW_TOKEN: process.env.CMS_PREVIEW_TOKEN,
    CMS_PREVIEW_URL: process.env.CMS_PREVIEW_URL,
    CMS_URL: process.env.CMS_URL,
    CMS_BRANCH: process.env.CMS_BRANCH,
    CURITY_CLIENT_ID_USER: process.env.CURITY_CLIENT_ID_USER,
    CURITY_CLIENT_ID_SERVICE: process.env.CURITY_CLIENT_ID_SERVICE,
    CURITY_CLIENT_SECRET_SERVICE: process.env.CURITY_CLIENT_SECRET_SERVICE,
    CURITY_CLIENT_SECRET_USER: process.env.CURITY_CLIENT_SECRET_USER,
    CURITY_ISSUER_USER: process.env.CURITY_ISSUER_USER,
    CURITY_ISSUER_SERVICE: process.env.CURITY_ISSUER_SERVICE,
    CYPRESS_BASE_URL: process.env.CYPRESS_TEST_URL,
    ENVTEST: process.env.ENVTEST,
    NEXTAUTH_DEBUG: process.env.NEXTAUTH_DEBUG,
    NEXTAUTH_REDIRECT_PROXY_URL: process.env.NEXTAUTH_REDIRECT_PROXY_URL,
    NEXTAUTH_SECRET: process.env.NEXTAUTH_SECRET,
    NEXTAUTH_URL: process.env.NEXTAUTH_URL,
    AUTH_URL: process.env.AUTH_URL,
    NODE_ENV: process.env.NODE_ENV,
    PRINT_QUERY: process.env.PRINT_QUERY,
    PUBLIC_URL: process.env.NEXT_PUBLIC_PUBLIC_URL,
    REVALIDATE_SECRET: process.env.REVALIDATE_SECRET,
    SITEMAP_SYNC_SECRET: process.env.SITEMAP_SYNC_SECRET,
    SALESFORCE_PREFERENCE_BASE_URL: process.env.SALESFORCE_PREFERENCE_BASE_URL,
    SEAMLESS_LOGIN_DA:
      process.env.SEAMLESS_LOGIN || process.env.SEAMLESS_LOGIN_DA,
    SEAMLESS_LOGIN_DE:
      process.env.SEAMLESS_LOGIN || process.env.SEAMLESS_LOGIN_DE,
    SEAMLESS_LOGIN_EN:
      process.env.SEAMLESS_LOGIN || process.env.SEAMLESS_LOGIN_EN,
    SEAMLESS_LOGIN_FI:
      process.env.SEAMLESS_LOGIN || process.env.SEAMLESS_LOGIN_FI,
    SEAMLESS_LOGIN_NO:
      process.env.SEAMLESS_LOGIN || process.env.SEAMLESS_LOGIN_NO,
    SEAMLESS_LOGIN_SV:
      process.env.SEAMLESS_LOGIN || process.env.SEAMLESS_LOGIN_SV,
    SEAMLESS_LOGOUT_DA:
      process.env.SEAMLESS_LOGOUT || process.env.SEAMLESS_LOGOUT_DA,
    SEAMLESS_LOGOUT_DE:
      process.env.SEAMLESS_LOGOUT || process.env.SEAMLESS_LOGOUT_DE,
    SEAMLESS_LOGOUT_EN:
      process.env.SEAMLESS_LOGOUT || process.env.SEAMLESS_LOGOUT_EN,
    SEAMLESS_LOGOUT_FI:
      process.env.SEAMLESS_LOGOUT || process.env.SEAMLESS_LOGOUT_FI,
    SEAMLESS_LOGOUT_NO:
      process.env.SEAMLESS_LOGOUT || process.env.SEAMLESS_LOGOUT_NO,
    SEAMLESS_LOGOUT_SV:
      process.env.SEAMLESS_LOGOUT || process.env.SEAMLESS_LOGOUT_SV,
    SHOW_SIGNUP_FLOW: process.env.SHOW_SIGNUP_FLOW,
    WEBVIEW_ENCRYPTION_KEY: process.env.WEBVIEW_ENCRYPTION_KEY,
    BOOKING_ENCRYPTION_KEY: process.env.BOOKING_ENCRYPTION_KEY,
    GOOGLE_STATIC_MAP_KEY: process.env.GOOGLE_STATIC_MAP_KEY,
    GOOGLE_STATIC_MAP_SIGNATURE_SECRET:
      process.env.GOOGLE_STATIC_MAP_SIGNATURE_SECRET,
    GOOGLE_STATIC_MAP_ID: process.env.GOOGLE_STATIC_MAP_ID,
    GOOGLE_DYNAMIC_MAP_ID: process.env.GOOGLE_DYNAMIC_MAP_ID,
    USE_NEW_REWARD_MODEL: process.env.USE_NEW_REWARD_MODEL,
    ENABLE_BOOKING_WIDGET: process.env.ENABLE_BOOKING_WIDGET,
    ENABLE_SURPRISES: process.env.ENABLE_SURPRISES,
    ENABLE_DTMC: process.env.ENABLE_DTMC,
    SHOW_SITE_WIDE_ALERT: process.env.SHOW_SITE_WIDE_ALERT,
    SENTRY_ENVIRONMENT: process.env.NEXT_PUBLIC_SENTRY_ENVIRONMENT,
    SENTRY_SERVER_SAMPLERATE: process.env.SENTRY_SERVER_SAMPLERATE,

    SAS_API_ENDPOINT: process.env.SAS_API_ENDPOINT,
    SAS_AUTH_ENDPOINT: process.env.SAS_AUTH_ENDPOINT,
    SAS_OCP_APIM: process.env.SAS_OCP_APIM,
    SAS_AUTH_CLIENTID: process.env.SAS_AUTH_CLIENTID,
    SAS_ENABLED: process.env.SAS,
    SAS_POINT_TRANSFER_ENABLED: process.env.SAS_POINT_TRANSFER_ENABLED,

    CACHE_TIME_HOTELS: process.env.CACHE_TIME_HOTELS,
    CACHE_TIME_CITY_SEARCH: process.env.CACHE_TIME_CITY_SEARCH,

    REDIS_API_HOST: process.env.REDIS_API_HOST,
    REDIS_API_KEY: process.env.REDIS_API_KEY,
    BRANCH: process.env.BRANCH,
    GIT_SHA: process.env.GIT_SHA,
    ENABLE_WARMUP_HOTEL: process.env.ENABLE_WARMUP_HOTEL,
    WARMUP_TOKEN: process.env.WARMUP_TOKEN,
    NEW_SITE_LIVE_FOR_LANGS: process.env.NEXT_PUBLIC_NEW_SITE_LIVE_FOR_LANGS,
    CAMPAIGN_PAGES_ENABLED: process.env.CAMPAIGN_PAGES_ENABLED,
  },
})

export const env = {
  ..._env,
  NEW_SITE_LIVE_STATUS: getLiveStatus(_env),
  isLangLive: (lang: Lang) => isLangLive(lang, _env.NEW_SITE_LIVE_FOR_LANGS),
} as const

function replaceTopLevelDomain(url: string, domain: string) {
  return url.replaceAll("{topleveldomain}", domain)
}
