import { defineRouteConfig } from "@medusajs/admin-sdk"
import { Container, Heading, Button, Input, Label, Hint, Text } from "@medusajs/ui"
import { useState } from "react"
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query"
import { useNavigate } from "react-router-dom"
import { PuzzleSolid } from "@medusajs/icons"
import { sdk } from "../../lib/sdk"
import { showConfirm } from "../../lib/confirm"
import { isDevOnlyFeaturesEnabled } from "../../lib/feature-flags"
import { CmsLanguageDropdown } from "../../components/CmsLanguageDropdown"

export const config = isDevOnlyFeaturesEnabled ? defineRouteConfig({
  label: "adminRoutes.cms.componentTypes",
  translationNs: "translation",
  icon: PuzzleSolid,
  rank: 51,
}) : undefined

type ComponentType = { id: string; name: string; display_name: string; reusable: boolean; repeatable: boolean; folder_id?: string | null; usage_count?: number }
type ComponentFolder = { id: string; name: string }
type ComponentTypesResponse = { component_types: ComponentType[]; is_production_mode?: boolean }

export default function ComponentBuilderList() {
  // Hide entire route in production
  if (!isDevOnlyFeaturesEnabled) {
    return null
  }
  const navigate = useNavigate()
  const qc = useQueryClient()
  const [newFolderName, setNewFolderName] = useState("")
  const [showNewFolder, setShowNewFolder] = useState(false)
  const [folderError, setFolderError] = useState<string | null>(null)
  const [typeError, setTypeError] = useState<string | null>(null)

  const { data, isLoading } = 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<ComponentTypesResponse>
    },
  })
  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: ComponentFolder[] }>
    },
  })

  const types = data?.component_types ?? []
  // TEMPORARY: Disabled production mode check for editing
  // const isProductionMode = Boolean(data?.is_production_mode)
  const isProductionMode = false
  const folders = foldersData?.component_folders ?? []
  const rootTypes = types.filter((t) => !t.folder_id)
  const typesByFolder = folders.map((f) => ({ folder: f, types: types.filter((t) => t.folder_id === f.id) }))

  const del = useMutation({
    mutationFn: async (id: string) => {
      const r = await sdk.fetch(`/admin/component-types/${id}`, { method: "DELETE" })
      const text = await r.text()
      if (!r.ok) {
        let msg = text
        try { const j = JSON.parse(text); if (j.message) msg = j.message } catch { /* ignore */ }
        throw new Error(msg)
      }
    },
    onSuccess: () => {
      setTypeError(null)
      qc.invalidateQueries({ queryKey: ["component-types"] })
    },
    onError: (e: Error) => setTypeError(e.message),
  })

  const createFolder = useMutation({
    mutationFn: async (name: string) => {
      const r = await sdk.fetch("/admin/component-folders", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ name: name.trim() }),
      })
      if (!r.ok) throw new Error(await r.text())
    },
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ["component-folders"] })
      setNewFolderName("")
      setShowNewFolder(false)
    },
  })

  const deleteFolder = useMutation({
    mutationFn: async (folderId: string) => {
      const r = await sdk.fetch(`/admin/component-folders/${folderId}`, { method: "DELETE" })
      if (!r.ok) {
        const text = await r.text()
        let msg = text
        try { const j = JSON.parse(text); if (j.message) msg = j.message } catch { /* ignore */ }
        throw new Error(msg)
      }
    },
    onSuccess: () => {
      setFolderError(null)
      qc.invalidateQueries({ queryKey: ["component-folders"] })
      qc.invalidateQueries({ queryKey: ["component-types"] })
    },
    onError: (e: Error) => setFolderError(e.message),
  })

  const renderTypeList = (list: ComponentType[]) => (
    <ul className="divide-y">
      {list.map((t) => (
        <li key={t.id} className="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-2 py-3 min-w-0">
          <div className="min-w-0 flex-1">
            <span className="font-medium block sm:inline">{t.display_name}</span>
            <span className="text-ui-fg-subtle text-sm ml-0 sm:ml-2 block sm:inline">({t.name})</span>
            <span className="text-xs text-ui-fg-muted block sm:inline sm:ml-2">
              {t.reusable && "reusable "}
              {t.repeatable && "repeatable "}
              {typeof t.usage_count === "number" && t.usage_count > 0
                ? `· Used in ${t.usage_count} place${t.usage_count === 1 ? "" : "s"}`
                : "· Not used"}
            </span>
          </div>
          {!isProductionMode && (
            <div className="flex gap-2 flex-shrink-0">
              <Button size="small" variant="secondary" onClick={() => navigate(`/component-builder/types/${t.id}`)}>Edit</Button>
              <Button size="small" variant="secondary" onClick={() => { setTypeError(null); showConfirm({ title: "Delete component type?", text: "This cannot be undone." }).then((r) => r.isConfirmed && del.mutate(t.id)); }}>Delete</Button>
            </div>
          )}
        </li>
      ))}
    </ul>
  )

  return (
    <Container className="px-3 sm:px-4 overflow-x-hidden">
      <CmsLanguageDropdown />
      <div className="flex flex-col sm:flex-row sm:justify-between sm:items-center py-4 sm:py-6 gap-4 sm:gap-2">
        <Heading level="h1" className="text-xl sm:text-2xl truncate min-w-0">Component Types</Heading>
        <div className="flex gap-2 flex-wrap">
          <Button variant="secondary" onClick={() => setShowNewFolder(true)} className="flex-1 sm:flex-none" disabled={isProductionMode}>New folder</Button>
          <Button onClick={() => navigate("/component-builder/types/new")} className="flex-1 sm:flex-none" disabled={isProductionMode}>New Type</Button>
        </div>
      </div>

      {isProductionMode && (
        <div className="mb-4 rounded-lg border border-ui-border-base bg-ui-bg-subtle p-3">
          <Text size="small" className="text-ui-fg-subtle">
            Production mode is active. Component types are view-only, so create, edit, reorder, and delete actions are disabled.
          </Text>
        </div>
      )}

      {showNewFolder && (
        <div className="mb-6 sm:mb-8 p-4 sm:p-6 rounded-lg border border-ui-border-base bg-ui-bg-subtle shadow-sm w-full max-w-md">
          <Heading level="h2" className="text-base font-semibold mb-1">Create new folder</Heading>
          <p className="text-ui-fg-subtle text-sm mb-4">Organize component types into folders. Choose a name that helps you find them later (e.g. &quot;Hero blocks&quot;, &quot;Product components&quot;).</p>
          <div className="space-y-2 mb-4">
            <Label htmlFor="new-folder-name">Folder name</Label>
            <Input
              id="new-folder-name"
              value={newFolderName}
              onChange={(e) => setNewFolderName(e.target.value)}
              placeholder="e.g. Hero blocks"
              onKeyDown={(e) => {
                if (e.key === "Enter") newFolderName.trim() && createFolder.mutate(newFolderName)
                if (e.key === "Escape") { setShowNewFolder(false); setNewFolderName("") }
              }}
            />
            <Hint>This name is shown in the component list and when creating new types.</Hint>
          </div>
          <div className="flex flex-col sm:flex-row gap-2">
            <Button
              onClick={() => newFolderName.trim() && createFolder.mutate(newFolderName)}
              disabled={createFolder.isPending || !newFolderName.trim()}
              className="w-full sm:w-auto"
            >
              {createFolder.isPending ? "Creating…" : "Create folder"}
            </Button>
            <Button
              variant="secondary"
              onClick={() => { setShowNewFolder(false); setNewFolderName("") }}
              disabled={createFolder.isPending}
              className="w-full sm:w-auto"
            >
              Cancel
            </Button>
          </div>
        </div>
      )}
      {folderError && <div className="mb-4 p-3 rounded bg-red-100 text-red-800 text-sm">{folderError}</div>}
      {typeError && <div className="mb-4 p-3 rounded bg-red-100 text-red-800 text-sm">{typeError}</div>}
      {isLoading && <p className="text-ui-fg-subtle">Loading...</p>}
      {!isLoading && types.length === 0 && folders.length === 0 && (
        <p className="text-ui-fg-subtle py-8">No component types or folders. Create a folder or a component type to get started.</p>
      )}
      {!isLoading && (rootTypes.length > 0 || typesByFolder.some((g) => g.types.length > 0) || folders.length > 0) && (
        <div className="space-y-6">
          <section className="rounded-lg border border-ui-border-base bg-ui-bg-base p-3 sm:p-4 overflow-hidden">
            <h2 className="text-base sm:text-lg font-semibold text-ui-fg-base mb-2">Root</h2>
            {rootTypes.length > 0 ? renderTypeList(rootTypes) : <p className="text-ui-fg-subtle text-sm py-2">No component types in root.</p>}
          </section>
          {typesByFolder.map(({ folder, types: folderTypes }) => (
            <section key={folder.id} className="rounded-lg border border-ui-border-base bg-ui-bg-base p-3 sm:p-4 overflow-hidden">
              <div className="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-2 mb-2">
                <h2 className="text-base sm:text-lg font-semibold text-ui-fg-base min-w-0 truncate">{folder.name}</h2>
                {!isProductionMode && (
                  <Button
                    size="small"
                    variant="secondary"
                    onClick={() => { setFolderError(null); showConfirm({ title: "Delete folder?", text: "Component types in it must be moved or deleted first." }).then((r) => r.isConfirmed && deleteFolder.mutate(folder.id)); }}
                    disabled={deleteFolder.isPending}
                    className="w-full sm:w-auto flex-shrink-0"
                  >
                    Delete folder
                  </Button>
                )}
              </div>
              {folderTypes.length > 0 ? renderTypeList(folderTypes) : <p className="text-ui-fg-subtle text-sm py-2">No component types in this folder.</p>}
            </section>
          ))}
        </div>
      )}
    </Container>
  )
}
