import { useState, useEffect, useMemo, useRef } from 'react'
import { useParams } from 'react-router-dom'
import { Plane, Train, Car, Ship, Bus, Sailboat, Bike, CarTaxiFront, Route, Paperclip, FileText, X, ExternalLink, Link2, Plus, Trash2 } from 'lucide-react'
import Modal from '../shared/Modal'
import CustomSelect from '../shared/CustomSelect'
import CustomTimePicker from '../shared/CustomTimePicker'
import AirportSelect, { type Airport } from './AirportSelect'
import LocationSelect, { type LocationPoint } from './LocationSelect'
import { useTranslation } from '../../i18n'
import { useToast } from '../shared/Toast'
import { useTripStore } from '../../store/tripStore'
import { useAddonStore } from '../../store/addonStore'
import { formatDate, splitReservationDateTime } from '../../utils/formatters'
import { openFile } from '../../utils/fileDownload'
import apiClient from '../../api/client'
import type { Day, Reservation, ReservationEndpoint, TripFile } from '../../types'
import { parseReservationMetadata, orderedEndpoints } from '../../utils/flightLegs'

const TRANSPORT_TYPES = ['flight', 'train', 'bus', 'car', 'taxi', 'bicycle', 'cruise', 'ferry', 'transport_other'] as const
type TransportType = typeof TRANSPORT_TYPES[number]

interface EndpointPick {
  airport?: Airport
  location?: LocationPoint
}

function endpointFromAirport(a: Airport, role: 'from' | 'to' | 'stop', sequence: number, date: string | null, time: string | null): Omit<ReservationEndpoint, 'id' | 'reservation_id'> {
  return {
    role, sequence,
    name: a.city ? `${a.city} (${a.iata})` : a.name,
    code: a.iata,
    lat: a.lat, lng: a.lng,
    timezone: a.tz,
    local_date: date,
    local_time: time,
  }
}

function endpointFromLocation(l: LocationPoint, role: 'from' | 'to', sequence: number, date: string | null, time: string | null): Omit<ReservationEndpoint, 'id' | 'reservation_id'> {
  return {
    role, sequence,
    name: l.name,
    code: null,
    lat: l.lat, lng: l.lng,
    timezone: null,
    local_date: date,
    local_time: time,
  }
}

function airportFromEndpoint(e: ReservationEndpoint | undefined): Airport | null {
  if (!e || !e.code) return null
  return {
    iata: e.code, icao: null,
    name: e.name, city: e.name.replace(/\s*\([A-Z]{3}\)\s*$/, ''),
    country: '',
    lat: e.lat, lng: e.lng,
    tz: e.timezone || '',
  }
}

function locationFromEndpoint(e: ReservationEndpoint | undefined): LocationPoint | null {
  if (!e) return null
  return { name: e.name, lat: e.lat, lng: e.lng, address: null }
}

// ── Multi-leg flight waypoints ─────────────────────────────────────────────
// A flight is an ordered list of airports. The origin has only a departure, the
// destination only an arrival, and each intermediate stop has both — plus the
// airline/flight number of the flight LEAVING it. N waypoints = N-1 legs. A
// single-leg flight is just two waypoints, so it persists exactly as before.
interface WaypointForm {
  airport: Airport | null
  arrDayId: string | number
  arrTime: string
  depDayId: string | number
  depTime: string
  airline: string
  flight_number: string
  seat: string
}
function emptyWaypoint(dayId: string | number = ''): WaypointForm {
  return { airport: null, arrDayId: dayId, arrTime: '', depDayId: dayId, depTime: '', airline: '', flight_number: '', seat: '' }
}

const TYPE_OPTIONS = [
  { value: 'flight',          labelKey: 'reservations.type.flight',          Icon: Plane },
  { value: 'train',           labelKey: 'reservations.type.train',           Icon: Train },
  { value: 'bus',             labelKey: 'reservations.type.bus',             Icon: Bus },
  { value: 'car',             labelKey: 'reservations.type.car',             Icon: Car },
  { value: 'taxi',            labelKey: 'reservations.type.taxi',            Icon: CarTaxiFront },
  { value: 'bicycle',         labelKey: 'reservations.type.bicycle',         Icon: Bike },
  { value: 'cruise',          labelKey: 'reservations.type.cruise',          Icon: Ship },
  { value: 'ferry',           labelKey: 'reservations.type.ferry',           Icon: Sailboat },
  { value: 'transport_other', labelKey: 'reservations.type.transport_other', Icon: Route },
]

const defaultForm = {
  title: '',
  type: 'flight' as TransportType,
  status: 'pending' as 'pending' | 'confirmed',
  start_day_id: '' as string | number,
  end_day_id: '' as string | number,
  departure_time: '',
  arrival_time: '',
  confirmation_number: '',
  notes: '',
  price: '',
  budget_category: '',
  meta_airline: '',
  meta_flight_number: '',
  meta_train_number: '',
  meta_platform: '',
  meta_seat: '',
}

interface TransportModalProps {
  isOpen: boolean
  onClose: () => void
  onSave: (data: Record<string, any> & { title: string }) => Promise<Reservation | undefined>
  reservation: Reservation | null
  days: Day[]
  selectedDayId: number | null
  files?: TripFile[]
  onFileUpload?: (fd: FormData) => Promise<unknown>
  onFileDelete?: (fileId: number) => Promise<void>
}

export function TransportModal({ isOpen, onClose, onSave, reservation, days, selectedDayId, files = [], onFileUpload, onFileDelete }: TransportModalProps) {
  const { t, locale } = useTranslation()
  const toast = useToast()
  const isBudgetEnabled = useAddonStore(s => s.isEnabled('budget'))
  const budgetItems = useTripStore(s => s.budgetItems)
  const loadFiles = useTripStore(s => s.loadFiles)
  const budgetCategories = useMemo(() => {
    const cats = new Set<string>()
    budgetItems.forEach(i => { if (i.category) cats.add(i.category) })
    return Array.from(cats).sort()
  }, [budgetItems])
  const { id: tripId } = useParams<{ id: string }>()
  const [form, setForm] = useState({ ...defaultForm })
  const [isSaving, setIsSaving] = useState(false)
  const [fromPick, setFromPick] = useState<EndpointPick>({})
  const [toPick, setToPick] = useState<EndpointPick>({})
  // Flight route as an ordered list of airports (origin .. stops .. destination).
  const [waypoints, setWaypoints] = useState<WaypointForm[]>([emptyWaypoint(), emptyWaypoint()])
  const [uploadingFile, setUploadingFile] = useState(false)
  const [pendingFiles, setPendingFiles] = useState<File[]>([])
  const [showFilePicker, setShowFilePicker] = useState(false)
  const [linkedFileIds, setLinkedFileIds] = useState<number[]>([])
  const fileInputRef = useRef<HTMLInputElement>(null)

  useEffect(() => {
    if (!isOpen) return
    if (reservation) {
      const meta = typeof reservation.metadata === 'string'
        ? JSON.parse(reservation.metadata || '{}')
        : (reservation.metadata || {})
      const eps = reservation.endpoints || []
      const from = eps.find(e => e.role === 'from')
      const to = eps.find(e => e.role === 'to')
      const type = (TRANSPORT_TYPES as readonly string[]).includes(reservation.type)
        ? reservation.type as TransportType
        : 'flight'
      setForm({
        title: reservation.title || '',
        type,
        status: reservation.status === 'confirmed' ? 'confirmed' : 'pending',
        start_day_id: reservation.day_id ?? '',
        end_day_id: reservation.end_day_id ?? '',
        departure_time: splitReservationDateTime(reservation.reservation_time).time ?? '',
        arrival_time: splitReservationDateTime(reservation.reservation_end_time).time ?? '',
        confirmation_number: reservation.confirmation_number || '',
        notes: reservation.notes || '',
        meta_airline: meta.airline || '',
        meta_flight_number: meta.flight_number || '',
        meta_train_number: meta.train_number || '',
        meta_platform: meta.platform || '',
        meta_seat: meta.seat || '',
        price: meta.price || '',
        budget_category: (meta.budget_category && budgetItems.some(i => i.category === meta.budget_category)) ? meta.budget_category : '',
      })
      if (type === 'flight') {
        const orderedEps = orderedEndpoints(reservation)
        const metaLegs: any[] = Array.isArray(meta.legs) ? meta.legs : []
        let wps: WaypointForm[]
        if (orderedEps.length >= 2) {
          wps = orderedEps.map((ep, i) => {
            const legInto = metaLegs[i - 1] // leg arriving INTO waypoint i
            const legOut = metaLegs[i] // leg departing FROM waypoint i
            const isFirst = i === 0
            const isLast = i === orderedEps.length - 1
            return {
              airport: airportFromEndpoint(ep),
              arrDayId: legInto?.arr_day_id ?? (isLast ? (reservation.end_day_id ?? '') : ''),
              arrTime: legInto?.arr_time ?? (!isFirst ? (ep.local_time ?? '') : ''),
              depDayId: legOut?.dep_day_id ?? (isFirst ? (reservation.day_id ?? '') : ''),
              depTime: legOut?.dep_time ?? (!isLast ? (ep.local_time ?? '') : ''),
              airline: legOut?.airline ?? (isFirst ? (meta.airline ?? '') : ''),
              flight_number: legOut?.flight_number ?? (isFirst ? (meta.flight_number ?? '') : ''),
              seat: legOut?.seat ?? (isFirst ? (meta.seat ?? '') : ''),
            }
          })
        } else {
          // Legacy flight with no (or partial) endpoints — seed two waypoints.
          const dep = emptyWaypoint(reservation.day_id ?? '')
          dep.airport = airportFromEndpoint(from)
          dep.depTime = splitReservationDateTime(reservation.reservation_time).time ?? ''
          dep.airline = meta.airline ?? ''
          dep.flight_number = meta.flight_number ?? ''
          dep.seat = meta.seat ?? ''
          const arr = emptyWaypoint(reservation.end_day_id ?? reservation.day_id ?? '')
          arr.airport = airportFromEndpoint(to)
          arr.arrTime = splitReservationDateTime(reservation.reservation_end_time).time ?? ''
          wps = [dep, arr]
        }
        setWaypoints(wps)
      } else {
        setFromPick({ location: locationFromEndpoint(from) || undefined })
        setToPick({ location: locationFromEndpoint(to) || undefined })
      }
    } else {
      setForm({ ...defaultForm, start_day_id: selectedDayId ?? '', end_day_id: selectedDayId ?? '' })
      setFromPick({})
      setToPick({})
      setWaypoints([emptyWaypoint(selectedDayId ?? ''), emptyWaypoint(selectedDayId ?? '')])
    }
  }, [isOpen, reservation, selectedDayId, budgetItems])

  const set = (field: string, value: any) => setForm(prev => ({ ...prev, [field]: value }))

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault()
    if (!form.title.trim()) return
    setIsSaving(true)
    try {
      const startDay = days.find(d => d.id === Number(form.start_day_id))
      const endDay = days.find(d => d.id === Number(form.end_day_id))

      const buildTime = (day: Day | undefined, time: string): string | null => {
        if (!time) return null
        return day?.date ? `${day.date}T${time}` : time
      }

      const dayDate = (id: string | number): string | null => days.find(d => d.id === Number(id))?.date ?? null
      // Flight route as an ordered list of airports (origin .. stops .. destination).
      const flightWps = form.type === 'flight' ? waypoints.filter(w => w.airport) : []
      const firstWp = flightWps[0]
      const lastWp = flightWps[flightWps.length - 1]
      // Per-leg day-plan positions are owned by the day planner, not this form — keep
      // them when re-saving so editing a flight doesn't reset where its legs sit.
      const origLegs: any[] = reservation ? (parseReservationMetadata(reservation).legs || []) : []

      const metadata: Record<string, any> = {}
      if (form.type === 'flight') {
        // Top-level keys mirror the first/last leg so legacy readers keep working.
        if (firstWp?.airline) metadata.airline = firstWp.airline
        if (firstWp?.flight_number) metadata.flight_number = firstWp.flight_number
        if (firstWp?.airport) {
          metadata.departure_airport = firstWp.airport.iata
          metadata.departure_timezone = firstWp.airport.tz
        }
        if (lastWp?.airport) {
          metadata.arrival_airport = lastWp.airport.iata
          metadata.arrival_timezone = lastWp.airport.tz
        }
        // Per-leg detail only for true multi-leg flights — a single-leg flight
        // keeps the exact same (flat) metadata it had before this feature.
        if (flightWps.length > 2) {
          metadata.legs = flightWps.slice(0, -1).map((w, i) => {
            const next = flightWps[i + 1]
            return {
              from: w.airport!.iata,
              to: next.airport!.iata,
              ...(w.airline ? { airline: w.airline } : {}),
              ...(w.flight_number ? { flight_number: w.flight_number } : {}),
              ...(w.seat ? { seat: w.seat } : {}),
              dep_day_id: w.depDayId ? Number(w.depDayId) : null,
              dep_time: w.depTime || null,
              arr_day_id: next.arrDayId ? Number(next.arrDayId) : null,
              arr_time: next.arrTime || null,
              ...(origLegs[i]?.day_positions ? { day_positions: origLegs[i].day_positions } : {}),
            }
          })
        }
        if (firstWp?.seat) metadata.seat = firstWp.seat
      } else if (form.type === 'train') {
        if (form.meta_train_number) metadata.train_number = form.meta_train_number
        if (form.meta_platform) metadata.platform = form.meta_platform
        if (form.meta_seat) metadata.seat = form.meta_seat
      }
      if (isBudgetEnabled) {
        if (form.price) metadata.price = form.price
        if (form.budget_category) metadata.budget_category = form.budget_category
      }

      const startDate = startDay?.date ?? null
      const endDate = (endDay ?? startDay)?.date ?? null
      const endpoints: ReturnType<typeof endpointFromAirport>[] = []
      if (form.type === 'flight') {
        flightWps.forEach((w, i) => {
          const isFirst = i === 0
          const isLast = i === flightWps.length - 1
          const role: 'from' | 'to' | 'stop' = isFirst ? 'from' : isLast ? 'to' : 'stop'
          const dId = isLast ? w.arrDayId : w.depDayId
          const time = isLast ? w.arrTime : w.depTime
          endpoints.push(endpointFromAirport(w.airport!, role, i, dayDate(dId), time || null))
        })
      } else {
        if (fromPick.location) endpoints.push(endpointFromLocation(fromPick.location, 'from', 0, startDate, form.departure_time || null))
        if (toPick.location) endpoints.push(endpointFromLocation(toPick.location, 'to', 1, endDate, form.arrival_time || null))
      }

      // Flights derive their span from the first/last waypoint; other transports
      // keep using the single departure/arrival form fields unchanged.
      const flightDepDay = firstWp && firstWp.depDayId ? Number(firstWp.depDayId) : null
      const flightArrDay = lastWp && lastWp.arrDayId ? Number(lastWp.arrDayId) : null
      const payload = {
        title: form.title,
        type: form.type,
        status: form.status,
        day_id: form.type === 'flight' ? flightDepDay : (form.start_day_id ? Number(form.start_day_id) : null),
        end_day_id: form.type === 'flight' ? flightArrDay : (form.end_day_id ? Number(form.end_day_id) : null),
        reservation_time: form.type === 'flight'
          ? buildTime(days.find(d => d.id === flightDepDay), firstWp?.depTime || '')
          : buildTime(startDay, form.departure_time),
        reservation_end_time: form.type === 'flight'
          ? buildTime(days.find(d => d.id === flightArrDay), lastWp?.arrTime || '')
          : buildTime(endDay ?? startDay, form.arrival_time),
        location: null,
        confirmation_number: form.confirmation_number || null,
        notes: form.notes || null,
        metadata: Object.keys(metadata).length > 0 ? metadata : null,
        endpoints,
        needs_review: false,
      }
      if (isBudgetEnabled) {
        (payload as any).create_budget_entry = form.price && parseFloat(form.price) > 0
          ? { total_price: parseFloat(form.price), category: form.budget_category || t(`reservations.type.${form.type}`) || 'Other' }
          : { total_price: 0 }
      }
      const saved = await onSave(payload)
      if (!reservation?.id && saved?.id && pendingFiles.length > 0 && onFileUpload) {
        for (const file of pendingFiles) {
          const fd = new FormData()
          fd.append('file', file)
          fd.append('reservation_id', String(saved.id))
          fd.append('description', form.title)
          await onFileUpload(fd)
        }
      }
    } catch (err: unknown) {
      toast.error(err instanceof Error ? err.message : t('common.unknownError'))
    } finally {
      setIsSaving(false)
    }
  }

  const handleFileChange = async (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0]
    if (!file) return
    if (reservation?.id) {
      setUploadingFile(true)
      try {
        const fd = new FormData()
        fd.append('file', file)
        fd.append('reservation_id', String(reservation.id))
        fd.append('description', reservation.title)
        await onFileUpload!(fd)
        toast.success(t('reservations.toast.fileUploaded'))
      } catch {
        toast.error(t('reservations.toast.uploadError'))
      } finally {
        setUploadingFile(false)
        e.target.value = ''
      }
    } else {
      setPendingFiles(prev => [...prev, file])
      e.target.value = ''
    }
  }

  const attachedFiles = reservation?.id
    ? files.filter(f =>
        f.reservation_id === reservation.id ||
        linkedFileIds.includes(f.id) ||
        (f.linked_reservation_ids && f.linked_reservation_ids.includes(reservation.id))
      )
    : []

  const inputClass = 'w-full border border-edge rounded-[10px] px-[12px] py-[8px] text-[13px] font-[inherit] outline-none box-border text-content bg-surface-input'
  const labelClass = 'block text-[11px] font-semibold text-content-faint mb-[5px] uppercase tracking-[0.03em]'

  const dayOptions = [
    { value: '', label: '—' },
    ...days.map(d => {
      const dateBadge = d.date ? (formatDate(d.date, locale) ?? undefined) : undefined
      const dayBadge = d.title ? t('dayplan.dayN', { n: d.day_number }) : undefined
      return {
        value: d.id,
        label: d.title || t('dayplan.dayN', { n: d.day_number }),
        badge: dateBadge ?? dayBadge,
      }
    }),
  ]

  return (
    <Modal
      isOpen={isOpen}
      onClose={onClose}
      title={reservation ? t('transport.modalTitle.edit') : t('transport.modalTitle.create')}
      size="2xl"
      footer={
        <div style={{ display: 'flex', justifyContent: 'flex-end', gap: 8 }}>
          <button type="button" onClick={onClose} className="text-content-muted" style={{ padding: '8px 16px', borderRadius: 10, border: '1px solid var(--border-primary)', background: 'none', fontSize: 12, cursor: 'pointer', fontFamily: 'inherit' }}>
            {t('common.cancel')}
          </button>
          <button type="button" onClick={handleSubmit} disabled={isSaving || !form.title.trim()} className="bg-[var(--text-primary)] text-[var(--bg-primary)]" style={{ padding: '8px 20px', borderRadius: 10, border: 'none', fontSize: 12, fontWeight: 600, cursor: 'pointer', fontFamily: 'inherit', opacity: isSaving || !form.title.trim() ? 0.5 : 1 }}>
            {isSaving ? t('common.saving') : reservation ? t('common.update') : t('common.add')}
          </button>
        </div>
      }
    >
      <form onSubmit={handleSubmit} style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>

        {/* Type selector */}
        <div>
          <label className={labelClass}>{t('reservations.bookingType')}</label>
          <div style={{ display: 'flex', flexWrap: 'wrap', gap: 5 }}>
            {TYPE_OPTIONS.map(({ value, labelKey, Icon }) => (
              <button key={value} type="button" onClick={() => set('type', value)} className={form.type === value ? 'bg-[var(--text-primary)] text-[var(--bg-primary)]' : 'bg-surface-card text-content-muted'} style={{
                display: 'flex', alignItems: 'center', gap: 4,
                padding: '5px 10px', borderRadius: 99, border: '1px solid',
                fontSize: 11, fontWeight: 500, cursor: 'pointer', fontFamily: 'inherit', transition: 'all 0.12s',
                borderColor: form.type === value ? 'var(--text-primary)' : 'var(--border-primary)',
              }}>
                <Icon size={11} /> {t(labelKey)}
              </button>
            ))}
          </div>
        </div>

        {/* Title */}
        <div>
          <label className={labelClass}>{t('reservations.titleLabel')} *</label>
          <input type="text" value={form.title} onChange={e => set('title', e.target.value)} required
            placeholder={t('reservations.titlePlaceholder')} className={inputClass} />
        </div>

        {form.type === 'flight' ? (
          /* ── Flight route: ordered airports (origin · stops · destination) ── */
          <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
            <label className={labelClass}>{t('reservations.layover.route')}</label>
            {waypoints.map((wp, i) => {
              const isFirst = i === 0
              const isLast = i === waypoints.length - 1
              const updateWp = (patch: Partial<WaypointForm>) => setWaypoints(prev => prev.map((w, j) => (j === i ? { ...w, ...patch } : w)))
              const roleLabel = isFirst ? t('reservations.meta.from') : isLast ? t('reservations.meta.to') : t('reservations.layover.stop')
              return (
                <div key={i} style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
                  <div className="bg-surface-card" style={{ border: '1px solid var(--border-primary)', borderRadius: 10, padding: 10, display: 'flex', flexDirection: 'column', gap: 8 }}>
                    <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
                      <span className="text-content-faint" style={{ fontSize: 10, fontWeight: 700, textTransform: 'uppercase', letterSpacing: '0.03em', flexShrink: 0 }}>{roleLabel}</span>
                      <div style={{ flex: 1, minWidth: 0 }}>
                        <AirportSelect value={wp.airport} onChange={a => updateWp({ airport: a || null })} />
                      </div>
                      {!isFirst && !isLast && (
                        <button type="button" onClick={() => setWaypoints(prev => prev.filter((_, j) => j !== i))} aria-label={t('common.delete')} className="text-content-faint" style={{ background: 'none', border: 'none', cursor: 'pointer', display: 'flex', padding: 4, flexShrink: 0 }}>
                          <Trash2 size={14} />
                        </button>
                      )}
                    </div>
                    {!isFirst && (
                      <div style={{ display: 'flex', gap: 8 }}>
                        <div style={{ flex: 1, minWidth: 0 }}>
                          <label className={labelClass}>{t('reservations.arrivalDate')}</label>
                          <CustomSelect value={wp.arrDayId} onChange={v => updateWp({ arrDayId: v })} placeholder={t('dayplan.dayN', { n: '?' })} options={dayOptions} size="sm" />
                        </div>
                        <div style={{ flex: 1, minWidth: 0 }}>
                          <label className={labelClass}>{t('reservations.arrivalTime')}</label>
                          <CustomTimePicker value={wp.arrTime} onChange={v => updateWp({ arrTime: v })} />
                        </div>
                        {wp.airport && (
                          <div style={{ flex: 1, minWidth: 0 }}>
                            <label className={labelClass}>{t('reservations.meta.arrivalTimezone')}</label>
                            <div className={inputClass} style={{ padding: '8px 12px', color: 'var(--text-muted)', fontSize: 12, background: 'var(--bg-tertiary)' }}>{wp.airport.tz}</div>
                          </div>
                        )}
                      </div>
                    )}
                    {!isLast && (
                      <>
                        <div style={{ display: 'flex', gap: 8 }}>
                          <div style={{ flex: 1, minWidth: 0 }}>
                            <label className={labelClass}>{t('reservations.departureDate')}</label>
                            <CustomSelect value={wp.depDayId} onChange={v => updateWp({ depDayId: v })} placeholder={t('dayplan.dayN', { n: '?' })} options={dayOptions} size="sm" />
                          </div>
                          <div style={{ flex: 1, minWidth: 0 }}>
                            <label className={labelClass}>{t('reservations.departureTime')}</label>
                            <CustomTimePicker value={wp.depTime} onChange={v => updateWp({ depTime: v })} />
                          </div>
                          {wp.airport && (
                            <div style={{ flex: 1, minWidth: 0 }}>
                              <label className={labelClass}>{t('reservations.meta.departureTimezone')}</label>
                              <div className={inputClass} style={{ padding: '8px 12px', color: 'var(--text-muted)', fontSize: 12, background: 'var(--bg-tertiary)' }}>{wp.airport.tz}</div>
                            </div>
                          )}
                        </div>
                        <div className="grid grid-cols-1 sm:grid-cols-3 gap-3">
                          <div>
                            <label className={labelClass}>{t('reservations.meta.airline')}</label>
                            <input type="text" value={wp.airline} onChange={e => updateWp({ airline: e.target.value })} placeholder="Lufthansa" className={inputClass} />
                          </div>
                          <div>
                            <label className={labelClass}>{t('reservations.meta.flightNumber')}</label>
                            <input type="text" value={wp.flight_number} onChange={e => updateWp({ flight_number: e.target.value })} placeholder="LH 123" className={inputClass} />
                          </div>
                          <div>
                            <label className={labelClass}>{t('reservations.meta.seat')}</label>
                            <input type="text" value={wp.seat} onChange={e => updateWp({ seat: e.target.value })} placeholder="12A" className={inputClass} />
                          </div>
                        </div>
                      </>
                    )}
                  </div>
                  {!isLast && (
                    <button type="button" onClick={() => setWaypoints(prev => [...prev.slice(0, i + 1), emptyWaypoint(prev[i]?.depDayId || ''), ...prev.slice(i + 1)])}
                      className="text-content-faint hover:text-content-secondary" style={{ width: '100%', display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 5, padding: '6px 10px', border: '1px dashed var(--border-primary)', borderRadius: 8, background: 'none', fontSize: 11, cursor: 'pointer', fontFamily: 'inherit' }}>
                      <Plus size={12} /> {t('reservations.layover.addStop')}
                    </button>
                  )}
                </div>
              )
            })}
          </div>
        ) : (
          <>
            {/* From / To endpoints (non-flight) */}
            <div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
              <div>
                <label className={labelClass}>{t('reservations.meta.from')}</label>
                <LocationSelect value={fromPick.location || null} onChange={l => setFromPick({ location: l || undefined })} />
              </div>
              <div>
                <label className={labelClass}>{t('reservations.meta.to')}</label>
                <LocationSelect value={toPick.location || null} onChange={l => setToPick({ location: l || undefined })} />
              </div>
            </div>

            {/* Departure row */}
            <div style={{ display: 'flex', gap: 8 }}>
              <div style={{ flex: 1, minWidth: 0 }}>
                <label className={labelClass}>{form.type === 'car' ? t('reservations.pickupDate') : t('reservations.date')}</label>
                <CustomSelect value={form.start_day_id} onChange={value => set('start_day_id', value)} placeholder={t('dayplan.dayN', { n: '?' })} options={dayOptions} size="sm" />
              </div>
              <div style={{ flex: 1, minWidth: 0 }}>
                <label className={labelClass}>{form.type === 'car' ? t('reservations.pickupTime') : t('reservations.startTime')}</label>
                <CustomTimePicker value={form.departure_time} onChange={v => set('departure_time', v)} />
              </div>
            </div>

            {/* Arrival row */}
            <div style={{ display: 'flex', gap: 8 }}>
              <div style={{ flex: 1, minWidth: 0 }}>
                <label className={labelClass}>{form.type === 'car' ? t('reservations.returnDate') : t('reservations.endDate')}</label>
                <CustomSelect value={form.end_day_id} onChange={value => set('end_day_id', value)} placeholder={t('dayplan.dayN', { n: '?' })} options={dayOptions} size="sm" />
              </div>
              <div style={{ flex: 1, minWidth: 0 }}>
                <label className={labelClass}>{form.type === 'car' ? t('reservations.returnTime') : t('reservations.endTime')}</label>
                <CustomTimePicker value={form.arrival_time} onChange={v => set('arrival_time', v)} />
              </div>
            </div>
          </>
        )}

        {/* Train-specific fields */}
        {form.type === 'train' && (
          <div className="grid grid-cols-3 gap-3">
            <div>
              <label className={labelClass}>{t('reservations.meta.trainNumber')}</label>
              <input type="text" value={form.meta_train_number} onChange={e => set('meta_train_number', e.target.value)}
                placeholder="ICE 123" className={inputClass} />
            </div>
            <div>
              <label className={labelClass}>{t('reservations.meta.platform')}</label>
              <input type="text" value={form.meta_platform} onChange={e => set('meta_platform', e.target.value)}
                placeholder="12" className={inputClass} />
            </div>
            <div>
              <label className={labelClass}>{t('reservations.meta.seat')}</label>
              <input type="text" value={form.meta_seat} onChange={e => set('meta_seat', e.target.value)}
                placeholder="42A" className={inputClass} />
            </div>
          </div>
        )}

        {/* Booking Code + Status */}
        <div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
          <div>
            <label className={labelClass}>{t('reservations.confirmationCode')}</label>
            <input type="text" value={form.confirmation_number} onChange={e => set('confirmation_number', e.target.value)}
              placeholder={t('reservations.confirmationPlaceholder')} className={inputClass} />
          </div>
          <div>
            <label className={labelClass}>{t('reservations.status')}</label>
            <CustomSelect
              value={form.status}
              onChange={value => set('status', value)}
              options={[
                { value: 'pending', label: t('reservations.pending') },
                { value: 'confirmed', label: t('reservations.confirmed') },
              ]}
              size="sm"
            />
          </div>
        </div>

        {/* Notes */}
        <div>
          <label className={labelClass}>{t('reservations.notes')}</label>
          <textarea value={form.notes} onChange={e => set('notes', e.target.value)} rows={2}
            placeholder={t('reservations.notesPlaceholder')}
            className={inputClass} style={{ resize: 'none', lineHeight: 1.5 }} />
        </div>

        {/* Files */}
        <div>
          <label className={labelClass}>{t('files.title')}</label>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
            {attachedFiles.map(f => (
              <div key={f.id} className="bg-surface-secondary" style={{ display: 'flex', alignItems: 'center', gap: 8, padding: '5px 10px', borderRadius: 8 }}>
                <FileText size={12} className="text-content-muted" style={{ flexShrink: 0 }} />
                <span className="text-content-secondary" style={{ flex: 1, fontSize: 12, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{f.original_name}</span>
                <a href="#" onClick={(e) => { e.preventDefault(); openFile(f.url).catch(() => {}) }} className="text-content-faint" style={{ display: 'flex', flexShrink: 0, cursor: 'pointer' }}><ExternalLink size={11} /></a>
                <button type="button" onClick={async () => {
                  if (f.reservation_id === reservation?.id) {
                    try { await apiClient.put(`/trips/${tripId}/files/${f.id}`, { reservation_id: null }) } catch { toast.error(t('reservations.toast.updateError')) }
                  }
                  try {
                    const linksRes = await apiClient.get(`/trips/${tripId}/files/${f.id}/links`)
                    const link = (linksRes.data.links || []).find((l: any) => l.reservation_id === reservation?.id)
                    if (link) await apiClient.delete(`/trips/${tripId}/files/${f.id}/link/${link.id}`)
                  } catch { toast.error(t('reservations.toast.updateError')) }
                  setLinkedFileIds(prev => prev.filter(id => id !== f.id))
                  if (tripId) loadFiles(tripId)
                }} className="text-content-faint" style={{ background: 'none', border: 'none', cursor: 'pointer', display: 'flex', padding: 0, flexShrink: 0 }}>
                  <X size={11} />
                </button>
              </div>
            ))}
            {pendingFiles.map((f, i) => (
              <div key={i} className="bg-surface-secondary" style={{ display: 'flex', alignItems: 'center', gap: 8, padding: '5px 10px', borderRadius: 8 }}>
                <FileText size={12} className="text-content-muted" style={{ flexShrink: 0 }} />
                <span className="text-content-secondary" style={{ flex: 1, fontSize: 12, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{f.name}</span>
                <button type="button" onClick={() => setPendingFiles(prev => prev.filter((_, j) => j !== i))}
                  className="text-content-faint" style={{ background: 'none', border: 'none', cursor: 'pointer', display: 'flex', padding: 0, flexShrink: 0 }}>
                  <X size={11} />
                </button>
              </div>
            ))}
            <input ref={fileInputRef} type="file" accept=".pdf,.doc,.docx,.txt,image/*" style={{ display: 'none' }} onChange={handleFileChange} />
            <div style={{ display: 'flex', gap: 6, flexWrap: 'wrap' }}>
              {onFileUpload && <button type="button" onClick={() => fileInputRef.current?.click()} disabled={uploadingFile} className="text-content-faint" style={{
                display: 'flex', alignItems: 'center', gap: 5, padding: '6px 10px',
                border: '1px dashed var(--border-primary)', borderRadius: 8, background: 'none',
                fontSize: 11, cursor: uploadingFile ? 'default' : 'pointer', fontFamily: 'inherit',
              }}>
                <Paperclip size={11} />
                {uploadingFile ? t('reservations.uploading') : t('reservations.attachFile')}
              </button>}
              {reservation?.id && files.filter(f => !f.deleted_at && !attachedFiles.some(af => af.id === f.id)).length > 0 && (
                <div style={{ position: 'relative' }}>
                  <button type="button" onClick={() => setShowFilePicker(v => !v)} className="text-content-faint" style={{
                    display: 'flex', alignItems: 'center', gap: 5, padding: '6px 10px',
                    border: '1px dashed var(--border-primary)', borderRadius: 8, background: 'none',
                    fontSize: 11, cursor: 'pointer', fontFamily: 'inherit',
                  }}>
                    <Link2 size={11} /> {t('reservations.linkExisting')}
                  </button>
                  {showFilePicker && (
                    <div className="bg-surface-card" style={{
                      position: 'absolute', bottom: '100%', left: 0, marginBottom: 4, zIndex: 50,
                      border: '1px solid var(--border-primary)', borderRadius: 10,
                      boxShadow: '0 4px 16px rgba(0,0,0,0.12)', padding: 4, minWidth: 220, maxHeight: 200, overflowY: 'auto',
                    }}>
                      {files.filter(f => !f.deleted_at && !attachedFiles.some(af => af.id === f.id)).map(f => (
                        <button key={f.id} type="button" onClick={async () => {
                          try {
                            await apiClient.post(`/trips/${tripId}/files/${f.id}/link`, { reservation_id: reservation.id })
                            setLinkedFileIds(prev => [...prev, f.id])
                            setShowFilePicker(false)
                            if (tripId) loadFiles(tripId)
                          } catch { toast.error(t('reservations.toast.updateError')) }
                        }}
                          className="text-content-secondary"
                          style={{
                            display: 'flex', alignItems: 'center', gap: 8, width: '100%', padding: '6px 10px',
                            background: 'none', border: 'none', cursor: 'pointer', fontSize: 12, fontFamily: 'inherit',
                            borderRadius: 7, textAlign: 'left',
                          }}
                          onMouseEnter={e => e.currentTarget.style.background = 'var(--bg-tertiary)'}
                          onMouseLeave={e => e.currentTarget.style.background = 'none'}>
                          <FileText size={12} className="text-content-faint" style={{ flexShrink: 0 }} />
                          <span style={{ overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{f.original_name}</span>
                        </button>
                      ))}
                    </div>
                  )}
                </div>
              )}
            </div>
          </div>
        </div>

        {/* Price + Budget Category */}
        {isBudgetEnabled && (
          <>
            <div style={{ display: 'flex', gap: 8 }}>
              <div style={{ flex: 1, minWidth: 0 }}>
                <label className={labelClass}>{t('reservations.price')}</label>
                <input type="text" inputMode="decimal" value={form.price}
                  onChange={e => { const v = e.target.value; if (v === '' || /^\d*[.,]?\d{0,2}$/.test(v)) set('price', v.replace(',', '.')) }}
                  onPaste={e => { e.preventDefault(); let txt = e.clipboardData.getData('text').trim().replace(/[^\d.,-]/g, ''); const lc = txt.lastIndexOf(','), ld = txt.lastIndexOf('.'), dp = Math.max(lc, ld); if (dp > -1) { txt = txt.substring(0, dp).replace(/[.,]/g, '') + '.' + txt.substring(dp + 1) } else { txt = txt.replace(/[.,]/g, '') } set('price', txt) }}
                  placeholder="0.00"
                  className={inputClass} />
              </div>
              <div style={{ flex: 1, minWidth: 0 }}>
                <label className={labelClass}>{t('reservations.budgetCategory')}</label>
                <CustomSelect
                  value={form.budget_category}
                  onChange={v => set('budget_category', v)}
                  options={[
                    { value: '', label: t('reservations.budgetCategoryAuto') },
                    ...budgetCategories.map(c => ({ value: c, label: c })),
                  ]}
                  placeholder={t('reservations.budgetCategoryAuto')}
                  size="sm"
                />
              </div>
            </div>
            {form.price && parseFloat(form.price) > 0 && (
              <div className="text-content-faint" style={{ fontSize: 11, marginTop: -4 }}>
                {t('reservations.budgetHint')}
              </div>
            )}
          </>
        )}

      </form>
    </Modal>
  )
}
