"use client"

import * as Sentry from "@sentry/nextjs"
import { useParams, useRouter, useSearchParams } from "next/navigation"
import { startTransition, useEffect, useRef } from "react"
import { useIntl } from "react-intl"

import { login } from "@scandic-hotels/common/constants/routes/handleAuth"
import { logger } from "@scandic-hotels/common/logger"
import { Typography } from "@scandic-hotels/design-system/Typography"
import { SESSION_EXPIRED } from "@scandic-hotels/trpc/errors"

import { env } from "@/env/client"

import styles from "./error.module.css"

import type { LangParams } from "@/types/params"

export default function Error({
  error,
  reset,
}: {
  error: Error & { digest?: string }
  reset: () => void
}) {
  const intl = useIntl()
  const params = useParams<LangParams>()
  const router = useRouter()
  const searchParams = useSearchParams()
  const currentSearchParamsRef = useRef<string>(undefined)
  const isFirstLoadRef = useRef<boolean>(true)

  useEffect(() => {
    if (!error) return

    if (error.message === SESSION_EXPIRED) {
      const loginUrl = login[params.lang]
      window.location.assign(loginUrl)
      return
    }

    logger.error("(live)/error", error)
    Sentry.captureException(error, { extra: { digest: error.digest } })
  }, [error, params.lang])

  useEffect(() => {
    // This is to reset the error and refresh the page when the search params change, to support the booking widget that is using router.push to navigate to the booking flow page
    const currentSearchParams = searchParams.toString()

    if (
      currentSearchParamsRef.current !== currentSearchParams &&
      !isFirstLoadRef.current
    ) {
      startTransition(() => {
        reset()
        router.refresh()
      })
    }
    isFirstLoadRef.current = false
    currentSearchParamsRef.current = currentSearchParams
  }, [searchParams, reset, router])

  return (
    <div className={styles.container}>
      <Typography variant="Title/md" className={styles.header}>
        <h1>
          {intl.formatMessage({
            id: "errorMessage.somethingWentWrong",
            defaultMessage: "Something went wrong!",
          })}
        </h1>
      </Typography>
      <div>
        <Typography variant="Body/Paragraph/mdRegular" className={styles.text}>
          <p>
            {intl.formatMessage({
              id: "errorMessage.somethingWentWrong.message",
              defaultMessage:
                "Please try refreshing the page or come back later. If the problem persists, please contact support.",
            })}
          </p>
        </Typography>
      </div>
      {error.digest && (
        <Typography
          variant="Body/Supporting text (caption)/smRegular"
          className={styles.digest}
        >
          {/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
          <p>Error reference ID: {error.digest}</p>
        </Typography>
      )}
      {env.NEXT_PUBLIC_SENTRY_ENVIRONMENT !== "production" && (
        <pre className={styles.errorDetails}>
          {error.message && <div>{error.message}</div>}
          {error.stack && <span>{error.stack}</span>}
        </pre>
      )}
    </div>
  )
}
