import { Select, Text } from "@medusajs/ui"
import { useQuery } from "@tanstack/react-query"
import { useEffect, useMemo, useState } from "react"
import { sdk } from "../lib/sdk"

type LocaleResponse = {
  locales?: Array<{
    code?: string
    is_enabled?: boolean
  }>
}

type StoreResponse = {
  stores?: Array<{
    metadata?: Record<string, unknown> | null
    supported_locales?: Array<{
      locale_code?: string
      locale?: {
        code?: string
        name?: string
      }
    }>
  }>
}

type LocaleConfigResponse = {
  locales: Array<{
    code: string
    name?: string
  }>
  defaultLocale: string
}

const STORAGE_KEY = "biomket.cms.selected-locale"
const DEFAULT_OPTION_VALUE = "__default__"

export function CmsLanguageDropdown() {
  const [selectedLocale, setSelectedLocale] = useState("")

  const { data, isLoading } = useQuery({
    queryKey: ["cms", "locale-config"],
    queryFn: async () => {
      const [localesResponse, storesResponse] = await Promise.all([
        sdk.fetch("/admin/locales", { method: "GET" }),
        sdk.fetch("/admin/stores", {
          method: "GET",
          query: {
            fields: "id,metadata,supported_locales.locale_code,supported_locales.locale.code,supported_locales.locale.name",
            limit: "1",
          },
        }),
      ])

      if (!localesResponse.ok || !storesResponse.ok) {
        throw new Error("Failed to load locale config")
      }

      const localesJson = (await localesResponse.json()) as LocaleResponse
      const storesJson = (await storesResponse.json()) as StoreResponse
      const allLocales = Array.isArray(localesJson.locales) ? localesJson.locales : []
      const store = storesJson.stores?.[0]
      const supportedLocales = Array.isArray(store?.supported_locales) ? store.supported_locales : []
      const metadata = (store?.metadata ?? {}) as Record<string, unknown>
      const defaultLocale = String(metadata.default_locale ?? "").trim()

      const localeNameByCode = new Map(
        supportedLocales
          .map((item) => {
            const code = String(item?.locale_code ?? item?.locale?.code ?? "").trim()
            const name = String(item?.locale?.name ?? code).trim()
            return [code, name] as const
          })
          .filter(([code]) => Boolean(code))
      )
      const supportedCodes = new Set([...localeNameByCode.keys()])

      const filteredLocales = allLocales
        .map((locale) => {
          const code = String(locale?.code ?? "").trim()
          return {
            code,
            name: localeNameByCode.get(code) ?? code,
            is_enabled: locale.is_enabled !== false,
          }
        })
        .filter((locale) => locale.code && supportedCodes.has(locale.code) && locale.is_enabled)

      return {
        locales: filteredLocales,
        defaultLocale,
      } as LocaleConfigResponse
    },
  })

  const locales = useMemo(() => {
    const rawLocales = Array.isArray(data?.locales) ? data.locales : []
    return rawLocales
      .map((locale) => ({
        code: String(locale.code ?? "").trim(),
        name: String(locale.name ?? locale.code ?? "").trim(),
      }))
      .filter((locale) => locale.code)
  }, [data])

  useEffect(() => {
    if (locales.length === 0) return

    const persisted = typeof window !== "undefined" ? window.localStorage.getItem(STORAGE_KEY) : ""
    const defaultLocale = String(data?.defaultLocale ?? "").trim()

    // Store locale setting is the source of truth for initial selection.
    // If "No default locale" is configured, force "Default" in CMS dropdown.
    const resolved = defaultLocale
      ? locales.find((locale) => locale.code === defaultLocale)?.code ||
        locales.find((locale) => locale.code === persisted)?.code ||
        defaultLocale
      : DEFAULT_OPTION_VALUE

    setSelectedLocale(resolved)
    if (typeof window !== "undefined") {
      window.localStorage.setItem(STORAGE_KEY, resolved)
      window.dispatchEvent(new CustomEvent("cms:locale-changed", { detail: { locale: resolved } }))
    }
  }, [data?.defaultLocale, locales])

  const onChange = (locale: string) => {
    setSelectedLocale(locale)
    if (typeof window !== "undefined") {
      window.localStorage.setItem(STORAGE_KEY, locale)
      window.dispatchEvent(new CustomEvent("cms:locale-changed", { detail: { locale } }))
    }
  }

  return (
    <div className="mb-4 flex items-center justify-end gap-2">
      <Text size="small" className="text-ui-fg-subtle">
        Language
      </Text>
      <Select
        size="small"
        value={selectedLocale}
        onValueChange={onChange}
        disabled={isLoading || locales.length === 0}
      >
        <Select.Trigger className="w-[200px]">
          <Select.Value placeholder={isLoading ? "Loading..." : "Select language"} />
        </Select.Trigger>
        <Select.Content>
          <Select.Item value={DEFAULT_OPTION_VALUE}>Default</Select.Item>
          {locales.map((locale) => (
            <Select.Item key={locale.code} value={locale.code}>
              {locale.name} ({locale.code})
            </Select.Item>
          ))}
        </Select.Content>
      </Select>
    </div>
  )
}
