"use client"

import { FieldDef } from "@/types/production"

import { Checkbox } from "@/components/ui/checkbox"
import { Field, FieldLabel } from "@/components/ui/field"
import { Input } from "@/components/ui/input"
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"

/**
 * Runtime renderer for a stage's `fieldDefs` (FR-MFG-07) — the counterpart to the builder's
 * field *designer*. The template author picks the types; this turns them into real inputs at
 * complete-time and hands back the `fieldValues` object the server stores as jsonb.
 *
 * Values are keyed by `def.key`, exactly as the server expects, and are never coerced to a
 * different shape than the type implies: Number stays a number, Checkbox a boolean, everything
 * else a string. That matters because the stored jsonb is later read back verbatim.
 */

/**
 * Labels of required fields with no value yet.
 *
 * Mirrors the server's `ValidateRequiredFields` exactly, including the part that surprises
 * people: an unchecked Checkbox **is** a provided value (`false`), so a required checkbox does
 * not force a tick. Only absent, null and whitespace-only strings count as missing — diverging
 * here would either block a save the server would accept or let one through it rejects.
 */
export function missingRequiredFields(defs: FieldDef[], values: Record<string, unknown>): string[] {
  return defs
    .filter((def) => {
      if (!def.required) return false
      const value = values[def.key]
      if (value === undefined || value === null) return true
      return typeof value === "string" && value.trim() === ""
    })
    .map((def) => def.label)
}

export function CustomFieldForm({
  defs,
  values,
  onChange,
  disabled = false,
}: {
  defs: FieldDef[]
  values: Record<string, unknown>
  onChange: (next: Record<string, unknown>) => void
  disabled?: boolean
}) {
  if (defs.length === 0) return null

  function set(key: string, value: unknown) {
    onChange({ ...values, [key]: value })
  }

  return (
    <div className="flex flex-col gap-3">
      {defs.map((def) => {
        const value = values[def.key]
        const label = (
          <FieldLabel htmlFor={`cf-${def.key}`}>
            {def.label}
            {def.required && <span className="ml-0.5 text-destructive">*</span>}
          </FieldLabel>
        )

        if (def.type === "Checkbox") {
          return (
            <div key={def.key} className="flex items-center gap-2">
              <Checkbox
                id={`cf-${def.key}`}
                checked={value === true}
                disabled={disabled}
                onCheckedChange={(checked) => set(def.key, checked === true)}
              />
              <label htmlFor={`cf-${def.key}`} className="text-sm text-foreground">
                {def.label}
                {def.required && <span className="ml-0.5 text-destructive">*</span>}
              </label>
            </div>
          )
        }

        if (def.type === "Select") {
          return (
            <Field key={def.key}>
              {label}
              <Select<string>
                value={typeof value === "string" ? value : null}
                onValueChange={(v) => set(def.key, v ?? null)}
              >
                <SelectTrigger className="h-10! w-full text-sm" disabled={disabled} id={`cf-${def.key}`}>
                  <SelectValue placeholder="Choose…" />
                </SelectTrigger>
                <SelectContent>
                  {(def.options ?? []).map((opt) => (
                    <SelectItem key={opt} value={opt} className="text-sm">
                      {opt}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </Field>
          )
        }

        return (
          <Field key={def.key}>
            {label}
            <Input
              id={`cf-${def.key}`}
              type={def.type === "Number" ? "number" : def.type === "Date" ? "date" : "text"}
              step={def.type === "Number" ? "any" : undefined}
              value={value === undefined || value === null ? "" : String(value)}
              disabled={disabled}
              onChange={(e) => {
                const raw = e.target.value
                if (def.type !== "Number") return set(def.key, raw)
                // An empty number box means "not answered", not zero — sending 0 would satisfy a
                // required check the operator never actually answered.
                set(def.key, raw === "" ? null : Number(raw))
              }}
              className="h-10 text-sm"
            />
          </Field>
        )
      })}
    </div>
  )
}
