'use client'

import type { ChangeEvent } from 'react'

import {
  DEFAULT_STOREFRONT_CURRENCY,
  type StoreCurrencyCode,
} from '@/plugins/ecommerce/currenciesConfig'
import { createUrl } from '@/utilities/createUrl'
import { isStoreCurrencyCode, normalizeStoreCurrencyCode } from '@/utilities/pricing'
import { useCart, useCurrency } from '@payloadcms/plugin-ecommerce/client/react'
import { usePathname, useRouter, useSearchParams } from 'next/navigation'
import { useEffect, useMemo } from 'react'
import { toast } from 'sonner'

const buildCurrencySearchParams = (
  searchParams: URLSearchParams,
  currencyCode: StoreCurrencyCode,
): URLSearchParams => {
  const nextParams = new URLSearchParams(searchParams.toString())

  if (currencyCode === DEFAULT_STOREFRONT_CURRENCY) {
    nextParams.delete('currency')
  } else {
    nextParams.set('currency', currencyCode)
  }

  nextParams.delete('maxPrice')
  nextParams.delete('minPrice')
  nextParams.delete('page')

  return nextParams
}

export function CurrencySelector() {
  const { cart } = useCart()
  const { currency, setCurrency, supportedCurrencies } = useCurrency()
  const pathname = usePathname()
  const router = useRouter()
  const searchParams = useSearchParams()
  const isShopRoute = pathname === '/shop'
  const selectedUrlCurrency = normalizeStoreCurrencyCode(searchParams.get('currency'))
  const cartItems = cart?.items || []
  const hasCartItems = cartItems.length > 0
  const cartCurrency =
    cart?.currency && isStoreCurrencyCode(cart.currency) ? cart.currency : undefined

  const activeCurrency = useMemo(() => {
    if (isShopRoute) {
      return selectedUrlCurrency
    }

    return normalizeStoreCurrencyCode(currency.code)
  }, [currency.code, isShopRoute, selectedUrlCurrency])

  useEffect(() => {
    if (!isShopRoute) {
      return
    }

    if (hasCartItems && cartCurrency && cartCurrency !== selectedUrlCurrency) {
      setCurrency(cartCurrency)
      router.replace(createUrl(pathname, buildCurrencySearchParams(searchParams, cartCurrency)), {
        scroll: false,
      })
      toast.warning(
        `Cart Anda masih memakai ${cartCurrency}. Kosongkan cart sebelum mengganti mata uang.`,
      )
      return
    }

    if (currency.code !== selectedUrlCurrency) {
      setCurrency(selectedUrlCurrency)
    }
  }, [
    cartCurrency,
    currency.code,
    hasCartItems,
    isShopRoute,
    pathname,
    router,
    searchParams,
    selectedUrlCurrency,
    setCurrency,
  ])

  const handleChange = (event: ChangeEvent<HTMLSelectElement>) => {
    const nextCurrency = normalizeStoreCurrencyCode(event.target.value)
    const currentCartCurrency = cartCurrency || normalizeStoreCurrencyCode(currency.code)

    if (hasCartItems && currentCartCurrency !== nextCurrency) {
      toast.warning(
        `Cart Anda masih memakai ${currentCartCurrency}. Kosongkan cart sebelum mengganti mata uang.`,
      )
      return
    }

    setCurrency(nextCurrency)

    if (isShopRoute) {
      router.push(createUrl(pathname, buildCurrencySearchParams(searchParams, nextCurrency)), {
        scroll: false,
      })
    }
  }

  return (
    <label className="hidden items-center gap-2 text-xs font-semibold text-muted-foreground md:inline-flex">
      <span className="sr-only">Currency</span>
      <select
        aria-label="Currency"
        className="h-9 rounded-full border border-border bg-background px-3 text-xs font-semibold text-primary shadow-none outline-none transition-colors hover:bg-muted focus-visible:ring-2 focus-visible:ring-ring"
        onChange={handleChange}
        value={activeCurrency}
      >
        {supportedCurrencies.map((supportedCurrency) => (
          <option key={supportedCurrency.code} value={supportedCurrency.code}>
            {supportedCurrency.code}
          </option>
        ))}
      </select>
    </label>
  )
}
