import { defineRouteConfig } from "@medusajs/admin-sdk"
import { Container, Heading, Button, Input, Label, Hint } from "@medusajs/ui"
import { useState, useEffect } from "react"
import { useMutation, useQuery } from "@tanstack/react-query"
import { useNavigate } from "react-router-dom"
import { sdk } from "../../../../lib/sdk"
import { CmsLanguageDropdown } from "../../../../components/CmsLanguageDropdown"

export const config = defineRouteConfig({})

const UNIQUE_NAME_HINT = "Auto-generated from Display Name. Must be unique; if it matches an existing type, enter a unique name."
const UNIQUE_DISPLAY_HINT = "Shown in the UI; can be changed later."

function slugifyApiKey(text: string): string {
  return text
    .trim()
    .toLowerCase()
    .replace(/\s+/g, "_")
    .replace(/[^a-z0-9_]/g, "")
    .replace(/_+/g, "_")
    .replace(/^_|_$/g, "") || ""
}

export default function NewComponentType() {
  const navigate = useNavigate()
  const [name, setName] = useState("")
  const [displayName, setDisplayName] = useState("")
  const [nameManuallyEdited, setNameManuallyEdited] = useState(false)
  const [description, setDescription] = useState("")
  const [reusable, setReusable] = useState(false)
  const [repeatable, setRepeatable] = useState(false)
  const [folderId, setFolderId] = useState<string | null>(null)
  const [error, setError] = useState<string | null>(null)

  const { data: foldersData } = useQuery({
    queryKey: ["component-folders"],
    queryFn: async () => {
      const r = await sdk.fetch("/admin/component-folders")
      if (!r.ok) throw new Error("Failed")
      return r.json() as Promise<{ component_folders: { id: string; name: string }[] }>
    },
  })
  const folders = foldersData?.component_folders ?? []

  const { data: typesData } = useQuery({
    queryKey: ["component-types"],
    queryFn: async () => {
      const r = await sdk.fetch("/admin/component-types")
      if (!r.ok) throw new Error("Failed")
      return r.json() as Promise<{ component_types: { name: string }[]; is_production_mode?: boolean }>
    },
  })
  const existingNames = new Set((typesData?.component_types ?? []).map((t) => t.name))
  // const isProductionMode = Boolean(typesData?.is_production_mode)
  const isProductionMode = false
  const nameExists = name.trim() !== "" && existingNames.has(name.trim())
  const nameConflictMessage = nameExists ? "This name is already used. Please enter a unique name." : null

  useEffect(() => {
    if (!nameManuallyEdited && displayName.trim()) {
      setName(slugifyApiKey(displayName))
    }
  }, [displayName, nameManuallyEdited])

  const create = useMutation({
    mutationFn: async () => {
      setError(null)
      const nameToUse = (name || slugifyApiKey(displayName) || "block").trim()
      if (existingNames.has(nameToUse)) {
        throw new Error("This name is already used. Please enter a unique name.")
      }
      const r = await sdk.fetch("/admin/component-types", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          name: nameToUse || "block",
          display_name: displayName || "Block",
          description: description || null,
          reusable,
          repeatable,
          folder_id: folderId || null,
        }),
      })
      const text = await r.text()
      if (!r.ok) throw new Error(text || "Create failed")
      return JSON.parse(text) as { component_type: { id: string } }
    },
    onSuccess: (d) => {
      navigate(`/component-builder/types/${d.component_type.id}`)
    },
    onError: (e: Error) => {
      const msg = e.message || "Failed to create"
      setError(msg.includes("unique") || msg.includes("duplicate") || msg.includes("already used")
        ? "A component type with this name already exists. Please enter a unique name."
        : msg)
    },
  })

  return (
    <Container className="px-3 sm:px-4">
      <CmsLanguageDropdown />
      <Heading level="h1" className="mb-4 sm:mb-6 text-xl sm:text-2xl">New Component Type</Heading>
      <div className="flex flex-col gap-4 w-full max-w-md">
        {isProductionMode && (
          <div className="p-3 rounded border border-ui-border-base bg-ui-bg-subtle text-sm text-ui-fg-subtle">
            Production mode is active. Component types are view-only, so new types cannot be created.
          </div>
        )}
        {error && (
          <div className="p-3 rounded bg-red-100 text-red-800 text-sm" role="alert">
            {error}
          </div>
        )}
        <div className="min-w-0">
          <Label>Display name</Label>
          <Input
            value={displayName}
            disabled={isProductionMode}
            readOnly={isProductionMode}
            onChange={(e) => setDisplayName(e.target.value)}
            placeholder="e.g. Hero Banner"
            className="w-full"
          />
          <Hint className="mt-1">{UNIQUE_DISPLAY_HINT}</Hint>
        </div>
        <div className="min-w-0">
          <Label>Name (API key) — unique</Label>
          <Input
            value={name}
            disabled={isProductionMode}
            readOnly={isProductionMode}
            onChange={(e) => {
              setName(e.target.value.replace(/\s/g, "_").toLowerCase())
              setNameManuallyEdited(true)
            }}
            placeholder="e.g. hero_banner, product_grid"
            className="w-full"
          />
          <Hint className="mt-1">{UNIQUE_NAME_HINT}</Hint>
          {nameConflictMessage && (
            <p className="mt-1 text-red-600 text-sm" role="alert">{nameConflictMessage}</p>
          )}
        </div>
        <div className="min-w-0">
          <Label>Description</Label>
          <Input value={description} disabled={isProductionMode} readOnly={isProductionMode} onChange={(e) => setDescription(e.target.value)} placeholder="Optional description" className="w-full" />
        </div>
        <div className="min-w-0">
          <Label>Folder</Label>
          <select
            value={folderId ?? ""}
            disabled={isProductionMode}
            onChange={(e) => setFolderId(e.target.value || null)}
            className="border rounded px-3 py-2 w-full bg-ui-bg-field border-ui-border-base"
          >
            <option value="">Root (no folder)</option>
            {folders.map((f) => (
              <option key={f.id} value={f.id}>{f.name}</option>
            ))}
          </select>
          <Hint className="mt-1">Create this component type in the root or inside a folder.</Hint>
        </div>
        <label className="flex items-center gap-2">
          <input type="checkbox" checked={reusable} onChange={(e) => setReusable(e.target.checked)} disabled={isProductionMode} />
          <span>Reusable</span>
        </label>
        <label className="flex items-center gap-2">
          <input type="checkbox" checked={repeatable} onChange={(e) => setRepeatable(e.target.checked)} disabled={isProductionMode} />
          <span>Repeatable</span>
        </label>
        <div className="flex flex-col sm:flex-row gap-2">
          <Button onClick={() => create.mutate()} disabled={isProductionMode || create.isPending || nameExists} className="w-full sm:w-auto">Create</Button>
          <Button variant="secondary" onClick={() => navigate("/component-builder")} className="w-full sm:w-auto">Cancel</Button>
        </div>
      </div>
    </Container>
  )
}
