"use client"

import { useEffect, useState } from "react"
import { Package } from "lucide-react"

import { productConfigApi } from "@/lib/api/product-config"
import { errorMessage } from "@/lib/error-map"
import { ProductConfig } from "@/types/master-data"

import { Skeleton } from "@/components/ui/skeleton"
import { Switch } from "@/components/ui/switch"
import { toast } from "@/components/ui/toast"

/**
 * Product Configuration (docs/11 §2.8; FR-MD-11) — the singleton feature gate.
 *
 * `subcategoriesEnabled`/`brandsEnabled` are the only user-toggleable flags here and are
 * enforced by the server (an item write carrying a gated field gets 422 CONFIG_DISABLED).
 * `itemTypesEnabled` has no control on this screen but is still part of the record, so
 * every save round-trips its current value unchanged (the server rejects a partial body).
 */
export default function ProductSettingsPage() {
  const [config, setConfig] = useState<ProductConfig | null>(null)
  const [etag, setEtag] = useState<string | null>(null)
  const [error, setError] = useState<string | null>(null)
  const [saving, setSaving] = useState<keyof ProductConfig | null>(null)

  function load() {
    setError(null)
    productConfigApi
      .get()
      .then((res) => {
        setConfig(res.data)
        setEtag(res.etag)
      })
      .catch((err) => setError(errorMessage(err)))
  }

  useEffect(load, [])

  async function toggle(flag: "subcategoriesEnabled" | "brandsEnabled", next: boolean) {
    if (!config) return
    setSaving(flag)
    try {
      // All three flags are always sent — the server rejects a partial body (400), which
      // is what stops an omitted flag from silently switching a feature off.
      const res = await productConfigApi.update(
        {
          subcategoriesEnabled: config.subcategoriesEnabled,
          brandsEnabled: config.brandsEnabled,
          itemTypesEnabled: config.itemTypesEnabled,
          [flag]: next,
        },
        etag ?? "",
      )
      setConfig(res.data)
      setEtag(res.etag)
      toast.success("Configuration saved", `${LABELS[flag]} ${next ? "enabled" : "disabled"}.`)
    } catch (err) {
      toast.error("Could not save configuration", errorMessage(err))
      load() // a 412 means someone else changed it — resync rather than retry blind
    } finally {
      setSaving(null)
    }
  }

  return (
    <div className="flex flex-col gap-6">
      <div className="flex items-center gap-3">
        <div>
          <h1 className="text-2xl font-bold text-foreground">Product Configuration</h1>
          <p className="text-base text-muted-foreground">
            Switch optional product features on or off for this deployment (FR-MD-11).
          </p>
        </div>
      </div>

      {error && (
        <div className="rounded-lg border border-destructive/30 bg-destructive/5 p-5 text-base text-destructive">{error}</div>
      )}

      {!error && !config && <Skeleton className="h-64 w-full" />}

      {!error && config && (
        <div className="flex flex-col gap-4 rounded-xl border p-6">
          <div className="flex items-center gap-2">
            <Package className="size-5 text-primary" />
            <h2 className="text-lg font-semibold text-foreground">Product Capabilities</h2>
          </div>
          <div className="border-t" />

          <div className="grid grid-cols-1 gap-x-10 md:grid-cols-2">
            <ToggleRow
              label="Subcategories"
              description="Category hierarchy includes a subcategory level. Off ⇒ products attach directly to a category."
              checked={config.subcategoriesEnabled}
              busy={saving === "subcategoriesEnabled"}
              onChange={(v) => toggle("subcategoriesEnabled", v)}
            />

            <ToggleRow
              label="Brands"
              description="Products may carry a brand."
              checked={config.brandsEnabled}
              busy={saving === "brandsEnabled"}
              onChange={(v) => toggle("brandsEnabled", v)}
            />
          </div>

          {config.updatedAt && (
            <p className="pt-2 text-sm text-muted-foreground">
              Last changed {new Date(config.updatedAt).toLocaleString()}
              {config.updatedBy ? ` by user #${config.updatedBy}` : ""}.
            </p>
          )}
        </div>
      )}
    </div>
  )
}

const LABELS: Record<string, string> = {
  subcategoriesEnabled: "Subcategories",
  brandsEnabled: "Brands",
}

function ToggleRow({
  label,
  description,
  checked,
  busy,
  onChange,
}: {
  label: string
  description: string
  checked: boolean
  busy: boolean
  onChange: (next: boolean) => void
}) {
  return (
    <div className="flex items-start gap-4 py-4">
      <Switch
        checked={checked}
        onCheckedChange={onChange}
        disabled={busy}
        aria-label={label}
        className="mt-1 shrink-0"
      />
      <div className="flex flex-col gap-1">
        <span className="text-base font-medium text-foreground">{label}</span>
        <span className="text-sm text-muted-foreground">{description}</span>
      </div>
    </div>
  )
}
