'use client'

import {
  memo,
  useCallback,
  useEffect,
  useId,
  useMemo,
  useRef,
  useState,
  type Dispatch,
  type ReactNode,
  type SetStateAction,
} from 'react'
import { useSession } from 'next-auth/react'
import { createPortal } from 'react-dom'
import { BOAT_MANUFACTURER_RECORDS } from '@/data/boat-manufacturers'
import {
  countryRegionNamePl,
  flagEmojiFromIso2,
  manufacturerRecordByExactName,
  manufacturersForListingCategory,
  type BoatManufacturerRecord,
  type ListingManufacturerCategory,
} from '@/data/boat-manufacturer-segments'
import { BOAT_EQUIPMENT_CATEGORIES, boatEquipmentItemsForCategory } from '@/data/boat-equipment'
import { POLISH_VOIVODESHIPS } from '@/data/polish-voivodeships'
import { LISTING_CATEGORIES as CATEGORIES } from '@/data/listing-field-options'
import { EquipmentGlyph } from '@/components/boats/equipment-glyphs'
import type { ListingCoreInput } from '@/lib/listings'
import { trackAnalyticsEvent } from '@/lib/analytics'

const MAX_LISTING_TITLE_LEN = 70
/** Limit słów w liczniku i przy wklejaniu (twarde ograniczenie wpisywania to znaki). */
const MAX_LISTING_TITLE_WORDS = 70

function countWordsInTitle(s: string): number {
  const t = s.trim()
  if (!t) return 0
  return t.split(/\s+/).length
}

function clampListingTitleInput(raw: string): string {
  let v = raw.slice(0, MAX_LISTING_TITLE_LEN)
  const words = v.trim().split(/\s+/).filter(Boolean)
  if (words.length > MAX_LISTING_TITLE_WORDS) {
    v = words.slice(0, MAX_LISTING_TITLE_WORDS).join(' ')
    v = v.slice(0, MAX_LISTING_TITLE_LEN)
  }
  return v
}

const ListingEditPhotoThumb = memo(function ListingEditPhotoThumb({
  src,
  isMain,
}: {
  src: string
  isMain: boolean
}) {
  const [broken, setBroken] = useState(false)
  return (
    <div className="relative aspect-square overflow-hidden rounded-lg border border-gray-200 bg-white shadow-sm">
      {isMain ? (
        <span className="absolute left-1 top-1 z-10 max-w-[calc(100%-0.5rem)] rounded bg-blue-600 px-1.5 py-0.5 text-[10px] font-semibold leading-tight text-white shadow-sm">
          Zdjęcie główne
        </span>
      ) : null}
      {broken ? (
        <div className="flex h-full min-h-[5rem] flex-col items-center justify-center p-2 text-center text-[11px] text-gray-500">
          Nie udało się wczytać podglądu
        </div>
      ) : (
        <img
          src={src}
          alt=""
          className="h-full w-full object-cover"
          loading="lazy"
          decoding="async"
          onError={() => setBroken(true)}
        />
      )}
    </div>
  )
})

const STEPS = [
  { id: 1, label: 'Kategoria', desc: 'Wybierz kategorię ogłoszenia.' },
  {
    id: 2,
    label: 'Szczegóły',
    desc: 'Tytuł, opis i cena na początku — potem szczegóły jednostki i wyposażenie.',
  },
  { id: 3, label: 'Zdjęcia', desc: 'Dodaj zdjęcia w dobrej jakości. Możesz też przesłać je później mailem.' },
  { id: 4, label: 'Czas i widoczność', desc: 'Wybierz czas publikacji i opcjonalne wyróżnienia ogłoszenia.' },
  { id: 5, label: 'Podsumowanie', desc: 'Sprawdź dane, uzupełnij dane do kontaktu i opublikuj.' },
] as const

/** Typy z odpowiednikami PL ↔ EN (jak w katalogach jachtowych) */
const BOAT_HULL_TYPES = [
  { value: 'katamaran', label: 'Katamaran (catamaran)' },
  { value: 'keelboat', label: 'Jacht kilowy (keelboat)' },
  { value: 'daysailer', label: 'Jacht dzienny (daysailer)' },
  { value: 'center_cockpit', label: 'Kokpit środkowy (center cockpit)' },
  { value: 'ketch', label: 'Ketch (ketch)' },
  { value: 'deck_saloon', label: 'Salon na pokładzie (deck saloon)' },
  { value: 'sailing_yacht', label: 'Jacht żaglowy (sailing yacht)' },
  { value: 'racing_boat', label: 'Jacht regatowy (racing boat)' },
  { value: 'bluewater_yacht', label: 'Jacht pełnomorski (bluewater yacht)' },
  { value: 'classic_sailing_yacht', label: 'Klasyczny jacht żaglowy (classic sailing yacht)' },
  { value: 'motorsailer', label: 'Motorożaglowiec (motorsailer)' },
  { value: 'trimaran', label: 'Trimaran (trimaran)' },
  { value: 'sailing_dinghy', label: 'Żaglówka (sailing dinghy)' },
  { value: 'dinghy_cruiser', label: 'Dinghy turystyczny / kabinowy (dinghy cruiser)' },
  { value: 'flat_bottomed_boat', label: 'Jacht lub łódź płaskodenny (flat-bottomed boat)' },
  { value: 'gulet', label: 'Gulet (gulet)' },
  { value: 'sailing_superyacht', label: 'Superjacht żaglowy (sailing superyacht)' },
] as const

/** Materiał kadłuba — wartości zgodne z typowymi ogłoszeniami jachtowymi */
const BOAT_HULL_MATERIALS = [
  { value: 'grp_polyester', label: 'Laminat poliestrowy (GRP / poliester)' },
  { value: 'grp_vinylester', label: 'Laminat winyloestrowy (vinylester GRP)' },
  { value: 'epoxy_composite', label: 'Laminat epoksydowy / kompozyt (epoxy composite)' },
  { value: 'carbon_composite', label: 'Kompozyt węglowy (carbon)' },
  { value: 'aluminum', label: 'Aluminium (aluminium)' },
  { value: 'steel', label: 'Stal (steel)' },
  { value: 'wood', label: 'Drewno (wood)' },
  { value: 'plywood_epoxy', label: 'Sklejka epoksydowa (plywood / epoxy)' },
  { value: 'ferrocement', label: 'Ferro-cement / beton (ferrocement)' },
  { value: 'inflatable_pvc', label: 'Łodzie pneumatyczne — kadłub z PVC' },
  { value: 'inflatable_hypalon', label: 'Łodzie pneumatyczne — kadłub Hypalon / CSM' },
  { value: 'mixed', label: 'Mieszany / laminat na drewnie (mixed)' },
  { value: 'other', label: 'Inny (doprecyzuj w uwagach)' },
] as const

/** Typ kilu / miecza */
const BOAT_KEEL_TYPES = [
  { value: 'na', label: 'Nie dotyczy / brak kilu (np. motorówka, RIB)' },
  { value: 'long_keel', label: 'Kil pełny (long keel)' },
  { value: 'fin_keel', label: 'Kil płetwowy / standardowy (fin keel)' },
  { value: 'wing_keel', label: 'Kil skrzydłowy (wing keel)' },
  { value: 'bulb_keel', label: 'Kil z bulbem (bulb keel)' },
  { value: 'twin_keel', label: 'Kil bliźniaczy (twin keel)' },
  { value: 'bilge_keel', label: 'Kil kolanowy (bilge keel)' },
  { value: 'lifting_keel', label: 'Kil podnoszony (lifting keel)' },
  { value: 'swing_keel', label: 'Kil kapujący / składany (swing keel)' },
  { value: 'centerboard', label: 'Miecz środkowy (centreboard)' },
  { value: 'daggerboard', label: 'Miecz szpadlowy (daggerboard)' },
  { value: 'keel_centerboard', label: 'Kil + miecz (keel / centreboard)' },
  { value: 'shoal_keel', label: 'Kil płytkiej wody (shoal draft)' },
  { value: 'other_keel', label: 'Inny (doprecyzuj w uwagach)' },
] as const

/** Typ masztu / sposób kotwiczenia (jak w formularzach ogłoszeń) */
const BOAT_MAST_TYPES = [
  { value: 'na', label: 'Nie dotyczy / brak masztu' },
  { value: 'aluminum', label: 'Maszt aluminiowy' },
  { value: 'wood', label: 'Maszt drewniany' },
  { value: 'carbon', label: 'Maszt z włókna węglowego' },
  { value: 'composite', label: 'Maszt kompozytowy (GRP)' },
  { value: 'keel_stepped', label: 'Kotwiczony w kielichu (keel-stepped)' },
  { value: 'deck_stepped', label: 'Kotwiczony na pokładzie (deck-stepped)' },
  { value: 'tabernacle', label: 'Maszt tabernaklowy' },
  { value: 'in_mast_furling', label: 'Roll w maszcie (in-mast furling)' },
  { value: 'other_mast', label: 'Inny (doprecyzuj w uwagach)' },
] as const

const BOAT_PROPULSION_TYPES = [
  { value: 'none', label: 'Brak silnika' },
  { value: 'outboard', label: 'Silnik zaburtowy' },
  { value: 'inboard', label: 'Silnik stacjonarny (wewnątrz kadłuba)' },
  { value: 'saildrive', label: 'Saildrive' },
  { value: 'shaft', label: 'Wał napędowy (straight shaft)' },
  { value: 'stern_drive', label: 'Sterndrive / Z-drive' },
  { value: 'pod', label: 'Silnik POD / IPS' },
  { value: 'surface_drive', label: 'Napęd powierzchniowy' },
  { value: 'jet', label: 'Napęd strugowodny (jet)' },
  { value: 'electric_motor', label: 'Silnik elektryczny' },
  { value: 'hybrid_motor', label: 'Napęd hybrydowy' },
  { value: 'other_prop', label: 'Inny (doprecyzuj w uwagach)' },
] as const

const BOAT_ENGINE_FUEL_TYPES = [
  { value: 'na', label: 'Nie dotyczy' },
  { value: 'diesel', label: 'Olej napędowy' },
  { value: 'petrol', label: 'Benzyna' },
  { value: 'electric', label: 'Energia elektryczna' },
  { value: 'lpg', label: 'LPG' },
  { value: 'other_fuel', label: 'Inne' },
] as const

/** Typ napędu przy ogłoszeniu tylko silnika — jak Boat24: do 3 pozycji. */
const ENGINE_LISTING_PROPULSION_TYPES = BOAT_PROPULSION_TYPES.filter((p) => p.value !== 'none')

const ENGINE_STEERING_TYPES = [
  { value: 'hydraulic', label: 'Hydrauliczne' },
  { value: 'mechanical', label: 'Mechaniczne' },
  { value: 'electric', label: 'Elektryczne (wspomaganie)' },
  { value: 'cable', label: 'Linka / przekładnia' },
  { value: 'tiller', label: 'Rumpel (ster bezpośredni)' },
  { value: 'na', label: 'Nie dotyczy / brak danych' },
] as const

/** Kategoria „Kajaki, wiosła, SUP” — typ jak w formularzu Boat24 Small boat (do 3 pozycji). */
const SMALL_CRAFT_TYPES = [
  { value: 'kayak', label: 'Kajak' },
  { value: 'canoe', label: 'Kanadyjka / kanoe' },
  { value: 'sup', label: 'SUP (deska paddlingowa)' },
  { value: 'rowing', label: 'Łódź wiosłowa' },
  { value: 'inflatable_rec', label: 'Ponton / dmuchana łódź rekreacyjna' },
  { value: 'sailing_dinghy_small', label: 'Żaglówka treningowa / klasa młodzieżowa' },
  { value: 'pedalo', label: 'Rower wodny / pedalówka' },
  { value: 'raft_tour', label: 'Tratwa / ponton turystyczny' },
  { value: 'other_small', label: 'Inna mała jednostka' },
] as const

/** Materiał — uproszczona lista pod małe jednostki (PDF Small boat). */
const SMALL_HULL_MATERIALS = [
  { value: 'pe_rotomold', label: 'Polietylen (formowany obrotowo)' },
  { value: 'composite_small', label: 'Kompozyt / laminat' },
  { value: 'wood_small', label: 'Drewno' },
  { value: 'inflatable_pvc_s', label: 'PVC (ponton)' },
  { value: 'inflatable_hypalon_s', label: 'Hypalon / CSM' },
  { value: 'aluminum_small', label: 'Aluminium' },
  { value: 'other_small_mat', label: 'Inny (doprecyzuj w opisie)' },
] as const

const BOAT_YEAR_MIN = 1970

const inputClass =
  'w-full px-3 py-2 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-600 focus:border-transparent'
/** Krótkie wartości liczbowe (wymiary, rok, litry, kg…) — węższa ramka */
const inputShortClass =
  'w-full max-w-[6.5rem] px-2 py-1 text-xs tabular-nums border border-gray-300 rounded-md focus:ring-2 focus:ring-blue-600 focus:border-transparent'
/** Cena — nieco szersze na dłuższe kwoty */
const inputPriceClass =
  'w-full max-w-[8.5rem] px-2 py-1 text-sm tabular-nums border border-gray-300 rounded-md focus:ring-2 focus:ring-blue-600 focus:border-transparent'
const labelClass = 'block text-sm font-medium text-gray-700 mb-1'

/** W podsumowaniu: nazwa + przypisany kraj (z katalogu marek). */
function ProducerSummaryDd({
  name,
  catalog,
}: {
  name: string
  catalog: readonly BoatManufacturerRecord[]
}) {
  const t = name.trim()
  if (!t) return '—'
  const record = manufacturerRecordByExactName(t, catalog)
  const code = record?.countryCode
  if (!code) return <span className="font-medium">{t}</span>
  const flag = flagEmojiFromIso2(code)
  const label = countryRegionNamePl(code)
  return (
    <span className="inline-flex flex-wrap items-center gap-2 font-medium">
      <span>{t}</span>
      <span
        className="inline-flex items-center gap-1 rounded-md border border-gray-200 bg-white px-1.5 py-px text-[11px] font-semibold leading-tight text-gray-600 tabular-nums"
        title={`Kraj: ${label}`}
      >
        {flag ? (
          <span aria-hidden className="text-[15px] leading-none">
            {flag}
          </span>
        ) : null}
        <span>{code}</span>
      </span>
    </span>
  )
}

/** Zgodne z logiką `parseDecimal` w `lib/listings.ts` (walidacja kroku 2). */
function parseListingPriceInput(s: string): number | null {
  const t = s.trim().replace(/\s/g, '').replace(',', '.')
  if (!t) return null
  const n = Number(t)
  return Number.isFinite(n) && n >= 0 ? n : null
}

const stepperShellClass =
  'flex h-7 items-stretch rounded-md border border-gray-300 overflow-hidden bg-white focus-within:ring-2 focus-within:ring-blue-600 focus-within:border-transparent'
const stepperBtnClass =
  'flex w-6 shrink-0 items-center justify-center bg-gray-100 text-xs font-semibold leading-none text-gray-700 transition hover:bg-gray-200 disabled:cursor-not-allowed disabled:opacity-35'
const stepperInputClass =
  'min-w-0 flex-1 border-0 bg-transparent px-0.5 text-center text-xs tabular-nums focus:outline-none focus:ring-0'

function IntStepper({
  label,
  value,
  onChange,
  min,
  max,
  step = 1,
}: {
  label: string
  value: string
  onChange: (v: string) => void
  min: number
  max: number
  /** Krok dla przycisków − / + (wpis ręczny dowolny w zakresie) */
  step?: number
}) {
  const cur =
    value.trim() === '' ? null : Math.min(max, Math.max(min, Number.parseInt(value, 10) || 0))

  return (
    <div className="min-w-0 w-[6.5rem] shrink-0">
      <label className={labelClass}>{label}</label>
      <div className={stepperShellClass}>
        <button
          type="button"
          className={stepperBtnClass}
          onClick={() => {
            if (cur === null) return
            const next = cur - step
            if (next < min) onChange('')
            else onChange(String(next))
          }}
          disabled={cur === null}
          aria-label="Zmniejsz"
        >
          −
        </button>
        <input
          type="text"
          inputMode="numeric"
          className={stepperInputClass}
          value={value}
          onChange={(e) => {
            const t = e.target.value
            if (t === '') {
              onChange('')
              return
            }
            const n = Number.parseInt(t, 10)
            if (!Number.isFinite(n)) return
            onChange(String(Math.min(max, Math.max(min, n))))
          }}
        />
        <button
          type="button"
          className={stepperBtnClass}
          onClick={() => {
            if (cur === null) onChange(String(min))
            else onChange(String(Math.min(max, cur + step)))
          }}
          disabled={cur !== null && cur >= max}
          aria-label="Zwiększ"
        >
          +
        </button>
      </div>
    </div>
  )
}

function HpStepper({
  label,
  value,
  onChange,
  max = 4000,
}: {
  label: string
  value: string
  onChange: (v: string) => void
  max?: number
}) {
  const step = 5
  const cur = value.trim() === '' ? null : Math.min(max, Math.max(0, Number.parseInt(value, 10) || 0))

  const bump = (delta: number) => {
    const base = cur ?? 0
    if (delta < 0 && base === 0) {
      onChange('')
      return
    }
    onChange(String(Math.min(max, Math.max(0, base + delta))))
  }

  return (
    <div className="min-w-0 w-[6.5rem] shrink-0">
      <label className={labelClass}>{label}</label>
      <div className={stepperShellClass}>
        <button
          type="button"
          className={stepperBtnClass}
          onClick={() => bump(-step)}
          disabled={cur === null}
          aria-label="Zmniejsz moc"
        >
          −
        </button>
        <input
          type="text"
          inputMode="numeric"
          className={stepperInputClass}
          value={value}
          onChange={(e) => {
            const t = e.target.value
            if (t === '') {
              onChange('')
              return
            }
            const n = Number.parseInt(t, 10)
            if (!Number.isFinite(n)) return
            onChange(String(Math.min(max, Math.max(0, n))))
          }}
        />
        <button
          type="button"
          className={stepperBtnClass}
          onClick={() => bump(step)}
          disabled={cur !== null && cur >= max}
          aria-label="Zwiększ moc"
        >
          +
        </button>
      </div>
    </div>
  )
}

/** Rok: przewijana lista + wpis własny (bez <datalist> — słabe przewijanie w przeglądarkach). */
const YearCombobox = memo(function YearCombobox({
  label,
  value,
  onChange,
}: {
  label: string
  value: string
  onChange: (v: string) => void
}) {
  const baseId = useId()
  const inputId = `${baseId}-year-in`
  const listboxId = `${baseId}-year-lb`
  const wrapRef = useRef<HTMLDivElement>(null)
  const [open, setOpen] = useState(false)
  const [highlight, setHighlight] = useState(-1)

  /** Górny rok = bieżący rok kalendarzowy w momencie otwarcia tego pola (nowa wartość po ponownym wejściu w krok). */
  const yearOptions = useMemo(() => {
    const max = new Date().getFullYear()
    return Array.from({ length: max - BOAT_YEAR_MIN + 1 }, (_, i) => max - i)
  }, [])

  const q = value.trim()
  const filtered = useMemo(() => {
    if (!q) return [...yearOptions]
    return yearOptions.filter((y) => String(y).includes(q))
  }, [q, yearOptions])

  const showPanel = open && filtered.length > 0

  const pick = useCallback(
    (year: number) => {
      onChange(String(year))
      setOpen(false)
      setHighlight(-1)
    },
    [onChange],
  )

  useEffect(() => {
    if (!open) return
    const onDoc = (e: MouseEvent) => {
      const el = wrapRef.current
      if (el && !el.contains(e.target as Node)) setOpen(false)
    }
    document.addEventListener('mousedown', onDoc)
    return () => document.removeEventListener('mousedown', onDoc)
  }, [open])

  return (
    <div ref={wrapRef} className="relative">
      <label className={labelClass} htmlFor={inputId}>
        {label}
      </label>
      <input
        id={inputId}
        type="text"
        inputMode="numeric"
        className={inputShortClass}
        value={value}
        autoComplete="off"
        role="combobox"
        aria-expanded={showPanel}
        aria-controls={listboxId}
        aria-autocomplete="list"
        placeholder="Wpisz lub rozwiń listę"
        onChange={(e) => {
          onChange(e.target.value)
          setOpen(true)
          setHighlight(-1)
        }}
        onFocus={() => setOpen(true)}
        onKeyDown={(e) => {
          if (!showPanel) {
            if (e.key === 'ArrowDown' && yearOptions.length > 0) {
              setOpen(true)
              setHighlight(0)
            }
            return
          }
          if (e.key === 'Escape') {
            setOpen(false)
            setHighlight(-1)
            e.preventDefault()
            return
          }
          if (e.key === 'ArrowDown') {
            setHighlight((h) => Math.min(filtered.length - 1, h + 1))
            e.preventDefault()
            return
          }
          if (e.key === 'ArrowUp') {
            setHighlight((h) => Math.max(0, h - 1))
            e.preventDefault()
            return
          }
          if (e.key === 'Enter' && highlight >= 0 && filtered[highlight] !== undefined) {
            pick(filtered[highlight])
            e.preventDefault()
          }
        }}
      />
      {showPanel && (
        <ul
          id={listboxId}
          role="listbox"
          className="absolute left-0 z-[10000] mt-1 box-border max-h-60 min-w-[6.5rem] w-[min(100%,9rem)] overflow-y-auto overscroll-contain rounded-lg border border-gray-200 bg-white py-1 pr-px shadow-lg [scrollbar-color:rgb(100_116_139)_rgb(241_245_249)] [scrollbar-gutter:stable] [scrollbar-width:auto] [&::-webkit-scrollbar]:w-2.5 [&::-webkit-scrollbar-thumb]:rounded-full [&::-webkit-scrollbar-thumb]:border-2 [&::-webkit-scrollbar-thumb]:border-transparent [&::-webkit-scrollbar-thumb]:bg-slate-500 [&::-webkit-scrollbar-track]:rounded-full [&::-webkit-scrollbar-track]:bg-slate-100"
        >
          {filtered.map((y, i) => (
            <li key={y} role="presentation">
              <button
                type="button"
                role="option"
                aria-selected={highlight === i}
                className={`w-full px-3 py-1.5 text-left text-xs tabular-nums ${
                  highlight === i ? 'bg-blue-50 text-blue-950' : 'text-gray-900 hover:bg-gray-50'
                }`}
                onMouseEnter={() => setHighlight(i)}
                onMouseDown={(e) => e.preventDefault()}
                onClick={() => pick(y)}
              >
                {y}
              </button>
            </li>
          ))}
        </ul>
      )}
      <p className="mt-1 text-xs text-gray-500">
        Lista przewijana — wpisz fragment (np. „201”) albo dowolny rok spoza listy.
      </p>
    </div>
  )
})

type ListingFormState = {
  category: string
  /** Kategoria „Silniki”: do 3 typów napędu z listy */
  engineListingTypes: string[]
  /** Kategoria „Kajaki, wiosła, SUP”: do 3 typów z listy (wzorzec Small boat PDF) */
  smallCraftTypes: string[]
  /** Kategoria „Kajaki…”: przyczepa / transport w zestawie */
  trailerIncluded: boolean
  /** Kategoria „Kajaki…”: możliwość postoju (np. marina) */
  berthAvailable: boolean
  /** Kategoria „Silniki”: sterowanie (lista) */
  steeringType: string
  boatType: string
  manufacturer: string
  modelTitle: string
  subtitle: string
  yearBuilt: string
  condition: string
  material: string
  keelType: string
  steering: string
  lengthM: string
  beamM: string
  maxDraftM: string
  draftKeelUpM: string
  bridgeClearanceM: string
  weightKg: string
  ballastKg: string
  ceMarking: string
  maxPersons: string
  mastMaterial: string
  mastHeightM: string
  mainsailM2: string
  jibM2: string
  genoaM2: string
  /** Łączna powierzchnia żagli (m²), opcjonalnie zamiast lub obok rozbicia na grot/fok/genoa */
  sailsTotalM2: string
  engineCount: string
  enginePowerHp: string
  propulsion: string
  fuelType: string
  fuelTankL: string
  engineHours: string
  cabins: string
  berths: string
  heads: string
  headroomM: string
  freshWaterL: string
  holdingTankL: string
  equipment: string[]
  notes: string
  youtubeUrl: string
  country: string
  region: string
  location: string
  price: string
  offerType: 'fixed' | 'negotiable' | 'on_request'
  contactPerson: string
  email: string
  phone: string
  photos: File[]
  duration: '30' | '60' | '90'
  topOffer: boolean
  highlight: boolean
  invoiceTitle: string
  invoiceName: string
  invoiceStreet: string
  invoiceHouseNo: string
  invoiceZip: string
  invoiceCity: string
  invoicePhone: string
  /** UX: po zaznaczeniu pokazuj pola faktury; nie wysyłane do API */
  wantsInvoiceData: boolean
  acceptTerms: boolean
  /** Przy edycji: kolejność ścieżek/URL zdjęć w witrynie; pierwsza pozycja = główne, zapis do `listing_images`. */
  serverListingPhotoPaths: string[]
}

function emptyForm(): ListingFormState {
  return {
    category: '',
    engineListingTypes: [],
    smallCraftTypes: [],
    trailerIncluded: false,
    berthAvailable: false,
    steeringType: '',
    boatType: '',
    manufacturer: '',
    modelTitle: '',
    subtitle: '',
    yearBuilt: '',
    condition: '',
    material: '',
    keelType: '',
    steering: '',
    lengthM: '',
    beamM: '',
    maxDraftM: '',
    draftKeelUpM: '',
    bridgeClearanceM: '',
    weightKg: '',
    ballastKg: '',
    ceMarking: '',
    maxPersons: '',
    mastMaterial: '',
    mastHeightM: '',
    mainsailM2: '',
    jibM2: '',
    genoaM2: '',
    sailsTotalM2: '',
    engineCount: '',
    enginePowerHp: '',
    propulsion: '',
    fuelType: '',
    fuelTankL: '',
    engineHours: '',
    cabins: '',
    berths: '',
    heads: '',
    headroomM: '',
    freshWaterL: '',
    holdingTankL: '',
    equipment: [],
    notes: '',
    youtubeUrl: '',
    country: 'Polska',
    region: '',
    location: '',
    price: '',
    offerType: 'fixed',
    contactPerson: '',
    email: '',
    phone: '',
    photos: [],
    duration: '60',
    topOffer: false,
    highlight: false,
    invoiceTitle: '',
    invoiceName: '',
    invoiceStreet: '',
    invoiceHouseNo: '',
    invoiceZip: '',
    invoiceCity: '',
    invoicePhone: '',
    wantsInvoiceData: false,
    acceptTerms: false,
    serverListingPhotoPaths: [],
  }
}

function hasAnyInvoiceDetail(data: Partial<ListingFormState>): boolean {
  return [
    data.invoiceTitle,
    data.invoiceName,
    data.invoiceStreet,
    data.invoiceHouseNo,
    data.invoiceZip,
    data.invoiceCity,
    data.invoicePhone,
  ].some((s) => String(s ?? '').trim().length > 0)
}

const NotesPriceFields = memo(function NotesPriceFields({
  form,
  update,
  setForm,
}: {
  form: ListingFormState
  update: <K extends keyof ListingFormState>(key: K, value: ListingFormState[K]) => void
  setForm: Dispatch<SetStateAction<ListingFormState>>
}) {
  return (
    <Section title="Opis i cena">
      <div>
        <label className={labelClass}>Notatki / opis</label>
        <textarea
          rows={8}
          className={inputClass}
          value={form.notes}
          onChange={(e) => update('notes', e.target.value)}
          placeholder="Stan techniczny, remonty, wyposażenie dodatkowe…"
        />
      </div>
      <fieldset className="rounded-xl border border-gray-200 bg-slate-50/60 px-3 py-3 sm:px-4 sm:py-4">
        <legend className={`${labelClass} px-0.5 font-semibold text-gray-800`}>Cena *</legend>
        <p className="mb-3 text-xs text-gray-600">
          Wybierz sposób podania oferty — dla stałej lub negocjacyjnej musisz wpisać kwotę.
        </p>
        <div className="space-y-2">
          {(
            [
              { value: 'fixed' as const, title: 'Cena stała', hint: 'Kwota widoczna w ogłoszeniu.' },
              {
                value: 'negotiable' as const,
                title: 'Do negocjacji',
                hint: 'Kwota jako punkt wyjścia do rozmowy.',
              },
              {
                value: 'on_request' as const,
                title: 'Cena na zapytanie',
                hint: 'Bez kwoty w ogłoszeniu — cena ustala się przy kontakcie.',
              },
            ] as const
          ).map((opt) => (
            <label
              key={opt.value}
              className={`flex cursor-pointer items-start gap-3 rounded-lg border p-3 text-sm transition-colors ${
                form.offerType === opt.value
                  ? 'border-blue-600 bg-blue-50/90'
                  : 'border-gray-200 bg-white hover:border-gray-300'
              }`}
            >
              <input
                type="radio"
                name="listing-offer-type-step2"
                className="mt-0.5 h-4 w-4 shrink-0 border-gray-300 text-blue-600"
                checked={form.offerType === opt.value}
                onChange={() => {
                  setForm((f) => ({
                    ...f,
                    offerType: opt.value,
                    price: opt.value === 'on_request' ? '' : f.price,
                  }))
                }}
              />
              <span>
                <span className="font-medium text-gray-900">{opt.title}</span>
                <span className="mt-0.5 block text-xs leading-snug text-gray-600">{opt.hint}</span>
              </span>
            </label>
          ))}
        </div>
        {form.offerType !== 'on_request' && (
          <div className="mt-3 border-t border-gray-200 pt-3">
            <label className={labelClass} htmlFor="listing-price-pln-step2">
              Kwota w zł *
            </label>
            <input
              id="listing-price-pln-step2"
              type="text"
              inputMode="decimal"
              className={`${inputPriceClass} max-w-full sm:max-w-[12rem]`}
              value={form.price}
              onChange={(e) => update('price', e.target.value)}
            />
          </div>
        )}
      </fieldset>
    </Section>
  )
})

function Section({ title, children }: { title: string; children: ReactNode }) {
  return (
    <fieldset className="rounded-xl border border-gray-200 bg-gray-50/80 p-4 space-y-3">
      <legend className="px-1 text-sm font-semibold text-blue-950">{title}</legend>
      {children}
    </fieldset>
  )
}

const EquipmentPicker = memo(function EquipmentPicker({
  equipment,
  onToggle,
}: {
  equipment: string[]
  onToggle: (id: string) => void
}) {
  return (
    <>
      <p className="text-xs text-gray-600">
        Grupy i pozycje odpowiadają PDF-owi Boat24 — każda ma stały identyfikator pod przyszłe filtry w wyszukiwarce.
      </p>
      <div className="space-y-8">
        {BOAT_EQUIPMENT_CATEGORIES.map((cat) => {
          const items = boatEquipmentItemsForCategory(cat.id)
          return (
            <div key={cat.id} className="space-y-3">
              <div className="border-b border-gray-200 pb-2">
                <h4 className="text-sm font-semibold text-blue-950">{cat.label}</h4>
                <p className="text-xs text-gray-500">{cat.labelEn}</p>
              </div>
              <div className="grid gap-2 sm:grid-cols-2 xl:grid-cols-3">
                {items.map((eq) => {
                  const on = equipment.includes(eq.id)
                  return (
                    <label
                      key={eq.id}
                      className={`flex cursor-pointer items-center gap-3 rounded-xl border-2 p-3 text-sm transition-colors ${
                        on ? 'border-blue-600 bg-blue-50/90' : 'border-gray-200 bg-white hover:border-gray-300'
                      }`}
                    >
                      <input
                        type="checkbox"
                        className="sr-only"
                        checked={on}
                        onChange={() => onToggle(eq.id)}
                      />
                      <EquipmentGlyph icon={eq.icon} className="h-8 w-8 shrink-0 text-blue-700" />
                      <span className={`font-medium leading-snug ${on ? 'text-blue-950' : 'text-gray-800'}`}>
                        {eq.label}
                      </span>
                    </label>
                  )
                })}
              </div>
            </div>
          )
        })}
      </div>
    </>
  )
})

const ManufacturerField = memo(function ManufacturerField({
  value,
  onChange,
  suggestions,
  catalog,
  categoryId,
}: {
  value: string
  onChange: (v: string) => void
  suggestions: readonly BoatManufacturerRecord[]
  /** Pełny katalog — do odwzorowania kraju dla wpisanej nazwy (bez ograniczenia listy sugestii). */
  catalog: readonly BoatManufacturerRecord[]
  categoryId: string
}) {
  const listboxId = useId()
  const wrapRef = useRef<HTMLDivElement>(null)
  const [open, setOpen] = useState(false)
  const [highlight, setHighlight] = useState(-1)

  const q = value.trim().toLowerCase()
  const filtered = useMemo(() => {
    if (!q) return suggestions.slice(0, 80)
    return suggestions.filter((m) => m.name.toLowerCase().includes(q)).slice(0, 80)
  }, [suggestions, q])

  const showPanel = open && filtered.length > 0

  const exactMatch = useMemo(
    () => manufacturerRecordByExactName(value, catalog),
    [value, catalog],
  )

  const pick = useCallback(
    (name: string) => {
      onChange(name)
      setOpen(false)
      setHighlight(-1)
    },
    [onChange],
  )

  useEffect(() => {
    if (!open) return
    const onDoc = (e: MouseEvent) => {
      const el = wrapRef.current
      if (el && !el.contains(e.target as Node)) setOpen(false)
    }
    document.addEventListener('mousedown', onDoc)
    return () => document.removeEventListener('mousedown', onDoc)
  }, [open])

  const noList = categoryId === 'berth' || categoryId === 'accessories'

  return (
    <div ref={wrapRef} className="relative">
      <label className={labelClass} htmlFor={listboxId + '-input'}>
        Producent
      </label>
      <div className="flex gap-2">
        <input
          id={listboxId + '-input'}
          type="text"
          className={`${inputClass} min-w-0 flex-1`}
          value={value}
          autoComplete="off"
          role="combobox"
          aria-expanded={showPanel}
          aria-controls={listboxId}
          aria-autocomplete="list"
          placeholder={noList ? 'Wpisz producenta lub markę' : 'Wpisz lub wybierz z listy'}
          onChange={(e) => {
            onChange(e.target.value)
            setOpen(true)
            setHighlight(-1)
          }}
          onFocus={() => setOpen(true)}
          onKeyDown={(e) => {
            if (!showPanel) {
              if (e.key === 'ArrowDown' && suggestions.length > 0) {
                setOpen(true)
                setHighlight(0)
              }
              return
            }
            if (e.key === 'Escape') {
              setOpen(false)
              setHighlight(-1)
              e.preventDefault()
              return
            }
            if (e.key === 'ArrowDown') {
              setHighlight((h) => Math.min(filtered.length - 1, h + 1))
              e.preventDefault()
              return
            }
            if (e.key === 'ArrowUp') {
              setHighlight((h) => Math.max(0, h - 1))
              e.preventDefault()
              return
            }
            if (e.key === 'Enter' && highlight >= 0 && filtered[highlight]) {
              pick(filtered[highlight].name)
              e.preventDefault()
            }
          }}
        />
        {value.trim() ? (
          <div
            className={`flex shrink-0 items-center justify-center self-stretch rounded-lg border px-2 ${
              exactMatch?.countryCode
                ? 'min-w-[4.25rem] border-blue-100 bg-blue-50/95'
                : 'min-w-[2.75rem] border-dashed border-gray-200 bg-gray-50'
            }`}
            title={
              exactMatch?.countryCode
                ? `Kraj: ${countryRegionNamePl(exactMatch.countryCode)}`
                : 'Brak dokładnego dopasowania do listy lub kraj nieustalony'
            }
          >
            {exactMatch?.countryCode ? (
              <span className="flex flex-col items-center gap-0.5 leading-none">
                <span aria-hidden className="text-xl leading-none">
                  {flagEmojiFromIso2(exactMatch.countryCode)}
                </span>
                <span className="text-[10px] font-bold uppercase tabular-nums text-blue-950">
                  {exactMatch.countryCode}
                </span>
              </span>
            ) : (
              <span className="px-1 text-center text-[10px] font-medium text-gray-400">?</span>
            )}
          </div>
        ) : null}
      </div>
      {showPanel && (
        <ul
          id={listboxId}
          role="listbox"
          className="absolute left-0 right-0 z-[10000] mt-1 max-h-60 overflow-y-auto rounded-lg border border-gray-200 bg-white py-1 shadow-lg"
        >
          {filtered.map((m, i) => {
            const flag = m.countryCode ? flagEmojiFromIso2(m.countryCode) : ''
            const title = m.countryCode
              ? `Kraj: ${countryRegionNamePl(m.countryCode)} (${m.countryCode})`
              : 'Kraj nieokreślony'
            return (
              <li key={m.name} role="presentation">
                <button
                  type="button"
                  role="option"
                  aria-selected={highlight === i}
                  className={`flex w-full items-center gap-2 px-3 py-2 text-left text-sm ${
                    highlight === i ? 'bg-blue-50 text-blue-950' : 'text-gray-900 hover:bg-gray-50'
                  }`}
                  onMouseEnter={() => setHighlight(i)}
                  onMouseDown={(e) => e.preventDefault()}
                  onClick={() => pick(m.name)}
                >
                  <span className="min-w-0 flex-1 truncate">{m.name}</span>
                  <span
                    className="flex shrink-0 items-center gap-1.5 rounded-md border border-gray-100 bg-gray-50/90 px-1.5 py-0.5"
                    title={title}
                  >
                    {m.countryCode ? (
                      <>
                        {flag ? (
                          <span aria-hidden className="text-lg leading-none">
                            {flag}
                          </span>
                        ) : null}
                        <span className="text-[10px] font-bold uppercase tabular-nums text-gray-600">
                          {m.countryCode}
                        </span>
                      </>
                    ) : (
                      <span className="text-[10px] font-medium text-gray-400">—</span>
                    )}
                  </span>
                </button>
              </li>
            )
          })}
        </ul>
      )}
      <p className="mt-1 text-xs text-gray-500">
        {noList
          ? 'Dla tej kategorii nie ma listy producentów — wpisz nazwę ręcznie.'
          : `Sugestie dopasowane do kategorii ogłoszenia: ${suggestions.length} marek. Możesz też podać producenta spoza listy.`}
      </p>
    </div>
  )
})

export default function AddBoatListingModal({
  showTriggerButton = true,
  autoEditListingId = null,
  onAutoEditConsumed,
  onPublished,
  analyticsSource = 'marketplace',
}: {
  showTriggerButton?: boolean
  autoEditListingId?: string | null
  onAutoEditConsumed?: () => void
  onPublished?: () => void
  analyticsSource?: 'marketplace' | 'profile'
} = {}) {
  const [open, setOpen] = useState(false)
  const [step, setStep] = useState(1)
  const [form, setForm] = useState<ListingFormState>(emptyForm)
  const [stepError, setStepError] = useState<string | null>(null)
  const [submitting, setSubmitting] = useState(false)
  const [editingListingId, setEditingListingId] = useState<string | null>(null)
  const titleId = useId()
  const fileInputId = useId()
  const stepScrollRef = useRef<HTMLDivElement>(null)
  const [mounted, setMounted] = useState(false)
  const { data: session, status: sessionStatus } = useSession()

  const manufacturerSuggestions = useMemo(
    () =>
      manufacturersForListingCategory(form.category as ListingManufacturerCategory, BOAT_MANUFACTURER_RECORDS),
    [form.category],
  )

  useEffect(() => {
    setMounted(true)
  }, [])

  useEffect(() => {
    const id = autoEditListingId?.trim()
    if (!id || sessionStatus !== 'authenticated') return
    let cancelled = false
    ;(async () => {
      try {
        const res = await fetch(`/api/listings/${encodeURIComponent(id)}`, { credentials: 'include' })
        const json = (await res.json().catch(() => ({}))) as {
          error?: string
          id?: string
          data?: ListingCoreInput
          photoUrls?: string[]
        }
        if (!res.ok || cancelled) return
        if (!json.data || !json.id) return
        setForm({
          ...emptyForm(),
          ...json.data,
          modelTitle: (json.data.modelTitle ?? '').slice(0, MAX_LISTING_TITLE_LEN),
          wantsInvoiceData: hasAnyInvoiceDetail(json.data as Partial<ListingFormState>),
          photos: [],
          acceptTerms: true,
          serverListingPhotoPaths: [...(json.photoUrls ?? [])],
        })
        setEditingListingId(json.id)
        setStep(1)
        setStepError(null)
        setOpen(true)
        onAutoEditConsumed?.()
      } catch {
        /* sieć */
      }
    })()
    return () => {
      cancelled = true
    }
  }, [autoEditListingId, sessionStatus, onAutoEditConsumed])

  const close = useCallback(() => {
    setOpen(false)
    setStep(1)
    setForm(emptyForm())
    setEditingListingId(null)
    setStepError(null)
    setSubmitting(false)
  }, [])

  useEffect(() => {
    if (!open) return

    const onKey = (e: KeyboardEvent) => {
      if (e.key === 'Escape') close()
    }
    document.addEventListener('keydown', onKey)
    const prevOverflow = document.body.style.overflow
    document.body.style.overflow = 'hidden'
    return () => {
      document.removeEventListener('keydown', onKey)
      document.body.style.overflow = prevOverflow
    }
  }, [open, close])

  const update = useCallback(<K extends keyof ListingFormState>(key: K, value: ListingFormState[K]) => {
    setForm((f) => ({ ...f, [key]: value }))
  }, [])

  const removeServerListingPhoto = useCallback((index: number) => {
    setForm((f) => ({
      ...f,
      serverListingPhotoPaths: f.serverListingPhotoPaths.filter((_, i) => i !== index),
    }))
  }, [])

  const moveServerListingPhoto = useCallback((index: number, delta: -1 | 1) => {
    setForm((f) => {
      const arr = [...f.serverListingPhotoPaths]
      const j = index + delta
      if (j < 0 || j >= arr.length) return f
      const t = arr[index]!
      arr[index] = arr[j]!
      arr[j] = t
      return { ...f, serverListingPhotoPaths: arr }
    })
  }, [])

  const setManufacturer = useCallback((v: string) => {
    setForm((f) => ({ ...f, manufacturer: v }))
  }, [])

  const toggleEquipment = useCallback((id: string) => {
    setForm((f) => ({
      ...f,
      equipment: f.equipment.includes(id) ? f.equipment.filter((x) => x !== id) : [...f.equipment, id],
    }))
  }, [])

  const toggleEngineListingType = useCallback((value: string) => {
    setForm((f) => {
      const on = f.engineListingTypes.includes(value)
      if (on) return { ...f, engineListingTypes: f.engineListingTypes.filter((x) => x !== value) }
      if (f.engineListingTypes.length >= 3) return f
      return { ...f, engineListingTypes: [...f.engineListingTypes, value] }
    })
  }, [])

  const toggleSmallCraftType = useCallback((value: string) => {
    setForm((f) => {
      const on = f.smallCraftTypes.includes(value)
      if (on) return { ...f, smallCraftTypes: f.smallCraftTypes.filter((x) => x !== value) }
      if (f.smallCraftTypes.length >= 3) return f
      return { ...f, smallCraftTypes: [...f.smallCraftTypes, value] }
    })
  }, [])

  const scrollStepPanelToTop = useCallback(() => {
    stepScrollRef.current?.scrollTo({ top: 0, behavior: 'smooth' })
  }, [])

  const showStepError = useCallback(
    (err: string) => {
      setStepError(err)
      scrollStepPanelToTop()
    },
    [scrollStepPanelToTop],
  )

  const validateStep = (s: number): string | null => {
    if (s === 1 && !form.category) return 'Wybierz kategorię ogłoszenia.'
    if (s === 2) {
      if (!form.modelTitle.trim()) return 'Podaj tytuł ogłoszenia.'
      if (form.modelTitle.trim().length > MAX_LISTING_TITLE_LEN) {
        return `Tytuł ogłoszenia może mieć maks. ${MAX_LISTING_TITLE_LEN} znaków.`
      }
      if (!form.yearBuilt.trim()) {
        return form.category === 'engine' ? 'Podaj rok produkcji.' : 'Podaj rok budowy.'
      }
      if (!form.contactPerson.trim()) return 'Podaj osobę kontaktową.'
      if (!form.email.trim()) return 'Podaj adres e-mail.'
      if (!form.country.trim()) return 'Podaj kraj.'
      if (form.category === 'engine' && form.engineListingTypes.length === 0) {
        return 'Wybierz co najmniej jeden typ silnika (maks. 3).'
      }
      if (form.category === 'small' && form.smallCraftTypes.length === 0) {
        return 'Wybierz co najmniej jeden typ jednostki (maks. 3) — jak w formularzu małych łodzi.'
      }
      if (form.offerType !== 'on_request' && parseListingPriceInput(form.price) === null) {
        return 'Podaj cenę w złotych lub wybierz „Cena na zapytanie”.'
      }
    }
    if (s === 5) {
      if (!editingListingId && !form.acceptTerms) {
        return 'Zaakceptuj regulamin, aby opublikować ogłoszenie.'
      }
      if (!form.wantsInvoiceData) return null
      if (!form.invoiceName.trim()) return 'Podaj imię i nazwisko lub nazwę do faktury.'
      if (!form.invoiceStreet.trim()) return 'Podaj ulicę.'
      if (!form.invoiceHouseNo.trim()) return 'Podaj numer domu.'
      if (!form.invoiceZip.trim()) return 'Podaj kod pocztowy.'
      if (!form.invoiceCity.trim()) return 'Podaj miasto.'
      if (!form.invoicePhone.trim()) return 'Podaj telefon do rozliczeń.'
    }
    return null
  }

  const next = () => {
    const err = validateStep(step)
    if (err) {
      showStepError(err)
      return
    }
    setStepError(null)
    trackAnalyticsEvent('listing_form_step', { step_number: Math.min(5, step + 1) })
    setStep((x) => Math.min(5, x + 1))
  }

  const back = () => {
    setStepError(null)
    setStep((x) => Math.max(1, x - 1))
  }

  // const durationPrice = form.duration === '30' ? 69 : form.duration === '60' ? 109 : 149
  // const extras = (form.topOffer ? 139 : 0) + (form.highlight ? 29 : 0)
  // const total = durationPrice + extras

  return (
    <>
      {showTriggerButton ? (
        <button
          type="button"
          onClick={() => {
            trackAnalyticsEvent('listing_form_start', { entry_point: analyticsSource })
            setEditingListingId(null)
            setForm(emptyForm())
            setStep(1)
            setStepError(null)
            setOpen(true)
          }}
          className="inline-flex items-center justify-center rounded-md border border-white/75 bg-white/12 px-3 py-1.5 text-xs font-semibold text-white shadow-sm backdrop-blur-sm transition-[background-color,border-color,box-shadow] duration-200 ease-out hover:border-white/95 hover:bg-white/[0.22] hover:shadow-[0_0_14px_rgba(255,255,255,0.09)] focus:outline-none focus-visible:ring-2 focus-visible:ring-white focus-visible:ring-offset-2 focus-visible:ring-offset-transparent sm:text-[13px]"
        >
          Dodaj ogłoszenie
        </button>
      ) : null}

      {mounted &&
        open &&
        createPortal(
          <div className="fixed inset-0 z-[9999] flex items-center justify-center p-3 sm:p-6">
            <button
              type="button"
              aria-label="Zamknij okno"
              className="absolute inset-0 z-0 cursor-pointer border-0 bg-black/55 backdrop-blur-[2px]"
              onClick={close}
            />

            <div
              role="dialog"
              aria-modal="true"
              aria-labelledby={titleId}
              className="relative z-10 flex max-h-[min(92vh,880px)] w-full max-w-3xl flex-col overflow-hidden rounded-2xl border border-white/25 bg-white shadow-2xl"
              onClick={(e) => e.stopPropagation()}
              onPointerDown={(e) => e.stopPropagation()}
            >
              {/* Nagłówek: zawsze widoczny, duży cel dla zamknięcia */}
              <div className="flex shrink-0 items-center justify-between gap-3 border-b border-gray-200 bg-white px-4 py-3 sm:px-5">
                <div className="min-w-0">
                  <h2 id={titleId} className="truncate text-lg font-bold text-blue-950 sm:text-xl">
                    {editingListingId ? 'Edycja ogłoszenia' : 'Nowe ogłoszenie'}
                  </h2>
                  <p className="truncate text-xs text-gray-500 sm:text-sm">
                    Krok {step} z 5 — {STEPS[step - 1]?.label}
                  </p>
                </div>
                <div className="flex shrink-0 items-center gap-1">
                  <button
                    type="button"
                    onClick={close}
                    className="hidden min-h-[44px] rounded-lg px-3 text-sm font-medium text-gray-600 hover:bg-gray-100 sm:inline-flex sm:items-center"
                  >
                    Zamknij
                  </button>
                  <button
                    type="button"
                    onClick={close}
                    aria-label="Zamknij"
                    className="inline-flex h-12 w-12 shrink-0 items-center justify-center rounded-xl border border-gray-200 bg-gray-50 text-gray-700 shadow-sm hover:bg-gray-100 active:bg-gray-200"
                  >
                    <svg className="h-6 w-6" fill="none" stroke="currentColor" strokeWidth={2} viewBox="0 0 24 24">
                      <path strokeLinecap="round" strokeLinejoin="round" d="M6 18L18 6M6 6l12 12" />
                    </svg>
                  </button>
                </div>
              </div>

              {/* Stepper */}
              <div className="shrink-0 border-b border-gray-100 bg-slate-50 px-3 py-2 sm:px-5">
                <ol className="flex flex-wrap items-center justify-center gap-1 sm:gap-2">
                  {STEPS.map((s) => (
                    <li key={s.id} className="flex items-center">
                      <span
                        className={`flex h-8 min-w-[1.75rem] items-center justify-center rounded-full px-2 text-xs font-semibold sm:h-9 sm:px-2.5 sm:text-sm ${
                          step === s.id
                            ? 'bg-blue-600 text-white'
                            : step > s.id
                              ? 'bg-blue-100 text-blue-800'
                              : 'bg-gray-200 text-gray-600'
                        }`}
                      >
                        {s.id}
                      </span>
                      {s.id < 5 && <span className="mx-0.5 text-gray-300 sm:mx-1">/</span>}
                    </li>
                  ))}
                </ol>
              </div>

              <div
                ref={stepScrollRef}
                className="min-h-0 flex-1 overflow-y-auto overscroll-contain px-4 py-4 sm:px-6"
              >
                <p className="mb-4 text-sm text-gray-600">{STEPS[step - 1]?.desc}</p>

                {stepError && (
                  <div className="mb-4 rounded-lg border border-red-200 bg-red-50 px-3 py-2 text-sm text-red-800">
                    {stepError}
                  </div>
                )}

                {/* Treść kroków bez animacji — stabilny render w portalu. */}
                <div key={step} className="space-y-4 pb-2">
                    {step === 1 && (
                      <div className="grid gap-2 sm:grid-cols-2">
                        {CATEGORIES.map((c) => (
                          <label
                            key={c.id}
                            className={`flex cursor-pointer items-center gap-3 rounded-xl border-2 p-4 transition-colors ${
                              form.category === c.id
                                ? 'border-blue-600 bg-blue-50'
                                : 'border-gray-200 hover:border-gray-300'
                            }`}
                          >
                            <input
                              type="radio"
                              name="category"
                              className="h-4 w-4 text-blue-600"
                              checked={form.category === c.id}
                              onChange={() => update('category', c.id)}
                            />
                            <span className="font-medium text-gray-900">{c.label}</span>
                          </label>
                        ))}
                      </div>
                    )}

                    {step === 2 && (
                      <>
                        <div className="rounded-xl border border-gray-200 bg-white p-4 shadow-sm">
                          <label className={labelClass}>Tytuł ogłoszenia *</label>
                          <input
                            type="text"
                            className={inputClass}
                            value={form.modelTitle}
                            maxLength={MAX_LISTING_TITLE_LEN}
                            onChange={(e) => update('modelTitle', clampListingTitleInput(e.target.value))}
                            aria-describedby="listing-title-counter"
                            placeholder={
                              form.category === 'engine'
                                ? 'Np. producent, model i moc silnika — widoczne w liście'
                                : form.category === 'small'
                                  ? 'Np. producent i model kajaka, SUP, pontonu — widoczne w liście'
                                  : 'Np. producent i model — widoczne w liście ofert'
                            }
                            autoComplete="off"
                          />
                          <p id="listing-title-counter" className="mt-1 text-xs text-gray-500" aria-live="polite">
                            <span className="tabular-nums font-medium text-gray-800">
                              {countWordsInTitle(form.modelTitle)}/{MAX_LISTING_TITLE_WORDS}
                            </span>{' '}
                            słów · max. {MAX_LISTING_TITLE_LEN} znaków.{' '}
                            {form.category === 'engine'
                              ? 'Wzorzec jak w formularzu silnika: model w tytule, jeśli brak na liście producentów.'
                              : form.category === 'small'
                                ? 'Jak w PDF Small boat: sam producent i model w tytule — reszta w polach poniżej.'
                                : 'Pierwsze pole w tym kroku — krótko opisz, co sprzedajesz.'}
                          </p>
                        </div>

                        <NotesPriceFields form={form} update={update} setForm={setForm} />

                        <Section title="Kontakt w ogłoszeniu">
                          <div className="grid gap-3 sm:grid-cols-2">
                            <div>
                              <label className={labelClass}>Osoba kontaktowa *</label>
                              <input
                                type="text"
                                className={inputClass}
                                value={form.contactPerson}
                                onChange={(e) => update('contactPerson', e.target.value)}
                              />
                            </div>
                            <div>
                              <label className={labelClass}>Telefon</label>
                              <input
                                type="tel"
                                className={inputClass}
                                value={form.phone}
                                onChange={(e) => update('phone', e.target.value)}
                              />
                            </div>
                            <div className="sm:col-span-2">
                              <label className={labelClass}>E-mail *</label>
                              <input
                                type="email"
                                className={inputClass}
                                value={form.email}
                                onChange={(e) => update('email', e.target.value)}
                                placeholder="Na ten adres wyślemy potwierdzenie"
                              />
                            </div>
                          </div>
                        </Section>

                        {form.category === 'engine' && (
                          <>
                            <Section title="Szczegóły silnika">
                              <div>
                                <label className={labelClass}>Podtytuł</label>
                                <input
                                  type="text"
                                  className={inputClass}
                                  value={form.subtitle}
                                  onChange={(e) => update('subtitle', e.target.value)}
                                  placeholder="Dodatkowe info widoczne w wynikach wyszukiwania"
                                />
                              </div>
                              <div>
                                <label className={labelClass}>Typ silnika / napędu *</label>
                                <p className="mb-2 text-xs text-gray-500">
                                  Wybierz maks. 3 pozycje z listy — kliknij kafelek, by dodać lub usunąć (wzorzec Boat
                                  Engine).
                                </p>
                                <div className="grid gap-2 sm:grid-cols-2">
                                  {ENGINE_LISTING_PROPULSION_TYPES.map((t) => {
                                    const on = form.engineListingTypes.includes(t.value)
                                    return (
                                      <label
                                        key={t.value}
                                        className={`flex cursor-pointer items-center gap-3 rounded-xl border-2 p-3 text-sm transition-colors ${
                                          on
                                            ? 'border-blue-600 bg-blue-50/90'
                                            : 'border-gray-200 hover:border-gray-300'
                                        }`}
                                      >
                                        <input
                                          type="checkbox"
                                          className="h-4 w-4 rounded border-gray-300 text-blue-600"
                                          checked={on}
                                          onChange={() => toggleEngineListingType(t.value)}
                                        />
                                        <span className={`font-medium ${on ? 'text-blue-950' : 'text-gray-800'}`}>
                                          {t.label}
                                        </span>
                                      </label>
                                    )
                                  })}
                                </div>
                              </div>
                              <div className="max-w-xl">
                                <ManufacturerField
                                  value={form.manufacturer}
                                  onChange={setManufacturer}
                                  suggestions={manufacturerSuggestions}
                                  catalog={BOAT_MANUFACTURER_RECORDS}
                                  categoryId={form.category}
                                />
                              </div>
                              <p className="text-xs text-gray-500">
                                Jeśli nie ma producenta na liście, wpisz nazwę w tytule ogłoszenia.
                              </p>
                            </Section>

                            <Section title="Parametry">
                              <p className="mb-3 text-xs text-gray-500">
                                Stan, sterowanie i paliwo — z listy. Rok produkcji — lista podpowiedzi lub własna
                                wartość. Masa, liczba, moc i motogodziny:{' '}
                                <span className="tabular-nums">−</span> / <span className="tabular-nums">+</span> lub wpis.
                              </p>
                              <div className="grid gap-3 sm:grid-cols-2">
                                <YearCombobox
                                  label="Rok produkcji *"
                                  value={form.yearBuilt}
                                  onChange={(v) => update('yearBuilt', v)}
                                />
                                <div>
                                  <label className={labelClass}>Stan</label>
                                  <select
                                    className={inputClass}
                                    value={form.condition}
                                    onChange={(e) => update('condition', e.target.value)}
                                  >
                                    <option value="">— wybierz z listy —</option>
                                    <option value="used">Używany</option>
                                    <option value="new">Nowy</option>
                                    <option value="refit">Po remoncie</option>
                                    <option value="project">Do remontu / na części</option>
                                  </select>
                                </div>
                                <div>
                                  <label className={labelClass}>Sterowanie</label>
                                  <select
                                    className={inputClass}
                                    value={form.steeringType}
                                    onChange={(e) => update('steeringType', e.target.value)}
                                  >
                                    <option value="">— wybierz z listy —</option>
                                    {ENGINE_STEERING_TYPES.map((s) => (
                                      <option key={s.value} value={s.value}>
                                        {s.label}
                                      </option>
                                    ))}
                                  </select>
                                </div>
                                <IntStepper
                                  label="Masa (kg)"
                                  min={0}
                                  max={800}
                                  step={5}
                                  value={form.weightKg}
                                  onChange={(v) => update('weightKg', v)}
                                />
                                <div className="sm:col-span-2">
                                  <label className={labelClass}>Paliwo</label>
                                  <select
                                    className={inputClass}
                                    value={form.fuelType}
                                    onChange={(e) => update('fuelType', e.target.value)}
                                  >
                                    <option value="">— wybierz z listy —</option>
                                    {BOAT_ENGINE_FUEL_TYPES.map((f) => (
                                      <option key={f.value} value={f.value}>
                                        {f.label}
                                      </option>
                                    ))}
                                  </select>
                                </div>
                              </div>
                              <div className="mt-4 flex flex-col gap-3 sm:flex-row sm:flex-wrap sm:items-end">
                                <IntStepper
                                  label="Liczba silników"
                                  min={0}
                                  max={6}
                                  value={form.engineCount}
                                  onChange={(v) => update('engineCount', v)}
                                />
                                <HpStepper
                                  label="Moc (KM)"
                                  value={form.enginePowerHp}
                                  onChange={(v) => update('enginePowerHp', v)}
                                />
                                <IntStepper
                                  label="Motogodziny"
                                  min={0}
                                  max={50000}
                                  step={50}
                                  value={form.engineHours}
                                  onChange={(v) => update('engineHours', v)}
                                />
                              </div>
                              <p className="mt-2 text-xs text-gray-500">
                                Motogodziny: przyciski co 50 h — dokładną wartość możesz wpisać w polu.
                              </p>
                            </Section>

                            <Section title="Wyposażenie dodatkowe (opcjonalnie)">
                              <EquipmentPicker equipment={form.equipment} onToggle={toggleEquipment} />
                            </Section>
                          </>
                        )}

                        {form.category !== 'engine' && (
                          <>
                            {form.category === 'small' ? (
                              <>
                                <Section title="Typ jednostki *">
                                  <p className="mb-2 text-xs text-gray-600">
                                    Jak w formularzu PDF (Small boat): wybierz do <strong>3</strong> pozycji —
                                    kliknij kafelek, by dodać lub usunąć.
                                  </p>
                                  <div className="grid gap-2 sm:grid-cols-2">
                                    {SMALL_CRAFT_TYPES.map((t) => {
                                      const on = form.smallCraftTypes.includes(t.value)
                                      return (
                                        <label
                                          key={t.value}
                                          className={`flex cursor-pointer items-center gap-3 rounded-xl border-2 p-3 text-sm transition-colors ${
                                            on
                                              ? 'border-blue-600 bg-blue-50/90'
                                              : 'border-gray-200 hover:border-gray-300'
                                          }`}
                                        >
                                          <input
                                            type="checkbox"
                                            className="h-4 w-4 rounded border-gray-300 text-blue-600"
                                            checked={on}
                                            onChange={() => toggleSmallCraftType(t.value)}
                                          />
                                          <span className={`font-medium ${on ? 'text-blue-950' : 'text-gray-800'}`}>
                                            {t.label}
                                          </span>
                                        </label>
                                      )
                                    })}
                                  </div>
                                </Section>

                                <Section title="Podstawowe">
                                  <div className="grid gap-3 sm:grid-cols-2">
                                    <ManufacturerField
                                      value={form.manufacturer}
                                      onChange={setManufacturer}
                                      suggestions={manufacturerSuggestions}
                                      catalog={BOAT_MANUFACTURER_RECORDS}
                                      categoryId={form.category}
                                    />
                                    <div>
                                      <label className={labelClass}>Podtytuł</label>
                                      <input
                                        type="text"
                                        className={inputClass}
                                        value={form.subtitle}
                                        onChange={(e) => update('subtitle', e.target.value)}
                                        placeholder="Dodatkowe info widoczne w wynikach wyszukiwania"
                                      />
                                    </div>
                                  </div>
                                  <div className="grid gap-3 sm:grid-cols-2">
                                    <YearCombobox
                                      label="Rok budowy *"
                                      value={form.yearBuilt}
                                      onChange={(v) => update('yearBuilt', v)}
                                    />
                                    <div>
                                      <label className={labelClass}>Stan</label>
                                      <select
                                        className={inputClass}
                                        value={form.condition}
                                        onChange={(e) => update('condition', e.target.value)}
                                      >
                                        <option value="">— wybierz —</option>
                                        <option value="used">Używana</option>
                                        <option value="new">Nowy</option>
                                        <option value="refit">Po remoncie</option>
                                        <option value="project">Do remontu</option>
                                      </select>
                                    </div>
                                  </div>
                                </Section>

                                <Section title="Materiał i wymiary">
                                  <div className="grid gap-3 sm:grid-cols-2">
                                    <div>
                                      <label className={labelClass}>Materiał</label>
                                      <select
                                        className={inputClass}
                                        value={form.material}
                                        onChange={(e) => update('material', e.target.value)}
                                      >
                                        <option value="">— wybierz —</option>
                                        {SMALL_HULL_MATERIALS.map((m) => (
                                          <option key={m.value} value={m.value}>
                                            {m.label}
                                          </option>
                                        ))}
                                      </select>
                                    </div>
                                    <div>
                                      <label className={labelClass}>Znak CE / kategoria projektowa</label>
                                      <input
                                        type="text"
                                        className={inputClass}
                                        value={form.ceMarking}
                                        onChange={(e) => update('ceMarking', e.target.value)}
                                        placeholder="np. C, kategoria D — jeśli dotyczy"
                                      />
                                    </div>
                                    <div>
                                      <label className={labelClass}>Długość (m)</label>
                                      <input
                                        type="text"
                                        className={inputShortClass}
                                        value={form.lengthM}
                                        onChange={(e) => update('lengthM', e.target.value)}
                                      />
                                    </div>
                                    <div>
                                      <label className={labelClass}>Szerokość (m)</label>
                                      <input
                                        type="text"
                                        className={inputShortClass}
                                        value={form.beamM}
                                        onChange={(e) => update('beamM', e.target.value)}
                                      />
                                    </div>
                                    <div>
                                      <label className={labelClass}>Masa (kg)</label>
                                      <input
                                        type="text"
                                        className={inputShortClass}
                                        value={form.weightKg}
                                        onChange={(e) => update('weightKg', e.target.value)}
                                      />
                                    </div>
                                    <div>
                                      <label className={labelClass}>Liczba osób (max.)</label>
                                      <input
                                        type="text"
                                        inputMode="numeric"
                                        className={inputShortClass}
                                        value={form.maxPersons}
                                        onChange={(e) => update('maxPersons', e.target.value)}
                                      />
                                    </div>
                                  </div>
                                </Section>

                                <Section title="Napęd (jeśli dotyczy)">
                                  <div className="grid gap-3 sm:grid-cols-2">
                                    <div>
                                      <label className={labelClass}>Napęd / silnik</label>
                                      <select
                                        className={inputClass}
                                        value={form.propulsion}
                                        onChange={(e) => update('propulsion', e.target.value)}
                                      >
                                        <option value="">— wybierz —</option>
                                        {BOAT_PROPULSION_TYPES.map((p) => (
                                          <option key={p.value} value={p.value}>
                                            {p.label}
                                          </option>
                                        ))}
                                      </select>
                                    </div>
                                    <div>
                                      <label className={labelClass}>Paliwo</label>
                                      <select
                                        className={inputClass}
                                        value={form.fuelType}
                                        onChange={(e) => update('fuelType', e.target.value)}
                                      >
                                        <option value="">— wybierz —</option>
                                        {BOAT_ENGINE_FUEL_TYPES.map((f) => (
                                          <option key={f.value} value={f.value}>
                                            {f.label}
                                          </option>
                                        ))}
                                      </select>
                                    </div>
                                  </div>
                                  <div className="mt-3 flex flex-col gap-3 sm:flex-row sm:flex-wrap sm:items-end">
                                    <IntStepper
                                      label="Liczba silników"
                                      min={0}
                                      max={6}
                                      value={form.engineCount}
                                      onChange={(v) => update('engineCount', v)}
                                    />
                                    <HpStepper
                                      label="Moc łącznie (KM)"
                                      value={form.enginePowerHp}
                                      onChange={(v) => update('enginePowerHp', v)}
                                    />
                                    <IntStepper
                                      label="Motogodziny"
                                      min={0}
                                      max={50000}
                                      step={50}
                                      value={form.engineHours}
                                      onChange={(v) => update('engineHours', v)}
                                    />
                                  </div>
                                  <p className="mt-2 text-xs text-gray-500">
                                    Przy jednostce bez silnika wybierz „Brak silnika” i zostaw 0 przy liczbie silników.
                                  </p>
                                </Section>

                                <Section title="Dodatkowo (jak w PDF)">
                                  <div className="space-y-3">
                                    <label className="flex cursor-pointer items-start gap-3 rounded-lg border border-gray-200 bg-white p-3 text-sm">
                                      <input
                                        type="checkbox"
                                        className="mt-0.5 h-4 w-4 rounded border-gray-300 text-blue-600"
                                        checked={form.trailerIncluded}
                                        onChange={(e) => update('trailerIncluded', e.target.checked)}
                                      />
                                      <span>
                                        <span className="font-medium text-gray-900">Przyczepa / transport w zestawie</span>
                                        <span className="mt-0.5 block text-xs text-gray-500">
                                          Odpowiednik „trailer included” — zaznacz, jeśli dokładasz lawetę lub przyczepę.
                                        </span>
                                      </span>
                                    </label>
                                    <label className="flex cursor-pointer items-start gap-3 rounded-lg border border-gray-200 bg-white p-3 text-sm">
                                      <input
                                        type="checkbox"
                                        className="mt-0.5 h-4 w-4 rounded border-gray-300 text-blue-600"
                                        checked={form.berthAvailable}
                                        onChange={(e) => update('berthAvailable', e.target.checked)}
                                      />
                                      <span>
                                        <span className="font-medium text-gray-900">Możliwość postoju</span>
                                        <span className="mt-0.5 block text-xs text-gray-500">
                                          Np. miejsce w marinie lub na kei (odpowiednik „berth available”).
                                        </span>
                                      </span>
                                    </label>
                                  </div>
                                </Section>

                                <Section title="Wyposażenie — zaznacz, jeśli dotyczy">
                                  <EquipmentPicker equipment={form.equipment} onToggle={toggleEquipment} />
                                </Section>
                              </>
                            ) : (
                              <>
                        <Section title="Podstawowe">
                          <div>
                            <label className={labelClass}>Typ jednostki</label>
                            <select
                              className={inputClass}
                              value={form.boatType}
                              onChange={(e) => update('boatType', e.target.value)}
                            >
                              <option value="">— wybierz z listy —</option>
                              {BOAT_HULL_TYPES.map((t) => (
                                <option key={t.value} value={t.value}>
                                  {t.label}
                                </option>
                              ))}
                            </select>
                            <p className="mt-1 text-xs text-gray-500">
                              Nazwy angielskie w nawiasach — w ofercie widoczna jest polska forma.
                            </p>
                          </div>
                          <div className="grid gap-3 sm:grid-cols-2">
                            <ManufacturerField
                              value={form.manufacturer}
                              onChange={setManufacturer}
                              suggestions={manufacturerSuggestions}
                              catalog={BOAT_MANUFACTURER_RECORDS}
                              categoryId={form.category}
                            />
                            <div>
                              <label className={labelClass}>Podtytuł</label>
                              <input
                                type="text"
                                className={inputClass}
                                value={form.subtitle}
                                onChange={(e) => update('subtitle', e.target.value)}
                                placeholder="Dodatkowe info widoczne w wynikach wyszukiwania"
                              />
                            </div>
                          </div>
                          <div className="grid gap-3 sm:grid-cols-2">
                            <YearCombobox
                              label="Rok budowy *"
                              value={form.yearBuilt}
                              onChange={(v) => update('yearBuilt', v)}
                            />
                            <div>
                              <label className={labelClass}>Stan</label>
                              <select
                                className={inputClass}
                                value={form.condition}
                                onChange={(e) => update('condition', e.target.value)}
                              >
                                <option value="">— wybierz —</option>
                                <option value="used">Używana</option>
                                <option value="new">Nowy</option>
                                <option value="refit">Po remoncie</option>
                                <option value="project">Do remontu</option>
                              </select>
                            </div>
                          </div>
                        </Section>

                        <Section title="Kadłub i wymiary">
                          <div className="grid gap-3 sm:grid-cols-2">
                            <div>
                              <label className={labelClass}>Materiał</label>
                              <select
                                className={inputClass}
                                value={form.material}
                                onChange={(e) => update('material', e.target.value)}
                              >
                                <option value="">— wybierz —</option>
                                {BOAT_HULL_MATERIALS.map((m) => (
                                  <option key={m.value} value={m.value}>
                                    {m.label}
                                  </option>
                                ))}
                              </select>
                            </div>
                            <div>
                              <label className={labelClass}>Typ kilu</label>
                              <select
                                className={inputClass}
                                value={form.keelType}
                                onChange={(e) => update('keelType', e.target.value)}
                              >
                                <option value="">— wybierz —</option>
                                {BOAT_KEEL_TYPES.map((k) => (
                                  <option key={k.value} value={k.value}>
                                    {k.label}
                                  </option>
                                ))}
                              </select>
                            </div>
                            <div>
                              <label className={labelClass}>Ster</label>
                              <input
                                type="text"
                                className={inputClass}
                                value={form.steering}
                                onChange={(e) => update('steering', e.target.value)}
                                placeholder="np. koło sterowe, stera zawiasowa"
                              />
                            </div>
                            <div>
                              <label className={labelClass}>Długość (m)</label>
                              <input
                                type="text"
                                className={inputShortClass}
                                value={form.lengthM}
                                onChange={(e) => update('lengthM', e.target.value)}
                              />
                            </div>
                            <div>
                              <label className={labelClass}>Szerokość (m)</label>
                              <input
                                type="text"
                                className={inputShortClass}
                                value={form.beamM}
                                onChange={(e) => update('beamM', e.target.value)}
                              />
                            </div>
                            <div>
                              <label className={labelClass}>Maks. zanurzenie (m)</label>
                              <input
                                type="text"
                                className={inputShortClass}
                                value={form.maxDraftM}
                                onChange={(e) => update('maxDraftM', e.target.value)}
                              />
                            </div>
                            <div>
                              <label className={labelClass}>Zanurzenie (kil w górze) (m)</label>
                              <input
                                type="text"
                                className={inputShortClass}
                                value={form.draftKeelUpM}
                                onChange={(e) => update('draftKeelUpM', e.target.value)}
                              />
                            </div>
                            <div>
                              <label className={labelClass}>Prześwit pod mostem (m)</label>
                              <input
                                type="text"
                                className={inputShortClass}
                                value={form.bridgeClearanceM}
                                onChange={(e) => update('bridgeClearanceM', e.target.value)}
                              />
                            </div>
                            <div>
                              <label className={labelClass}>Masa (kg)</label>
                              <input
                                type="text"
                                className={inputShortClass}
                                value={form.weightKg}
                                onChange={(e) => update('weightKg', e.target.value)}
                              />
                            </div>
                            <div>
                              <label className={labelClass}>Balast (kg)</label>
                              <input
                                type="text"
                                className={inputShortClass}
                                value={form.ballastKg}
                                onChange={(e) => update('ballastKg', e.target.value)}
                              />
                            </div>
                            <div>
                              <label className={labelClass}>Znak CE / kategoria</label>
                              <input
                                type="text"
                                className={inputShortClass}
                                value={form.ceMarking}
                                onChange={(e) => update('ceMarking', e.target.value)}
                              />
                            </div>
                            <div>
                              <label className={labelClass}>Liczba osób (max)</label>
                              <input
                                type="text"
                                inputMode="numeric"
                                className={inputShortClass}
                                value={form.maxPersons}
                                onChange={(e) => update('maxPersons', e.target.value)}
                              />
                            </div>
                          </div>
                        </Section>

                        <Section title="Ożaglowanie (jeśli dotyczy)">
                          <div className="grid gap-3 sm:grid-cols-2">
                            <div>
                              <label className={labelClass}>Typ masztu</label>
                              <select
                                className={inputClass}
                                value={form.mastMaterial}
                                onChange={(e) => update('mastMaterial', e.target.value)}
                              >
                                <option value="">— wybierz —</option>
                                {BOAT_MAST_TYPES.map((m) => (
                                  <option key={m.value} value={m.value}>
                                    {m.label}
                                  </option>
                                ))}
                              </select>
                            </div>
                            <div>
                              <label className={labelClass}>Wysokość masztu (m)</label>
                              <input
                                type="text"
                                className={inputShortClass}
                                value={form.mastHeightM}
                                onChange={(e) => update('mastHeightM', e.target.value)}
                              />
                            </div>
                            <div>
                              <label className={labelClass}>Grot (m²)</label>
                              <input
                                type="text"
                                className={inputShortClass}
                                value={form.mainsailM2}
                                onChange={(e) => update('mainsailM2', e.target.value)}
                              />
                            </div>
                            <div>
                              <label className={labelClass}>Fok (m²)</label>
                              <input
                                type="text"
                                className={inputShortClass}
                                value={form.jibM2}
                                onChange={(e) => update('jibM2', e.target.value)}
                              />
                            </div>
                            <div>
                              <label className={labelClass}>Genoa (m²)</label>
                              <input
                                type="text"
                                className={inputShortClass}
                                value={form.genoaM2}
                                onChange={(e) => update('genoaM2', e.target.value)}
                              />
                            </div>
                            <div className="sm:col-span-2">
                              <label className={labelClass}>Łącznie (m²)</label>
                              <input
                                type="text"
                                className={inputShortClass}
                                value={form.sailsTotalM2}
                                onChange={(e) => update('sailsTotalM2', e.target.value)}
                                placeholder="np. gdy znasz tylko sumę powierzchni żagli"
                              />
                            </div>
                          </div>
                        </Section>

                        <Section title="Silnik">
                          <div className="grid gap-3 sm:grid-cols-2">
                            <div>
                              <label className={labelClass}>Napęd / typ silnika</label>
                              <select
                                className={inputClass}
                                value={form.propulsion}
                                onChange={(e) => update('propulsion', e.target.value)}
                              >
                                <option value="">— wybierz —</option>
                                {BOAT_PROPULSION_TYPES.map((p) => (
                                  <option key={p.value} value={p.value}>
                                    {p.label}
                                  </option>
                                ))}
                              </select>
                            </div>
                            <div>
                              <label className={labelClass}>Paliwo</label>
                              <select
                                className={inputClass}
                                value={form.fuelType}
                                onChange={(e) => update('fuelType', e.target.value)}
                              >
                                <option value="">— wybierz —</option>
                                {BOAT_ENGINE_FUEL_TYPES.map((f) => (
                                  <option key={f.value} value={f.value}>
                                    {f.label}
                                  </option>
                                ))}
                              </select>
                            </div>
                          </div>
                          <div className="mt-3 flex flex-col gap-3 sm:flex-row sm:flex-wrap sm:items-end">
                            <IntStepper
                              label="Liczba silników"
                              min={0}
                              max={6}
                              value={form.engineCount}
                              onChange={(v) => update('engineCount', v)}
                            />
                            <HpStepper
                              label="Moc łącznie (KM)"
                              value={form.enginePowerHp}
                              onChange={(v) => update('enginePowerHp', v)}
                            />
                            <IntStepper
                              label="Motogodziny"
                              min={0}
                              max={50000}
                              step={50}
                              value={form.engineHours}
                              onChange={(v) => update('engineHours', v)}
                            />
                          </div>
                          <p className="mt-2 text-xs text-gray-500">
                            Motogodziny: przyciski co 50 h — dokładną wartość możesz wpisać w polu.
                          </p>
                          <div className="mt-3">
                            <label className={labelClass}>Zbiornik paliwa (l)</label>
                            <input
                              type="text"
                              inputMode="decimal"
                              className={inputShortClass}
                              value={form.fuelTankL}
                              onChange={(e) => update('fuelTankL', e.target.value)}
                            />
                          </div>
                        </Section>

                        <Section title="Wnętrze">
                          <div className="grid grid-cols-3 gap-2 sm:gap-3">
                            <IntStepper
                              label="Kabiny"
                              min={0}
                              max={12}
                              value={form.cabins}
                              onChange={(v) => update('cabins', v)}
                            />
                            <IntStepper
                              label="Miejsca"
                              min={0}
                              max={24}
                              value={form.berths}
                              onChange={(v) => update('berths', v)}
                            />
                            <IntStepper
                              label="Toalety"
                              min={0}
                              max={8}
                              value={form.heads}
                              onChange={(v) => update('heads', v)}
                            />
                          </div>
                          <div className="mt-3 grid gap-3 sm:grid-cols-2">
                            <div>
                              <label className={labelClass}>Wysokość w kabinie (m)</label>
                              <input
                                type="text"
                                className={inputShortClass}
                                value={form.headroomM}
                                onChange={(e) => update('headroomM', e.target.value)}
                              />
                            </div>
                            <div>
                              <label className={labelClass}>Zbiornik wody słodkiej (l)</label>
                              <input
                                type="text"
                                className={inputShortClass}
                                value={form.freshWaterL}
                                onChange={(e) => update('freshWaterL', e.target.value)}
                              />
                            </div>
                            <div>
                              <label className={labelClass}>Zbiornik fekaliów (l)</label>
                              <input
                                type="text"
                                className={inputShortClass}
                                value={form.holdingTankL}
                                onChange={(e) => update('holdingTankL', e.target.value)}
                              />
                            </div>
                          </div>
                        </Section>

                        <Section title="Wyposażenie — zaznacz, co jest na jachcie">
                          <EquipmentPicker equipment={form.equipment} onToggle={toggleEquipment} />
                        </Section>
                              </>
                            )}
                          </>
                        )}

                        <Section title="Multimedia i lokalizacja">
                          <div>
                            <label className={labelClass}>Link do filmu YouTube</label>
                            <input
                              type="url"
                              className={inputClass}
                              value={form.youtubeUrl}
                              onChange={(e) => update('youtubeUrl', e.target.value)}
                              placeholder="https://youtu.be/…"
                            />
                          </div>
                          <div className="grid gap-3 sm:grid-cols-3">
                            <div>
                              <label className={labelClass}>Kraj *</label>
                              <input
                                type="text"
                                className={inputClass}
                                value={form.country}
                                onChange={(e) => update('country', e.target.value)}
                              />
                            </div>
                            <div>
                              <label className={labelClass}>Województwo</label>
                              <select
                                className={inputClass}
                                value={form.region}
                                onChange={(e) => update('region', e.target.value)}
                              >
                                <option value="">— wybierz —</option>
                                {POLISH_VOIVODESHIPS.map((voiv) => (
                                  <option key={voiv} value={voiv}>
                                    {voiv.replace(/^./, (c) => c.toLocaleUpperCase('pl-PL'))}
                                  </option>
                                ))}
                              </select>
                            </div>
                            <div>
                              <label className={labelClass}>Lokalizacja (port, miasto)</label>
                              <input
                                type="text"
                                className={inputClass}
                                value={form.location}
                                onChange={(e) => update('location', e.target.value)}
                              />
                            </div>
                          </div>
                        </Section>
                      </>
                    )}

                    {step === 3 && (
                      <div className="space-y-4">
                        <p className="text-sm text-gray-600">
                          Zdjęcia zapisujemy na serwerze po publikacji ogłoszenia (format na dysku: JPEG, PNG, WebP
                          lub GIF — wg treści pliku, bez konwersji). Maks. 10 MB na plik, do 25 zdjęć naraz. HEIC
                          z iPhone&apos;a przed wysłaniem zapisz proszę jako JPEG. W razie problemów napisz na{' '}
                          <a href="mailto:kontakt@twojalodka.pl" className="font-medium text-blue-600 underline">
                            kontakt@twojalodka.pl
                          </a>
                          .
                        </p>
                        <input
                          id={fileInputId}
                          type="file"
                          accept=".jpg,.jpeg,.webp,.png,.gif"
                          multiple
                          className="sr-only"
                          onChange={(e) => {
                            const list = e.target.files ? Array.from(e.target.files) : []
                            setForm((f) => ({ ...f, photos: list }))
                          }}
                        />
                        <label
                          htmlFor={fileInputId}
                          className="flex min-h-[140px] cursor-pointer flex-col items-center justify-center rounded-xl border-2 border-dashed border-gray-300 bg-gray-50 px-4 py-8 text-center transition-colors hover:border-blue-400 hover:bg-blue-50/50"
                          onDragOver={(e) => {
                            e.preventDefault()
                            e.stopPropagation()
                          }}
                          onDrop={(e) => {
                            e.preventDefault()
                            e.stopPropagation()
                            const files = Array.from(e.dataTransfer.files ?? []).filter((f) =>
                              /^image\//.test(f.type)
                            )
                            if (files.length) setForm((f) => ({ ...f, photos: files }))
                          }}
                        >
                          <span className="text-sm font-medium text-blue-700">Dodaj zdjęcia</span>
                          <span className="mt-1 text-xs text-gray-500">
                            Kliknij lub przeciągnij pliki (obsługa przeglądarki: wybór przez okno systemowe)
                          </span>
                        </label>
                        {form.photos.length > 0 && (
                          <ul className="max-h-40 space-y-1 overflow-y-auto rounded-lg border border-gray-200 bg-white p-3 text-sm">
                            {form.photos.map((file, i) => (
                              <li key={`${file.name}-${i}`} className="flex justify-between gap-2 text-gray-700">
                                <span className="truncate">{file.name}</span>
                                <span className="shrink-0 text-gray-400">
                                  {(file.size / 1024 / 1024).toFixed(1)} MB
                                </span>
                              </li>
                            ))}
                          </ul>
                        )}
                        <label className="flex items-center gap-2 text-sm text-gray-600">
                          <input
                            type="checkbox"
                            className="h-4 w-4 rounded border-gray-300"
                            onChange={(e) => {
                              if (e.target.checked) setForm((f) => ({ ...f, photos: [] }))
                            }}
                          />
                          Dodam zdjęcia później (np. mailem)
                        </label>
                        {editingListingId ? (
                          <div className="rounded-xl border border-amber-200 bg-amber-50/80 p-3">
                            <label className={labelClass}>Zdjęcia w witrynie</label>
                            <p className="mb-3 text-xs text-gray-600">
                              <span className="font-medium text-gray-800">Pierwsze zdjęcie</span> w siatce to zdjęcie
                              główne (miniatura i nagłówek). Strzałkami zmieniasz kolejność, „Usuń” usuwa pozycję z
                              galerii (po zapisie). Jeśli na tym kroku wybierzesz nowe pliki i zapiszesz ogłoszenie,
                              wgrane pliki{' '}
                              <span className="font-medium text-gray-800">zastąpią całą obecną galerię</span>.
                            </p>
                            {form.serverListingPhotoPaths.length > 0 ? (
                              <div className="grid grid-cols-3 gap-2 sm:grid-cols-4 md:grid-cols-5">
                                {form.serverListingPhotoPaths.map((path, i) => {
                                  const n = form.serverListingPhotoPaths.length
                                  return (
                                    <div
                                      key={`${i}-${path}`}
                                      className="relative flex flex-col gap-1 rounded-lg"
                                    >
                                      <ListingEditPhotoThumb src={path} isMain={i === 0} />
                                      <div className="flex flex-wrap gap-1">
                                        <button
                                          type="button"
                                          disabled={i === 0}
                                          onClick={() => moveServerListingPhoto(i, -1)}
                                          className="min-h-0 flex-1 rounded border border-gray-300 bg-white px-1 py-1 text-[10px] font-medium text-gray-700 hover:bg-gray-50 disabled:cursor-not-allowed disabled:opacity-40"
                                          title="W lewo (wcześniej w galerii)"
                                        >
                                          ←
                                        </button>
                                        <button
                                          type="button"
                                          disabled={i >= n - 1}
                                          onClick={() => moveServerListingPhoto(i, 1)}
                                          className="min-h-0 flex-1 rounded border border-gray-300 bg-white px-1 py-1 text-[10px] font-medium text-gray-700 hover:bg-gray-50 disabled:cursor-not-allowed disabled:opacity-40"
                                          title="W prawo (później w galerii)"
                                        >
                                          →
                                        </button>
                                        <button
                                          type="button"
                                          onClick={() => removeServerListingPhoto(i)}
                                          className="w-full rounded border border-red-200 bg-white px-1 py-1 text-[10px] font-medium text-red-700 hover:bg-red-50"
                                        >
                                          Usuń
                                        </button>
                                      </div>
                                    </div>
                                  )
                                })}
                              </div>
                            ) : (
                              <p className="rounded-lg border border-dashed border-amber-300/80 bg-white/60 px-3 py-4 text-center text-sm text-gray-600">
                                Brak zdjęć przy ogłoszeniu — możesz wgrać pliki powyżej (przy zapisie zastąpią galerię)
                                lub zostawić pusto (galeria zostanie usunięta po zapisie).
                              </p>
                            )}
                          </div>
                        ) : null}
                      </div>
                    )}

                    {step === 4 && (
                      <div className="space-y-6">
                        <div>
                          <h3 className="mb-3 text-sm font-semibold text-blue-950">Czas publikacji</h3>
                          <div className="grid gap-3 sm:grid-cols-3">
                            {(
                              [
                                { id: '30' as const, days: '30 dni', rec: false },
                                { id: '60' as const, days: '60 dni', rec: true },
                                { id: '90' as const, days: '90 dni', rec: false },
                              ] as const
                            ).map((opt) => (
                              <label
                                key={opt.id}
                                className={`relative flex cursor-pointer flex-col rounded-xl border-2 p-4 transition-colors ${
                                  form.duration === opt.id
                                    ? 'border-blue-600 bg-blue-50'
                                    : 'border-gray-200 hover:border-gray-300'
                                }`}
                              >
                                <input
                                  type="radio"
                                  name="duration"
                                  className="sr-only"
                                  checked={form.duration === opt.id}
                                  onChange={() => update('duration', opt.id)}
                                />
                                <span className="font-semibold text-gray-900">{opt.days}</span>
                                {opt.rec && (
                                  <span className="mt-1 text-xs font-medium text-green-700">Polecane</span>
                                )}
                              </label>
                            ))}
                          </div>
                        </div>
                        {/* Promowanie — tymczasowo wyłączone (przywróć po uruchomieniu płatnych opcji)
                        <div>
                          <h3 className="mb-3 text-sm font-semibold text-blue-950">Opcje promowania (dodatkowo)</h3>
                          <label className="mb-3 flex cursor-pointer items-start gap-3 rounded-xl border border-gray-200 p-4 hover:bg-gray-50">
                            <input
                              type="checkbox"
                              className="mt-1 h-4 w-4 rounded border-gray-300 text-blue-600"
                              checked={form.topOffer}
                              onChange={(e) => update('topOffer', e.target.checked)}
                            />
                            <div>
                              <span className="font-medium text-gray-900">Oferta na górze listy</span>
                              <p className="text-sm text-gray-600">
                                Większa widoczność w wynikach wyszukiwania (rotacja z innymi ofertami TOP).
                              </p>
                              <span className="text-sm font-semibold text-blue-700">+ 139 zł / 30 dni</span>
                            </div>
                          </label>
                          <label className="flex cursor-pointer items-start gap-3 rounded-xl border border-gray-200 p-4 hover:bg-gray-50">
                            <input
                              type="checkbox"
                              className="mt-1 h-4 w-4 rounded border-gray-300 text-blue-600"
                              checked={form.highlight}
                              onChange={(e) => update('highlight', e.target.checked)}
                            />
                            <div>
                              <span className="font-medium text-gray-900">Wyróżnienie kolorem</span>
                              <p className="text-sm text-gray-600">
                                Kolorowe tło wpisu w liście — od razu rzuca się w oczy.
                              </p>
                              <span className="text-sm font-semibold text-blue-700">+ 29 zł / 30 dni</span>
                            </div>
                          </label>
                        </div>
                        */}
                      </div>
                    )}

                    {step === 5 && (
                      <div className="space-y-4">
                        <div className="rounded-xl border border-gray-200 bg-slate-50 p-4 text-sm">
                          <h3 className="mb-2 font-semibold text-blue-950">Podsumowanie</h3>
                          <dl className="grid gap-2 sm:grid-cols-2">
                            <div>
                              <dt className="text-gray-500">Kategoria</dt>
                              <dd className="font-medium">
                                {CATEGORIES.find((c) => c.id === form.category)?.label ?? '—'}
                              </dd>
                            </div>
                            {form.category === 'engine' ? (
                              <>
                                <div>
                                  <dt className="text-gray-500">Typ silnika (do 3)</dt>
                                  <dd className="font-medium">
                                    {form.engineListingTypes.length
                                      ? form.engineListingTypes
                                          .map(
                                            (v) =>
                                              BOAT_PROPULSION_TYPES.find((p) => p.value === v)?.label ?? v,
                                          )
                                          .join(', ')
                                      : '—'}
                                  </dd>
                                </div>
                                <div>
                                  <dt className="text-gray-500">Producent</dt>
                                  <dd>
                                    <ProducerSummaryDd name={form.manufacturer} catalog={BOAT_MANUFACTURER_RECORDS} />
                                  </dd>
                                </div>
                                <div>
                                  <dt className="text-gray-500">Rok produkcji</dt>
                                  <dd className="font-medium">{form.yearBuilt || '—'}</dd>
                                </div>
                                <div>
                                  <dt className="text-gray-500">Stan</dt>
                                  <dd className="font-medium">
                                    {form.condition === 'used'
                                      ? 'Używany'
                                      : form.condition === 'new'
                                        ? 'Nowy'
                                        : form.condition === 'refit'
                                          ? 'Po remoncie'
                                          : form.condition === 'project'
                                            ? 'Do remontu / na części'
                                            : '—'}
                                  </dd>
                                </div>
                                <div>
                                  <dt className="text-gray-500">Sterowanie</dt>
                                  <dd className="font-medium">
                                    {ENGINE_STEERING_TYPES.find((s) => s.value === form.steeringType)?.label ??
                                      '—'}
                                  </dd>
                                </div>
                                <div>
                                  <dt className="text-gray-500">Masa (kg)</dt>
                                  <dd className="font-medium">{form.weightKg || '—'}</dd>
                                </div>
                                <div>
                                  <dt className="text-gray-500">Liczba silników</dt>
                                  <dd className="font-medium">{form.engineCount.trim() || '—'}</dd>
                                </div>
                                <div>
                                  <dt className="text-gray-500">Moc (KM)</dt>
                                  <dd className="font-medium">{form.enginePowerHp.trim() || '—'}</dd>
                                </div>
                                <div>
                                  <dt className="text-gray-500">Motogodziny</dt>
                                  <dd className="font-medium">{form.engineHours.trim() || '—'}</dd>
                                </div>
                                <div>
                                  <dt className="text-gray-500">Paliwo</dt>
                                  <dd className="font-medium">
                                    {BOAT_ENGINE_FUEL_TYPES.find((f) => f.value === form.fuelType)?.label ?? '—'}
                                  </dd>
                                </div>
                              </>
                            ) : form.category === 'small' ? (
                              <>
                                <div>
                                  <dt className="text-gray-500">Typ jednostki (do 3)</dt>
                                  <dd className="font-medium">
                                    {form.smallCraftTypes.length
                                      ? form.smallCraftTypes
                                          .map((v) => SMALL_CRAFT_TYPES.find((t) => t.value === v)?.label ?? v)
                                          .join(', ')
                                      : '—'}
                                  </dd>
                                </div>
                                <div>
                                  <dt className="text-gray-500">Producent</dt>
                                  <dd>
                                    <ProducerSummaryDd name={form.manufacturer} catalog={BOAT_MANUFACTURER_RECORDS} />
                                  </dd>
                                </div>
                                <div>
                                  <dt className="text-gray-500">Podtytuł</dt>
                                  <dd className="font-medium">{form.subtitle || '—'}</dd>
                                </div>
                                <div>
                                  <dt className="text-gray-500">Rok budowy</dt>
                                  <dd className="font-medium">{form.yearBuilt || '—'}</dd>
                                </div>
                                <div>
                                  <dt className="text-gray-500">Stan</dt>
                                  <dd className="font-medium">
                                    {form.condition === 'used'
                                      ? 'Używana'
                                      : form.condition === 'new'
                                        ? 'Nowy'
                                        : form.condition === 'refit'
                                          ? 'Po remoncie'
                                          : form.condition === 'project'
                                            ? 'Do remontu'
                                            : '—'}
                                  </dd>
                                </div>
                                <div>
                                  <dt className="text-gray-500">Materiał</dt>
                                  <dd className="font-medium">
                                    {SMALL_HULL_MATERIALS.find((m) => m.value === form.material)?.label ?? '—'}
                                  </dd>
                                </div>
                                <div>
                                  <dt className="text-gray-500">CE / kategoria</dt>
                                  <dd className="font-medium">{form.ceMarking || '—'}</dd>
                                </div>
                                <div>
                                  <dt className="text-gray-500">Dł. × szer. (m)</dt>
                                  <dd className="font-medium">
                                    {[form.lengthM, form.beamM].filter(Boolean).join(' × ') || '—'}
                                  </dd>
                                </div>
                                <div>
                                  <dt className="text-gray-500">Masa (kg)</dt>
                                  <dd className="font-medium">{form.weightKg || '—'}</dd>
                                </div>
                                <div>
                                  <dt className="text-gray-500">Max. osób</dt>
                                  <dd className="font-medium">{form.maxPersons || '—'}</dd>
                                </div>
                                <div>
                                  <dt className="text-gray-500">Napęd</dt>
                                  <dd className="font-medium">
                                    {BOAT_PROPULSION_TYPES.find((p) => p.value === form.propulsion)?.label ?? '—'}
                                  </dd>
                                </div>
                                <div>
                                  <dt className="text-gray-500">Paliwo</dt>
                                  <dd className="font-medium">
                                    {BOAT_ENGINE_FUEL_TYPES.find((f) => f.value === form.fuelType)?.label ?? '—'}
                                  </dd>
                                </div>
                                <div>
                                  <dt className="text-gray-500">Silniki / moc / motogodz.</dt>
                                  <dd className="font-medium">
                                    {[
                                      form.engineCount.trim() && `${form.engineCount.trim()} szt.`,
                                      form.enginePowerHp.trim() && `${form.enginePowerHp.trim()} KM`,
                                      form.engineHours.trim() && `${form.engineHours.trim()} mh`,
                                    ]
                                      .filter(Boolean)
                                      .join(', ') || '—'}
                                  </dd>
                                </div>
                                <div>
                                  <dt className="text-gray-500">Przyczepa w zestawie</dt>
                                  <dd className="font-medium">{form.trailerIncluded ? 'Tak' : 'Nie'}</dd>
                                </div>
                                <div>
                                  <dt className="text-gray-500">Możliwość postoju</dt>
                                  <dd className="font-medium">{form.berthAvailable ? 'Tak' : 'Nie'}</dd>
                                </div>
                              </>
                            ) : (
                              <>
                                <div>
                                  <dt className="text-gray-500">Typ</dt>
                                  <dd className="font-medium">
                                    {BOAT_HULL_TYPES.find((t) => t.value === form.boatType)?.label ?? '—'}
                                  </dd>
                                </div>
                                <div>
                                  <dt className="text-gray-500">Producent</dt>
                                  <dd>
                                    <ProducerSummaryDd name={form.manufacturer} catalog={BOAT_MANUFACTURER_RECORDS} />
                                  </dd>
                                </div>
                                <div>
                                  <dt className="text-gray-500">Materiał kadłuba</dt>
                                  <dd className="font-medium">
                                    {BOAT_HULL_MATERIALS.find((m) => m.value === form.material)?.label ?? '—'}
                                  </dd>
                                </div>
                                <div>
                                  <dt className="text-gray-500">Typ kilu</dt>
                                  <dd className="font-medium">
                                    {BOAT_KEEL_TYPES.find((k) => k.value === form.keelType)?.label ?? '—'}
                                  </dd>
                                </div>
                                <div>
                                  <dt className="text-gray-500">Typ masztu</dt>
                                  <dd className="font-medium">
                                    {BOAT_MAST_TYPES.find((m) => m.value === form.mastMaterial)?.label ?? '—'}
                                  </dd>
                                </div>
                                <div>
                                  <dt className="text-gray-500">Napęd</dt>
                                  <dd className="font-medium">
                                    {BOAT_PROPULSION_TYPES.find((p) => p.value === form.propulsion)?.label ?? '—'}
                                  </dd>
                                </div>
                                <div>
                                  <dt className="text-gray-500">Paliwo</dt>
                                  <dd className="font-medium">
                                    {BOAT_ENGINE_FUEL_TYPES.find((f) => f.value === form.fuelType)?.label ?? '—'}
                                  </dd>
                                </div>
                              </>
                            )}
                            <div>
                              <dt className="text-gray-500">Tytuł</dt>
                              <dd className="font-medium">{form.modelTitle || '—'}</dd>
                            </div>
                            <div>
                              <dt className="text-gray-500">Lokalizacja</dt>
                              <dd className="font-medium">
                                {[form.location, form.region, form.country].filter(Boolean).join(', ') || '—'}
                              </dd>
                            </div>
                            <div>
                              <dt className="text-gray-500">Cena</dt>
                              <dd className="font-medium">
                                {form.offerType === 'on_request'
                                  ? 'Na zapytanie'
                                  : form.price
                                    ? `${form.price} zł${form.offerType === 'negotiable' ? ' (do negocjacji)' : ''}`
                                    : '—'}
                              </dd>
                            </div>
                            <div>
                              <dt className="text-gray-500">Publikacja</dt>
                              <dd className="font-medium">{form.duration} dni</dd>
                            </div>
                            {/* Koszty publikacji — tymczasowo ukryte (przywróć po uruchomieniu rozliczeń)
                            <div>
                              <dt className="text-gray-500">Publikacja</dt>
                              <dd className="font-medium">{form.duration} dni — {durationPrice} zł</dd>
                            </div>
                            <div>
                              <dt className="text-gray-500">Dodatki</dt>
                              <dd className="font-medium">
                                {[form.topOffer && 'TOP', form.highlight && 'Wyróżnienie'].filter(Boolean).join(', ') ||
                                  'brak'}
                              </dd>
                            </div>
                            */}
                            <div>
                              <dt className="text-gray-500">Zdjęcia</dt>
                              <dd className="font-medium">{form.photos.length} plik(ów)</dd>
                            </div>
                          </dl>
                          {/* Razem do zapłaty — tymczasowo ukryte (przywróć po uruchomieniu rozliczeń)
                          <p className="mt-3 border-t border-gray-200 pt-3 text-base font-bold text-blue-950">
                            Razem: {total} zł brutto (orientacyjnie — finalne rozliczenie po weryfikacji)
                          </p>
                          */}
                        </div>

                        <Section title="Dane do faktury / rozliczenia">
                          <label className="flex cursor-pointer items-start gap-3 rounded-lg border border-gray-200 bg-white p-3 text-sm">
                            <input
                              type="checkbox"
                              className="mt-0.5 h-4 w-4 rounded border-gray-300 text-blue-600"
                              checked={form.wantsInvoiceData}
                              onChange={(e) => update('wantsInvoiceData', e.target.checked)}
                            />
                            <span>
                              <span className="font-medium text-gray-900">Podaj dane do faktury lub rozliczenia</span>
                              <span className="mt-0.5 block text-xs text-gray-500">
                                Opcjonalnie — zaznacz, jeśli potrzebujesz faktury lub pełnego adresu do rozliczenia.
                              </span>
                            </span>
                          </label>
                          {form.wantsInvoiceData ? (
                            <>
                              <div>
                                <label className={labelClass}>Tytuł / firma (opcjonalnie)</label>
                                <input
                                  type="text"
                                  className={inputClass}
                                  value={form.invoiceTitle}
                                  onChange={(e) => update('invoiceTitle', e.target.value)}
                                  placeholder="np. Pani, Pan, JDG"
                                />
                              </div>
                              <div>
                                <label className={labelClass}>Imię i nazwisko / nazwa *</label>
                                <input
                                  type="text"
                                  className={inputClass}
                                  value={form.invoiceName}
                                  onChange={(e) => update('invoiceName', e.target.value)}
                                />
                              </div>
                              <div className="grid gap-3 sm:grid-cols-3">
                                <div className="sm:col-span-2">
                                  <label className={labelClass}>Ulica *</label>
                                  <input
                                    type="text"
                                    className={inputClass}
                                    value={form.invoiceStreet}
                                    onChange={(e) => update('invoiceStreet', e.target.value)}
                                  />
                                </div>
                                <div>
                                  <label className={labelClass}>Nr domu *</label>
                                  <input
                                    type="text"
                                    className={inputShortClass}
                                    value={form.invoiceHouseNo}
                                    onChange={(e) => update('invoiceHouseNo', e.target.value)}
                                  />
                                </div>
                              </div>
                              <div className="grid gap-3 sm:grid-cols-2">
                                <div>
                                  <label className={labelClass}>Kod pocztowy *</label>
                                  <input
                                    type="text"
                                    className={inputShortClass}
                                    value={form.invoiceZip}
                                    onChange={(e) => update('invoiceZip', e.target.value)}
                                  />
                                </div>
                                <div>
                                  <label className={labelClass}>Miasto *</label>
                                  <input
                                    type="text"
                                    className={inputClass}
                                    value={form.invoiceCity}
                                    onChange={(e) => update('invoiceCity', e.target.value)}
                                  />
                                </div>
                              </div>
                              <div>
                                <label className={labelClass}>Telefon (do ewentualnych pytań) *</label>
                                <input
                                  type="tel"
                                  className={inputClass}
                                  value={form.invoicePhone}
                                  onChange={(e) => update('invoicePhone', e.target.value)}
                                />
                              </div>
                            </>
                          ) : null}
                        </Section>

                        {!editingListingId ? (
                        <label className="flex cursor-pointer items-start gap-3 text-sm text-gray-700">
                          <input
                            type="checkbox"
                            className="mt-1 h-4 w-4 rounded border-gray-300 text-blue-600"
                            checked={form.acceptTerms}
                            onChange={(e) => update('acceptTerms', e.target.checked)}
                          />
                          <span>
                            Opublikowanie ogłoszenia jest płatne zgodnie z wybranym pakietem. Akceptuję{' '}
                            <a
                              href="/regulamin"
                              target="_blank"
                              rel="noopener noreferrer"
                              className="font-medium text-blue-600 underline"
                            >
                              regulamin
                            </a>{' '}
                            i wyrażam zgodę na przetwarzanie danych w celu publikacji ogłoszenia.
                          </span>
                        </label>
                        ) : null}
                      </div>
                    )}
                </div>
              </div>

              <div className="flex shrink-0 flex-wrap items-center justify-between gap-3 border-t border-gray-200 bg-gray-50 px-4 py-3 sm:px-6">
                <button
                  type="button"
                  onClick={back}
                  disabled={step === 1}
                  className="min-h-[44px] rounded-lg border border-gray-300 bg-white px-4 text-sm font-medium text-gray-700 hover:bg-gray-50 disabled:cursor-not-allowed disabled:opacity-40"
                >
                  Wstecz
                </button>
                {step < 5 ? (
                  <button
                    type="button"
                    onClick={next}
                    className="min-h-[44px] rounded-lg bg-blue-600 px-6 text-sm font-semibold text-white hover:bg-blue-700"
                  >
                    Dalej
                  </button>
                ) : (
                  <button
                    type="button"
                    disabled={submitting}
                    onClick={async () => {
                      const err = validateStep(5)
                      if (err) {
                        showStepError(err)
                        return
                      }
                      if (sessionStatus === 'loading') {
                        showStepError('Sprawdzanie sesji…')
                        return
                      }
                      if (!session?.user?.id) {
                        showStepError('Zaloguj się, aby opublikować ogłoszenie (ikona logowania w menu).')
                        return
                      }
                      setStepError(null)
                      setSubmitting(true)
                      try {
                        const {
                          photos: _photos,
                          serverListingPhotoPaths,
                          wantsInvoiceData,
                          ...rest
                        } = form
                        const payload: Record<string, unknown> = {
                          ...rest,
                          equipment: Array.isArray(form.equipment) ? [...form.equipment] : [],
                        }
                        if (!wantsInvoiceData) {
                          payload.invoiceTitle = ''
                          payload.invoiceName = ''
                          payload.invoiceStreet = ''
                          payload.invoiceHouseNo = ''
                          payload.invoiceZip = ''
                          payload.invoiceCity = ''
                          payload.invoicePhone = ''
                        }
                        if (editingListingId) {
                          if (form.photos.length === 0) {
                            payload.photoPaths = [...serverListingPhotoPaths]
                          }
                        }
                        const url = editingListingId
                          ? `/api/listings/${encodeURIComponent(editingListingId)}`
                          : '/api/listings'
                        const res = await fetch(url, {
                          method: editingListingId ? 'PATCH' : 'POST',
                          headers: { 'Content-Type': 'application/json' },
                          credentials: 'include',
                          body: JSON.stringify(payload),
                        })
                        const data = (await res.json().catch(() => ({}))) as {
                          error?: string
                          slug?: string
                          id?: string
                          emailSent?: boolean
                          emailSkipped?: boolean
                        }
                        if (!res.ok) {
                          setStepError(data.error ?? 'Nie udało się zapisać ogłoszenia.')
                          return
                        }

                        const slugOut = data.slug ?? ''
                        const listingIdForImages = editingListingId ?? data.id
                        if (form.photos.length > 0 && listingIdForImages) {
                          const fd = new FormData()
                          for (const f of form.photos) {
                            fd.append('files', f)
                          }
                          const q = editingListingId ? '?replace=1' : ''
                          const up = await fetch(
                            `/api/listings/${encodeURIComponent(listingIdForImages)}/images${q}`,
                            { method: 'POST', body: fd, credentials: 'include' },
                          )
                          const upJson = (await up.json().catch(() => ({}))) as { error?: string }
                          if (!up.ok) {
                            setStepError(
                              upJson.error ??
                                'Ogłoszenie zapisano, ale nie udało się wgrać zdjęć. Spróbuj je dodać w edycji ogłoszenia (krok ze zdjęciami).',
                            )
                            return
                          }
                        }

                        if (!editingListingId) {
                          trackAnalyticsEvent('listing_publish', {
                            listing_category: form.category || 'other',
                            publication_days: Number(form.duration),
                            has_photos: form.photos.length > 0,
                          })
                        }

                        close()
                        onPublished?.()
                        const origin =
                          typeof window !== 'undefined' ? window.location.origin : ''
                        const previewUrl = slugOut ? `${origin}/sklep/${slugOut}` : ''
                        const emailNote =
                          !editingListingId && data.emailSent
                            ? `\n\nPotwierdzenie wysłaliśmy na adres: ${form.email.trim()}.`
                            : !editingListingId && !data.emailSkipped && form.email.trim()
                              ? '\n\nNie udało się wysłać e-maila z potwierdzeniem — sprawdź skrzynkę później lub napisz na kontakt@twojalodka.pl.'
                              : ''
                        alert(
                          slugOut
                            ? editingListingId
                              ? `Zapisano zmiany.\n\nPodgląd:\n${previewUrl}`
                              : `Ogłoszenie opublikowane.\n\nZobacz je na stronie:\n${previewUrl}${emailNote}`
                            : 'Zapisano.',
                        )
                      } catch {
                        setStepError('Błąd sieci. Spróbuj ponownie.')
                      } finally {
                        setSubmitting(false)
                      }
                    }}
                    className="min-h-[44px] rounded-lg bg-blue-600 px-6 text-sm font-semibold text-white hover:bg-blue-700 disabled:opacity-60"
                  >
                    {submitting ? 'Zapisywanie…' : editingListingId ? 'Zapisz zmiany' : 'Opublikuj ogłoszenie'}
                  </button>
                )}
              </div>
            </div>
          </div>,
          document.body,
        )}
    </>
  )
}
