import { defineWidgetConfig } from "@medusajs/admin-sdk"
import { Container, Heading, Text, Button } from "@medusajs/ui"
import { useEffect, useMemo, useState } from "react"
import type { DetailWidgetProps, AdminProduct } from "@medusajs/framework/types"
import { toAbsoluteMediaUrl } from "../lib/media-url"
import Swal from "sweetalert2"
import { useTranslation } from "react-i18next"
import { normalizeValue, isContentEqual, deepClone } from "../lib/cms-utils"

const getFileTypeLabel = (filename: string, mimeType?: string) => {
  if (mimeType) return mimeType
  const ext = filename.split(".").pop()?.toLowerCase()
  if (!ext) return "unknown"
  return ext.toUpperCase()
}

const TechnicalSheetWidget = ({
  data: product,
}: DetailWidgetProps<AdminProduct>) => {
  const { t } = useTranslation()
  const [sheetUrl, setSheetUrl] = useState("")
  const [sheetFilename, setSheetFilename] = useState("")
  const [sheetType, setSheetType] = useState("")
  const [selectedFile, setSelectedFile] = useState<File | null>(null)
  const [lastSaved, setLastSaved] = useState<{ url: string; filename: string; type: string } | null>(null)
  const [isUploading, setIsUploading] = useState(false)
  const [isSaving, setIsSaving] = useState(false)

  useEffect(() => {
    const metadata = product?.metadata || {}

    const existingUrl =
      (typeof metadata.technical_sheet_url === "string" && metadata.technical_sheet_url) ||
      (typeof metadata.technical_sheet === "string" && metadata.technical_sheet) ||
      ""

    const existingFilename =
      (typeof metadata.technical_sheet_filename === "string" && metadata.technical_sheet_filename) ||
      ""

    const existingType =
      (typeof metadata.technical_sheet_type === "string" && metadata.technical_sheet_type) ||
      ""

    setSheetUrl(existingUrl)
    setSheetFilename(existingFilename)
    setSheetType(existingType)
    setLastSaved(normalizeValue({ url: existingUrl, filename: existingFilename, type: existingType }))
    setSelectedFile(null)
  }, [product])

  const previewUrl = useMemo(() => toAbsoluteMediaUrl(sheetUrl), [sheetUrl])

  const uploadFile = async (file: File) => {
    const dataUrl = await new Promise<string>((resolve, reject) => {
      const reader = new FileReader()
      reader.onload = () => resolve(String(reader.result || ""))
      reader.onerror = reject
      reader.readAsDataURL(file)
    })

    const uploadRes = await fetch("/admin/upload", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      credentials: "include",
      body: JSON.stringify({ file: dataUrl, filename: file.name }),
    })

    const uploadJson = await uploadRes.json()

    if (!uploadRes.ok || !uploadJson?.url) {
      throw new Error(uploadJson?.error || t("biomketProduct.technicalSheet.uploadFailed"))
    }

    return uploadJson.url as string
  }

  const handleSave = async () => {
    if (!product?.id) {
      await Swal.fire({
        icon: "error",
        title: t("biomketProduct.technicalSheet.swalProductMissingTitle"),
        text: t("biomketProduct.technicalSheet.swalProductMissingText"),
      })
      return
    }

    setIsSaving(true)

    try {
      let nextUrl = sheetUrl
      let nextFilename = sheetFilename
      let nextType = sheetType

      if (selectedFile) {
        setIsUploading(true)
        nextUrl = await uploadFile(selectedFile)
        nextFilename = selectedFile.name
        nextType = getFileTypeLabel(selectedFile.name, selectedFile.type)
        setIsUploading(false)
      }

      const updatedMetadata = {
        ...(product.metadata || {}),
        technical_sheet_url: nextUrl,
        technical_sheet_filename: nextFilename,
        technical_sheet_type: nextType,
      }

      const saveRes = await fetch(`/admin/products/${product.id}`, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        credentials: "include",
        body: JSON.stringify({ metadata: updatedMetadata }),
      })

      if (!saveRes.ok) {
        const err = await saveRes.json().catch(() => ({}))
        throw new Error(err?.message || t("biomketProduct.technicalSheet.saveFailed"))
      }

      setSheetUrl(nextUrl)
      setSheetFilename(nextFilename)
      setSheetType(nextType)
      setLastSaved(normalizeValue({ url: nextUrl, filename: nextFilename, type: nextType }))
      setSelectedFile(null)
      await Swal.fire({
        icon: "success",
        title: t("biomketProduct.technicalSheet.swalSavedTitle"),
        text: t("biomketProduct.technicalSheet.swalSavedText"),
        timer: 1800,
        showConfirmButton: false,
      })
    } catch (error) {
      console.error(error)
      await Swal.fire({
        icon: "error",
        title: t("biomketProduct.technicalSheet.swalSaveFailedTitle"),
        text: (error as Error).message || t("biomketProduct.technicalSheet.swalGenericError"),
      })
    } finally {
      setIsUploading(false)
      setIsSaving(false)
    }
  }

  const isBusy = isSaving || isUploading

  return (
    <Container className="p-6 mt-4">
      <Heading level="h2" className="mb-4">
        {t("biomketProduct.technicalSheet.title")}
      </Heading>

      <div className="flex flex-col gap-4">
        <div className="flex flex-col gap-2">
          <Text size="small" className="font-medium">
            {t("biomketProduct.technicalSheet.uploadLabel")}
          </Text>
          <input
            type="file"
            accept=".pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.txt"
            onChange={(e) => setSelectedFile(e.target.files?.[0] || null)}
            disabled={isBusy}
          />
          {selectedFile ? (
            <Text size="small" className="text-ui-fg-subtle">
              {t("biomketProduct.technicalSheet.selectedFile", { name: selectedFile.name })}
            </Text>
          ) : null}
        </div>

        {sheetUrl ? (
          <div className="flex items-center gap-3">
            <Button
              variant="secondary"
              size="small"
              onClick={() => window.open(previewUrl, "_blank", "noopener,noreferrer")}
              type="button"
            >
              {t("biomketProduct.technicalSheet.preview")}
            </Button>
            <Button
              variant="transparent"
              size="small"
              onClick={() => window.open(previewUrl, "_blank", "noopener,noreferrer")}
              type="button"
            >
              {t("biomketProduct.technicalSheet.download")}
            </Button>
            <Text size="small" className="text-ui-fg-subtle">
              {(sheetFilename || t("biomketProduct.technicalSheet.uploadedFileFallback")) +
                (sheetType ? ` (${sheetType})` : "")}
            </Text>
          </div>
        ) : (
          <Text size="small" className="text-ui-fg-subtle">
            {t("biomketProduct.technicalSheet.noFileYet")}
          </Text>
        )}

        <div className="flex justify-end mt-2">
          <Button 
            variant="primary" 
            isLoading={isBusy} 
            onClick={handleSave}
            disabled={!selectedFile && lastSaved !== null && isContentEqual({ url: sheetUrl, filename: sheetFilename, type: sheetType }, lastSaved)}
          >
            {t("biomketProduct.technicalSheet.saveButton")}
          </Button>
        </div>
      </div>
    </Container>
  )
}

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

export default TechnicalSheetWidget
