import { defineRouteConfig } from "@medusajs/admin-sdk"
import { Button, Container, RadioGroup, Text, toast } from "@medusajs/ui"
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"
import { useMemo, useState } from "react"
import { sdk } from "../../lib/sdk"
import { useTranslation } from "react-i18next"

type LocaleRecord = {
  code: string
  name: string
  is_default: boolean
  is_enabled: boolean
}

type LocaleResponse = {
  locales?: LocaleRecord[]
}

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

const localesQueryKey = ["admin", "locales"]
const NO_DEFAULT_VALUE = "__none__"

export const config = defineRouteConfig({
  label: "adminRoutes.locales.title",
  translationNs: "translation",
})

async function parseJsonOrThrow(response: Response) {
  const text = await response.text()
  if (!response.ok) {
    let message = text || "Request failed."
    try {
      const json = JSON.parse(text)
      if (json?.message) message = json.message
    } catch {
      // use text fallback
    }
    throw new Error(message)
  }
  return text ? JSON.parse(text) : {}
}

export default function LocalesPage() {
  const { t } = useTranslation()
  const queryClient = useQueryClient()
  const [selectedCode, setSelectedCode] = useState<string>("")

  const localesQuery = useQuery({
    queryKey: localesQueryKey,
    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",
            limit: "1",
          },
        }),
      ])
      const localesJson = (await parseJsonOrThrow(localesResponse)) as LocaleResponse
      const storesJson = (await parseJsonOrThrow(storesResponse)) as StoreResponse
      const locales = Array.isArray(localesJson.locales) ? localesJson.locales : []
      const supportedLocales = Array.isArray(storesJson.stores?.[0]?.supported_locales)
        ? storesJson.stores?.[0]?.supported_locales
        : []
      const storeId = String(storesJson.stores?.[0]?.id ?? "")
      const metadata = (storesJson.stores?.[0]?.metadata ?? {}) as Record<string, unknown>
      const defaultLocaleFromMetadata = String(metadata?.default_locale ?? "").trim()
      const activeCodes = new Set(
        supportedLocales
          .map((item) => String(item?.locale_code ?? item?.locale?.code ?? "").trim())
          .filter(Boolean)
      )
      const normalizedLocales = locales
        .map((locale) => ({
          code: String(locale.code ?? "").trim(),
          name: String(locale.name ?? locale.code ?? "").trim(),
          is_default: false,
          // /admin/locales may omit is_enabled for built-in translation locales.
          // Treat omitted as enabled so configured locales are still shown here.
          is_enabled: locale.is_enabled !== false,
        }))
        .filter((locale) => locale.code && activeCodes.has(locale.code))
        .sort((a, b) => a.code.localeCompare(b.code))

      return {
        locales: normalizedLocales.map((locale) => ({
          ...locale,
          is_default: locale.code === defaultLocaleFromMetadata,
        })),
        storeId,
        storeMetadata: metadata,
      }
    },
  })

  const locales = localesQuery.data?.locales ?? []
  const storeId = localesQuery.data?.storeId ?? ""
  const storeMetadata = localesQuery.data?.storeMetadata ?? {}

  const currentDefaultCode = useMemo(
    () => locales.find((locale) => locale.is_default)?.code ?? "",
    [locales]
  )

  const effectiveSelection = selectedCode || currentDefaultCode || NO_DEFAULT_VALUE

  const setDefaultMutation = useMutation({
    mutationFn: async (targetCode: string) => {
      const normalizedTargetCode = targetCode === NO_DEFAULT_VALUE ? "" : targetCode
      if (!storeId) {
        throw new Error(t("adminRoutes.locales.storeNotFound"))
      }

      await sdk.fetch(`/admin/stores/${storeId}`, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          metadata: {
            ...storeMetadata,
            default_locale: normalizedTargetCode || null,
          },
        }),
      }).then(parseJsonOrThrow)
    },
    onSuccess: () => {
      toast.success(t("adminRoutes.locales.saveSuccess"))
      setSelectedCode("")
      queryClient.invalidateQueries({ queryKey: localesQueryKey })
    },
    onError: (error: Error) => {
      toast.error(error.message || t("adminRoutes.locales.saveError"))
    },
  })

  return (
    <Container className="px-6 py-4">
      <div className="flex items-center justify-between gap-3">
        <div>
          <Text size="xlarge" weight="plus">
            {t("adminRoutes.locales.title")}
          </Text>
          <Text size="small" className="text-ui-fg-subtle">
            {t("adminRoutes.locales.subtitle")}
          </Text>
        </div>
      </div>

      <div className="mt-6 rounded-lg border border-ui-border-base p-5">
        {localesQuery.isLoading ? (
          <Text size="small" className="text-ui-fg-subtle">
            {t("adminRoutes.locales.loading")}
          </Text>
        ) : null}

        {localesQuery.isError ? (
          <Text size="small" className="text-ui-fg-error">
            {(localesQuery.error as Error)?.message || t("adminRoutes.locales.loadError")}
          </Text>
        ) : null}

        {!localesQuery.isLoading && !localesQuery.isError && locales.length === 0 ? (
          <Text size="small" className="text-ui-fg-subtle">
            {t("adminRoutes.locales.empty")}
          </Text>
        ) : null}

        {!localesQuery.isLoading && !localesQuery.isError && locales.length > 0 ? (
          <>
            <RadioGroup
              value={effectiveSelection}
              onValueChange={(value) => setSelectedCode(String(value))}
            >
              <div className="flex flex-col gap-3">
                <div className="flex items-center justify-between rounded-md border border-ui-border-base px-3 py-2">
                  <div>
                    <Text weight="plus">{t("adminRoutes.locales.noDefaultTitle")}</Text>
                    <Text size="small" className="text-ui-fg-subtle">
                      {t("adminRoutes.locales.noDefaultSubtitle")}
                    </Text>
                  </div>
                  <RadioGroup.Item value={NO_DEFAULT_VALUE} />
                </div>
                {locales.map((locale) => (
                  <div
                    key={locale.code}
                    className="flex items-center justify-between rounded-md border border-ui-border-base px-3 py-2"
                  >
                    <div>
                      <Text weight="plus">
                        {locale.name} ({locale.code})
                      </Text>
                      <Text size="small" className="text-ui-fg-subtle">
                        {locale.is_enabled ? t("adminRoutes.locales.enabled") : t("adminRoutes.locales.disabled")}
                      </Text>
                    </div>
                    <RadioGroup.Item value={locale.code} />
                  </div>
                ))}
              </div>
            </RadioGroup>

            <div className="mt-4 flex justify-end">
              <Button
                size="small"
                variant="secondary"
                onClick={() => setDefaultMutation.mutate(effectiveSelection)}
                disabled={effectiveSelection === (currentDefaultCode || NO_DEFAULT_VALUE)}
                isLoading={setDefaultMutation.isPending}
              >
                {t("adminRoutes.locales.save")}
              </Button>
            </div>
          </>
        ) : null}
      </div>
    </Container>
  )
}
