import { defineWidgetConfig } from "@medusajs/admin-sdk"
import { Button, Container, Input, Text, Textarea, toast } from "@medusajs/ui"
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"
import { useEffect, useState } from "react"
import { sdk } from "../lib/sdk"
import { useTranslation } from "react-i18next"
import { normalizeValue, isContentEqual, deepClone } from "../lib/cms-utils"

type SeoFieldState = {
  title: string
  description: string
  keywords: string
}

const INITIAL_FIELDS: SeoFieldState = {
  title: "",
  description: "",
  keywords: "",
}

const findMetadataValue = (
  metadata: Record<string, unknown> | null | undefined,
  keys: string[]
) => {
  if (!metadata) {
    return ""
  }

  const matchedKey = Object.keys(metadata).find((key) =>
    keys.some((candidate) => key.toLowerCase() === candidate.toLowerCase())
  )

  if (!matchedKey) {
    return ""
  }

  const value = metadata[matchedKey]
  return typeof value === "string" ? value : ""
}

const withoutMetadataKeys = (
  metadata: Record<string, unknown>,
  keys: string[]
) => {
  return Object.fromEntries(
    Object.entries(metadata).filter(
      ([key]) =>
        !keys.some((candidate) => key.toLowerCase() === candidate.toLowerCase())
    )
  )
}

const SeoWidget = ({ data }: { data: { id: string } }) => {
  const { t } = useTranslation()
  const queryClient = useQueryClient()
  const [fields, setFields] = useState(INITIAL_FIELDS)
  const [lastSaved, setLastSaved] = useState<SeoFieldState | null>(null)

  const productQuery = useQuery({
    queryKey: ["admin", "product-seo", data.id],
    queryFn: async () => {
      const response = await sdk.fetch(`/admin/products/${data.id}`)

      if (!response.ok) {
        throw new Error(t("biomketProduct.seo.loadError"))
      }

      return (await response.json()) as { product?: { id: string; metadata?: Record<string, unknown> | null } }
    },
  })

  useEffect(() => {
    const product = productQuery.data?.product
    if (!product) {
      return
    }

    const metadata = product.metadata || {}

    const next = {
      title: findMetadataValue(metadata, ["seo_title", "seo title"]),
      description: findMetadataValue(metadata, ["seo_description", "seo description"]),
      keywords: findMetadataValue(metadata, ["seo_keywords", "seo keywords"]),
    }
    setFields(next)
    setLastSaved(normalizeValue(next))
  }, [productQuery.data])

  const saveMutation = useMutation({
    mutationFn: async (payload: SeoFieldState) => {
      const currentMetadata = productQuery.data?.product?.metadata || {}
      const baseMetadata = withoutMetadataKeys(currentMetadata, [
        "seo_title",
        "seo title",
        "seo_description",
        "seo description",
        "seo_keywords",
        "seo keywords",
      ])

      const nextMetadata = {
        ...baseMetadata,
        seo_title: payload.title,
        seo_description: payload.description,
        seo_keywords: payload.keywords,
      }

      console.log("Saving SEO metadata:", nextMetadata)

      const response = await sdk.fetch(`/admin/products/${data.id}`, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          metadata: nextMetadata,
        }),
      })

      console.log("Save response status:", response.status)

      if (!response.ok) {
        const error = await response.text()
        console.error("Save error:", error)
        throw new Error(error || t("biomketProduct.seo.saveError"))
      }

      const result = await response.json()
      console.log("Save result:", result)

      return payload
    },
    onSuccess: (payload) => {
      console.log("Save success, updating cache:", payload)
      queryClient.setQueryData(
        ["admin", "product-seo", data.id],
        (current: { product?: { id: string; metadata?: Record<string, unknown> | null } } | undefined) => ({
          product: {
            id: current?.product?.id || data.id,
            metadata: {
              ...(current?.product?.metadata || {}),
              seo_title: payload.title,
              seo_description: payload.description,
              seo_keywords: payload.keywords,
            },
          },
        })
      )
      toast.success(t("biomketProduct.seo.saveSuccess"))
      setLastSaved(normalizeValue(payload))
      queryClient.invalidateQueries({
        queryKey: ["admin", "product-seo", data.id],
      })
    },
    onError: (error: Error) => {
      console.error("Save mutation error:", error)
      toast.error(error.message || t("biomketProduct.seo.saveError"))
    },
  })

  if (productQuery.isLoading) {
    return (
      <Container className="px-6 py-4">
        <Text size="small" leading="compact" className="text-ui-fg-subtle">
          {t("biomketProduct.seo.loading")}
        </Text>
      </Container>
    )
  }

  if (productQuery.isError) {
    return (
      <Container className="px-6 py-4">
        <Text size="small" leading="compact" className="text-ui-fg-error">
          {t("biomketProduct.seo.loadError")}
        </Text>
      </Container>
    )
  }

  return (
    <Container className="px-6 py-4">
      <div className="flex flex-col gap-y-1">
        <Text size="large" leading="compact" weight="plus">
          {t("biomketProduct.seo.title")}
        </Text>
        <Text size="small" leading="compact" className="text-ui-fg-subtle">
          {t("biomketProduct.seo.subtitle")}
        </Text>
      </div>

      <div className="mt-4 flex flex-col gap-y-4">
        <div className="flex flex-col gap-y-2">
          <Text size="small" leading="compact" weight="plus">
            {t("biomketProduct.seo.fieldTitle")}
          </Text>
          <Input
            value={fields.title}
            placeholder={t("biomketProduct.seo.fieldTitlePlaceholder")}
            onChange={(event) =>
              setFields((current) => ({
                ...current,
                title: event.target.value,
              }))
            }
          />
        </div>

        <div className="flex flex-col gap-y-2">
          <Text size="small" leading="compact" weight="plus">
            {t("biomketProduct.seo.fieldDescription")}
          </Text>
          <Textarea
            value={fields.description}
            placeholder={t("biomketProduct.seo.fieldDescriptionPlaceholder")}
            onChange={(event) =>
              setFields((current) => ({
                ...current,
                description: event.target.value,
              }))
            }
            rows={3}
          />
        </div>

        <div className="flex flex-col gap-y-2">
          <Text size="small" leading="compact" weight="plus">
            {t("biomketProduct.seo.fieldKeywords")}
          </Text>
          <Input
            value={fields.keywords}
            placeholder={t("biomketProduct.seo.fieldKeywordsPlaceholder")}
            onChange={(event) =>
              setFields((current) => ({
                ...current,
                keywords: event.target.value,
              }))
            }
          />
          <Text size="small" className="text-ui-fg-subtle">
            {t("biomketProduct.seo.keywordsHint")}
          </Text>
        </div>
      </div>

      <div className="mt-6 flex justify-end">
        <Button
          size="small"
          isLoading={saveMutation.isPending}
          disabled={lastSaved !== null && isContentEqual(fields, lastSaved)}
          onClick={() =>
            saveMutation.mutate(fields)
          }
        >
          {t("biomketProduct.common.save")}
        </Button>
      </div>
    </Container>
  )
}

export const config = defineWidgetConfig({
  zone: "product.details.side.after",
})

export default SeoWidget
