'use client'

import { useMemo, useState, useTransition } from 'react'
import { useRouter } from 'next/navigation'
import { saveIntakeField, submitIntake } from '@/app/intake/new/actions'
import SupplierPicker, {
  type SupplierPickerValue,
  type SupplierResult,
} from './supplier-picker'

export type FieldOption = { value: string; label: string; normalized_label?: string }

const COUNTRY_FLAG_PREFIXES: Record<string, string> = {
  de_: '🇩🇪',
  us_: '🇺🇸',
  mx_: '🇲🇽',
  cn_: '🇨🇳',
  za_: '🇿🇦',
  hu_: '🇭🇺',
  uk_: '🇬🇧',
}

function flagForOption(option: FieldOption): string {
  const nl = option.normalized_label
  if (!nl) return ''
  for (const prefix in COUNTRY_FLAG_PREFIXES) {
    if (nl.startsWith(prefix)) return COUNTRY_FLAG_PREFIXES[prefix]
  }
  return ''
}

type VisibleIf =
  | { field: string; equals: string }
  | { field: string; in: string[] }
  | null

export type FieldDefinition = {
  id: string
  field_key: string
  block: number
  sort_order: number
  label: string | null
  helptext: string | null
  field_type:
    | 'text'
    | 'textarea'
    | 'number'
    | 'date'
    | 'daterange'
    | 'boolean'
    | 'select'
    | 'multiselect'
    | 'hybrid_select'
    | 'file_upload'
    | 'user_picker'
    | 'supplier_picker'
  is_required: boolean
  visible_if: VisibleIf
  options: FieldOption[]
}

const BLOCK_TITLES: Record<number, string> = {
  1: 'Projektdaten',
  2: 'Produktdaten',
  3: 'Lieferantendaten',
  4: 'Ansprechpartner BMW', // allow-customer-string
  5: 'Ansprechpartner Lieferant',
  6: 'Kosten',
  7: 'Kapazität',
  8: 'Unterlagen (Uploads)',
  9: 'Terminwünsche',
}

interface Props {
  intakeId: string
  intakeNumber: string
  definitions: FieldDefinition[]
}

type FieldValues = Record<string, unknown>

function isVisible(def: FieldDefinition, values: FieldValues): boolean {
  if (!def.visible_if) return true
  const v = values[def.visible_if.field]
  if ('equals' in def.visible_if) {
    return v === def.visible_if.equals
  }
  if ('in' in def.visible_if) {
    return Array.isArray(def.visible_if.in) && def.visible_if.in.includes(v as string)
  }
  return true
}

export default function IntakeFormClient({
  intakeId,
  intakeNumber,
  definitions,
}: Props) {
  const router = useRouter()
  const [values, setValues] = useState<FieldValues>({})
  const [savingField, setSavingField] = useState<string | null>(null)
  const [savedField, setSavedField] = useState<string | null>(null)
  const [errorMsg, setErrorMsg] = useState<string | null>(null)
  const [submitting, setSubmitting] = useState(false)
  const [, startTransition] = useTransition()

  const blocks = useMemo(() => {
    const map = new Map<number, FieldDefinition[]>()
    for (const d of definitions) {
      const arr = map.get(d.block) ?? []
      arr.push(d)
      map.set(d.block, arr)
    }
    return Array.from(map.entries()).sort((a, b) => a[0] - b[0])
  }, [definitions])

  function updateValue(fieldKey: string, value: unknown) {
    setValues((prev) => ({ ...prev, [fieldKey]: value }))
  }

  function persist(fieldKey: string) {
    const value = values[fieldKey]
    setSavingField(fieldKey)
    setErrorMsg(null)
    startTransition(async () => {
      const res = await saveIntakeField(intakeId, fieldKey, value)
      setSavingField(null)
      if (!res.ok) {
        setErrorMsg(`"${fieldKey}" Speichern fehlgeschlagen: ${res.error}`)
        return
      }
      setSavedField(fieldKey)
      setTimeout(() => setSavedField((f) => (f === fieldKey ? null : f)), 1200)
    })
  }

  async function handleSubmit() {
    // Pflichtfeld-Check für alle aktuell sichtbaren Felder
    const visible = definitions.filter((d) => isVisible(d, values))
    const missing = visible.filter((d) => {
      if (!d.is_required) return false
      const v = values[d.field_key]
      if (v == null) return true
      if (typeof v === 'string' && v.trim() === '') return true
      if (Array.isArray(v) && v.length === 0) return true
      return false
    })
    if (missing.length > 0) {
      setErrorMsg(
        `${missing.length} Pflichtfeld(er) fehlen: ${missing.map((m) => m.label ?? m.field_key).join(', ')}`,
      )
      return
    }

    setSubmitting(true)
    setErrorMsg(null)
    const res = await submitIntake(intakeId)
    setSubmitting(false)
    if (!res.ok) {
      setErrorMsg(`Einreichen fehlgeschlagen: ${res.error}`)
      return
    }
    router.push('/intake')
  }

  return (
    <div className="space-y-6">
      {errorMsg && (
        <div className="bg-destructive/10 border border-destructive text-destructive px-4 py-3 rounded-md text-sm">
          {errorMsg}
        </div>
      )}

      {blocks.map(([blockNum, fields]) => {
        const visibleInBlock = fields.filter((f) => isVisible(f, values))
        if (visibleInBlock.length === 0) return null

        return (
          <section
            key={blockNum}
            className="bg-card border border-border rounded-md overflow-hidden"
          >
            <header className="bg-muted px-4 py-2 flex items-center gap-3 border-b border-border">
              <span className="text-xs font-condensed font-bold text-muted-foreground">
                Block {blockNum}
              </span>
              <h2 className="text-sm font-bold text-foreground">
                {BLOCK_TITLES[blockNum] ?? `Block ${blockNum}`}
              </h2>
            </header>
            <div className="p-4 grid grid-cols-1 md:grid-cols-2 gap-4">
              {visibleInBlock.map((field) => (
                <FieldRenderer
                  key={field.field_key}
                  field={field}
                  value={values[field.field_key]}
                  onChange={(v) => updateValue(field.field_key, v)}
                  onBlur={() => persist(field.field_key)}
                  saving={savingField === field.field_key}
                  saved={savedField === field.field_key}
                  onSupplierPicked={(supplier: SupplierResult | null) => {
                    // KAR-146: Auto-Fill supplier_number + supplier_plant_location + persist
                    if (supplier) {
                      updateValue('supplier_number', supplier.supplier_number)
                      const loc = supplier.supplier_location ?? supplier.city ?? null
                      if (loc) updateValue('supplier_plant_location', loc)
                      // persist linked fields
                      setTimeout(() => {
                        persist('supplier_number')
                        if (loc) persist('supplier_plant_location')
                      }, 0)
                    }
                  }}
                />
              ))}
            </div>
          </section>
        )
      })}

      <div className="flex items-center justify-end gap-3 sticky bottom-0 bg-background border-t border-border py-4">
        <button
          type="button"
          onClick={() => router.push('/intake')}
          className="px-4 py-2 text-sm font-condensed font-bold text-foreground bg-secondary hover:bg-state-hover rounded-sm border border-border"
        >
          Als Entwurf speichern
        </button>
        <button
          type="button"
          onClick={handleSubmit}
          disabled={submitting}
          className="px-4 py-2 text-sm font-condensed font-bold text-primary-foreground bg-primary hover:bg-primary-dark rounded-sm disabled:opacity-50"
        >
          {submitting ? 'Einreichen…' : 'Einreichen ›'}
        </button>
      </div>
    </div>
  )
}

function FieldRenderer({
  field,
  value,
  onChange,
  onBlur,
  saving,
  saved,
  onSupplierPicked,
}: {
  field: FieldDefinition
  value: unknown
  onChange: (v: unknown) => void
  onBlur: () => void
  saving: boolean
  saved: boolean
  onSupplierPicked?: (supplier: SupplierResult | null) => void
}) {
  const baseInputClass =
    'w-full px-2 py-1.5 text-sm bg-background border border-input rounded-sm text-foreground focus:outline-none focus:border-ring'

  return (
    <div className="flex flex-col gap-1">
      <label className="flex items-center gap-2 text-xs font-condensed uppercase tracking-wide text-muted-foreground">
        <span>{field.label ?? field.field_key}</span>
        {field.is_required && <span className="text-destructive">*</span>}
        {saving && <span className="text-info">…</span>}
        {saved && <span className="text-success">✓</span>}
      </label>
      {field.helptext && (
        <p className="text-[10px] text-muted-foreground">{field.helptext}</p>
      )}
      {renderInput(field, value, onChange, onBlur, baseInputClass, onSupplierPicked)}
    </div>
  )
}

function renderInput(
  field: FieldDefinition,
  value: unknown,
  onChange: (v: unknown) => void,
  onBlur: () => void,
  cls: string,
  onSupplierPicked?: (supplier: SupplierResult | null) => void,
): React.ReactNode {
  switch (field.field_type) {
    case 'supplier_picker': {
      // KAR-146: Lieferanten-Picker
      const pickerValue: SupplierPickerValue =
        typeof value === 'object' && value !== null && 'kind' in value
          ? (value as SupplierPickerValue)
          : typeof value === 'string' && value.trim() !== ''
            ? { kind: 'freetext', freetext: value }
            : null
      return (
        <SupplierPicker
          value={pickerValue}
          onChange={(v) => {
            if (v?.kind === 'master_data') {
              onChange(v.supplier_id)
              onSupplierPicked?.(v.supplier)
            } else if (v?.kind === 'freetext') {
              onChange(v.freetext)
              onSupplierPicked?.(null)
            } else {
              onChange(null)
              onSupplierPicked?.(null)
            }
          }}
          onBlur={onBlur}
          className={cls}
        />
      )
    }
    case 'text':
    case 'user_picker':
      return (
        <input
          type="text"
          value={(value as string) ?? ''}
          onChange={(e) => onChange(e.target.value)}
          onBlur={onBlur}
          className={cls}
        />
      )
    case 'textarea':
      return (
        <textarea
          value={(value as string) ?? ''}
          onChange={(e) => onChange(e.target.value)}
          onBlur={onBlur}
          rows={3}
          className={`${cls} resize-y min-h-[60px]`}
        />
      )
    case 'number':
      return (
        <input
          type="number"
          step="any"
          value={(value as number | string) ?? ''}
          onChange={(e) => onChange(e.target.value === '' ? null : Number(e.target.value))}
          onBlur={onBlur}
          className={`${cls} font-condensed`}
        />
      )
    case 'date':
      return (
        <input
          type="date"
          value={(value as string) ?? ''}
          onChange={(e) => onChange(e.target.value)}
          onBlur={onBlur}
          className={`${cls} font-condensed`}
        />
      )
    case 'daterange': {
      const range = (value as { start?: string; end?: string }) ?? {}
      return (
        <div className="flex gap-2">
          <input
            type="date"
            value={range.start ?? ''}
            onChange={(e) => onChange({ ...range, start: e.target.value })}
            onBlur={onBlur}
            className={`${cls} font-condensed`}
          />
          <input
            type="date"
            value={range.end ?? ''}
            onChange={(e) => onChange({ ...range, end: e.target.value })}
            onBlur={onBlur}
            className={`${cls} font-condensed`}
          />
        </div>
      )
    }
    case 'boolean':
      return (
        <label className="flex items-center gap-2 text-sm">
          <input
            type="checkbox"
            checked={Boolean(value)}
            onChange={(e) => {
              onChange(e.target.checked)
              onBlur()
            }}
            className="w-4 h-4"
          />
          <span className="text-foreground">Ja</span>
        </label>
      )
    case 'select':
      return (
        <select
          value={(value as string) ?? ''}
          onChange={(e) => {
            onChange(e.target.value)
          }}
          onBlur={onBlur}
          className={cls}
        >
          <option value="">— bitte wählen —</option>
          {field.options.map((opt) => (
            <option key={opt.value} value={opt.value}>
              {opt.label}
            </option>
          ))}
        </select>
      )
    case 'multiselect': {
      const selected = (value as string[]) ?? []
      return (
        <div className="flex flex-wrap gap-1.5">
          {field.options.map((opt) => {
            const isOn = selected.includes(opt.value)
            const flag = flagForOption(opt)
            return (
              <button
                key={opt.value}
                type="button"
                onClick={() => {
                  const next = isOn
                    ? selected.filter((v) => v !== opt.value)
                    : [...selected, opt.value]
                  onChange(next)
                  // persist on toggle (no separate blur)
                  setTimeout(onBlur, 0)
                }}
                className={`px-2 py-1 text-xs font-condensed rounded-sm border ${
                  isOn
                    ? 'bg-primary text-primary-foreground border-primary'
                    : 'bg-background text-foreground border-input hover:bg-state-hover'
                }`}
              >
                {flag && <span className="mr-1">{flag}</span>}
                {opt.label}
              </button>
            )
          })}
        </div>
      )
    }
    case 'hybrid_select': {
      const hv = (value as { selected?: string; freetext?: string }) ?? {}
      return (
        <div className="space-y-1">
          <select
            value={hv.selected ?? ''}
            onChange={(e) => onChange({ ...hv, selected: e.target.value })}
            onBlur={onBlur}
            className={cls}
          >
            <option value="">— vordefiniert wählen —</option>
            {field.options.map((opt) => (
              <option key={opt.value} value={opt.value}>
                {opt.label}
              </option>
            ))}
          </select>
          <input
            type="text"
            value={hv.freetext ?? ''}
            placeholder="oder Freitext"
            onChange={(e) => onChange({ ...hv, freetext: e.target.value })}
            onBlur={onBlur}
            className={cls}
          />
        </div>
      )
    }
    case 'file_upload':
      return (
        <div className="text-xs text-muted-foreground italic">
          Datei-Upload wird in einem späteren PR aktiviert.
        </div>
      )
    default:
      return <span className="text-xs text-muted-foreground">{field.field_type}</span>
  }
}
