import ReactDOM from 'react-dom'
import { X, MapPin, Ticket, Check } from 'lucide-react'
import { filesApi } from '../../api/client'
import type { Place, Reservation, Day } from '../../types'
import type { FileManagerState } from './useFileManager'
import { TRANSPORT_TYPES } from './FileManager.constants'
import { transportIcon } from './FileManager.helpers'

export function AssignModal(S: FileManagerState) {
  const { files, assignFileId, setAssignFileId, t, days, assignments, places, reservations, tripId, handleAssign, refreshFiles } = S
  return ReactDOM.createPortal(
    <div style={{ position: 'fixed', inset: 0, background: 'rgba(0,0,0,0.5)', zIndex: 5000, display: 'flex', alignItems: 'center', justifyContent: 'center' }}
      onClick={() => setAssignFileId(null)}>
      <div style={{
        background: 'var(--bg-card)', borderRadius: 16, boxShadow: '0 20px 60px rgba(0,0,0,0.2)',
        width: 'min(600px, calc(100vw - 32px))', maxHeight: '70vh', overflow: 'hidden', display: 'flex', flexDirection: 'column',
      }} onClick={e => e.stopPropagation()}>
        <div style={{ padding: '16px 20px 12px', borderBottom: '1px solid var(--border-primary)', display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 12 }}>
          <div style={{ flex: 1, minWidth: 0 }}>
            <div style={{ fontSize: 15, fontWeight: 600, color: 'var(--text-primary)' }}>{t('files.assignTitle')}</div>
            <div style={{ fontSize: 12, color: 'var(--text-faint)', marginTop: 2, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
              {files.find(f => f.id === assignFileId)?.original_name || ''}
            </div>
          </div>
          <button onClick={() => setAssignFileId(null)} style={{ background: 'none', border: 'none', cursor: 'pointer', color: 'var(--text-faint)', padding: 4, display: 'flex', flexShrink: 0 }}>
            <X size={18} />
          </button>
        </div>
        <div style={{ padding: '8px 12px 0' }}>
          <div style={{ fontSize: 11, fontWeight: 600, color: 'var(--text-faint)', padding: '0 2px 4px', textTransform: 'uppercase', letterSpacing: 0.5 }}>
            {t('files.noteLabel') || 'Note'}
          </div>
          <input
            type="text"
            placeholder={t('files.notePlaceholder')}
            defaultValue={files.find(f => f.id === assignFileId)?.description || ''}
            onBlur={e => {
              const val = e.target.value.trim()
              const file = files.find(f => f.id === assignFileId)
              if (file && val !== (file.description || '')) {
                handleAssign(file.id, { description: val } as any)
              }
            }}
            onKeyDown={e => { if (e.key === 'Enter') (e.target as HTMLInputElement).blur() }}
            style={{
              width: '100%', padding: '7px 10px', fontSize: 13, borderRadius: 8,
              border: '1px solid var(--border-primary)', background: 'var(--bg-secondary)',
              color: 'var(--text-primary)', fontFamily: 'inherit', outline: 'none',
            }}
          />
        </div>
        <div style={{ overflowY: 'auto', padding: 8 }}>
          {(() => {
            const file = files.find(f => f.id === assignFileId)
            if (!file) return null
            const assignedPlaceIds = new Set<number>()
            const dayGroups: { day: Day; dayPlaces: Place[] }[] = []
            for (const day of days) {
              const da = assignments[String(day.id)] || []
              const dayPlaces = da.map(a => places.find(p => p.id === a.place?.id || p.id === a.place_id)).filter(Boolean) as Place[]
              if (dayPlaces.length > 0) {
                dayGroups.push({ day, dayPlaces })
                dayPlaces.forEach(p => assignedPlaceIds.add(p.id))
              }
            }
            const unassigned = places.filter(p => !assignedPlaceIds.has(p.id))
            const placeBtn = (p: Place, idx: number) => {
              const isLinked = file.place_id === p.id || (file.linked_place_ids || []).includes(p.id)
              return (
                <button key={`${p.id}-${idx}`} onClick={async () => {
                  if (isLinked) {
                    if (file.place_id === p.id) {
                      await handleAssign(file.id, { place_id: null })
                    } else {
                      try {
                        const linksRes = await filesApi.getLinks(tripId, file.id)
                        const link = (linksRes.links || []).find((l: any) => l.place_id === p.id)
                        if (link) await filesApi.removeLink(tripId, file.id, link.id)
                        refreshFiles()
                      } catch {}
                    }
                  } else {
                    if (!file.place_id) {
                      await handleAssign(file.id, { place_id: p.id })
                    } else {
                      try {
                        await filesApi.addLink(tripId, file.id, { place_id: p.id })
                        refreshFiles()
                      } catch {}
                    }
                  }
                }} style={{
                  width: '100%', textAlign: 'left', padding: '6px 10px 6px 20px', background: isLinked ? 'var(--bg-hover)' : 'none',
                  border: 'none', cursor: 'pointer', fontSize: 13, color: 'var(--text-primary)',
                  borderRadius: 8, fontFamily: 'inherit', fontWeight: isLinked ? 600 : 400,
                  display: 'flex', alignItems: 'center', gap: 6,
                }}
                  onMouseEnter={e => e.currentTarget.style.background = 'var(--bg-hover)'}
                  onMouseLeave={e => e.currentTarget.style.background = isLinked ? 'var(--bg-hover)' : 'transparent'}>
                  <MapPin size={12} style={{ flexShrink: 0, color: 'var(--text-muted)' }} />
                  <span style={{ overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{p.name}</span>
                  {isLinked && <Check size={14} style={{ marginLeft: 'auto', flexShrink: 0, color: 'var(--accent)' }} />}
                </button>
              )
            }

            const placesSection = places.length > 0 && (
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{ fontSize: 11, fontWeight: 600, color: 'var(--text-faint)', padding: '8px 10px 4px', textTransform: 'uppercase', letterSpacing: 0.5 }}>
                  {t('files.assignPlace')}
                </div>
                {dayGroups.map(({ day, dayPlaces }) => (
                  <div key={day.id}>
                    <div style={{ display: 'flex', alignItems: 'center', gap: 6, fontSize: 11, fontWeight: 600, color: 'var(--text-muted)', padding: '8px 10px 2px' }}>
                      <span>{day.title || t('dayplan.dayN', { n: day.day_number })}</span>
                      {(() => {
                        const badge = day.date || (day.title ? t('dayplan.dayN', { n: day.day_number }) : null)
                        return badge ? (
                          <span style={{
                            fontSize: 10, fontWeight: 600, color: 'var(--text-faint)',
                            background: 'var(--bg-tertiary)', padding: '1px 6px', borderRadius: 999,
                          }}>{badge}</span>
                        ) : null
                      })()}
                    </div>
                    {dayPlaces.map(placeBtn)}
                  </div>
                ))}
                {unassigned.length > 0 && (
                  <div>
                    {dayGroups.length > 0 && <div style={{ fontSize: 11, fontWeight: 600, color: 'var(--text-muted)', padding: '8px 10px 2px' }}>{t('files.unassigned')}</div>}
                    {unassigned.map(placeBtn)}
                  </div>
                )}
              </div>
            )

            const bookingReservations = reservations.filter(r => !TRANSPORT_TYPES.has(r.type))
            const transportReservations = reservations.filter(r => TRANSPORT_TYPES.has(r.type))

            const reservationBtn = (r: Reservation) => {
              const isLinked = file.reservation_id === r.id || (file.linked_reservation_ids || []).includes(r.id)
              const Icon = TRANSPORT_TYPES.has(r.type) ? transportIcon(r.type) : Ticket
              return (
                <button key={r.id} onClick={async () => {
                  if (isLinked) {
                    if (file.reservation_id === r.id) {
                      await handleAssign(file.id, { reservation_id: null })
                    } else {
                      try {
                        const linksRes = await filesApi.getLinks(tripId, file.id)
                        const link = (linksRes.links || []).find((l: any) => l.reservation_id === r.id)
                        if (link) await filesApi.removeLink(tripId, file.id, link.id)
                        refreshFiles()
                      } catch {}
                    }
                  } else {
                    if (!file.reservation_id) {
                      await handleAssign(file.id, { reservation_id: r.id })
                    } else {
                      try {
                        await filesApi.addLink(tripId, file.id, { reservation_id: r.id })
                        refreshFiles()
                      } catch {}
                    }
                  }
                }} style={{
                  width: '100%', textAlign: 'left', padding: '6px 10px 6px 20px', background: isLinked ? 'var(--bg-hover)' : 'none',
                  border: 'none', cursor: 'pointer', fontSize: 13, color: 'var(--text-primary)',
                  borderRadius: 8, fontFamily: 'inherit', fontWeight: isLinked ? 600 : 400,
                  display: 'flex', alignItems: 'center', gap: 6,
                }}
                  onMouseEnter={e => e.currentTarget.style.background = 'var(--bg-hover)'}
                  onMouseLeave={e => e.currentTarget.style.background = isLinked ? 'var(--bg-hover)' : 'transparent'}>
                  <Icon size={12} style={{ flexShrink: 0, color: 'var(--text-muted)' }} />
                  <span style={{ overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{r.title}</span>
                  {isLinked && <Check size={14} style={{ marginLeft: 'auto', flexShrink: 0, color: 'var(--accent)' }} />}
                </button>
              )
            }

            const bookingsSection = reservations.length > 0 && (
              <div style={{ flex: 1, minWidth: 0 }}>
                {bookingReservations.length > 0 && (
                  <>
                    <div style={{ fontSize: 11, fontWeight: 600, color: 'var(--text-faint)', padding: '8px 10px 4px', textTransform: 'uppercase', letterSpacing: 0.5 }}>
                      {t('files.assignBooking')}
                    </div>
                    {bookingReservations.map(reservationBtn)}
                  </>
                )}
                {transportReservations.length > 0 && (
                  <>
                    <div style={{ fontSize: 11, fontWeight: 600, color: 'var(--text-faint)', padding: '8px 10px 4px', textTransform: 'uppercase', letterSpacing: 0.5, marginTop: bookingReservations.length > 0 ? 4 : 0 }}>
                      {t('files.assignTransport')}
                    </div>
                    {transportReservations.map(reservationBtn)}
                  </>
                )}
              </div>
            )

            const hasBoth = placesSection && bookingsSection
            return (
              <div className={hasBoth ? 'md:flex' : ''}>
                <div className={hasBoth ? 'md:w-1/2' : ''} style={{ overflowY: 'auto', maxHeight: '55vh', paddingRight: hasBoth ? 6 : 0 }}>{placesSection}</div>
                {hasBoth && <div className="hidden md:block" style={{ width: 1, background: 'var(--border-primary)', flexShrink: 0 }} />}
                {hasBoth && <div className="block md:hidden" style={{ height: 1, background: 'var(--border-primary)', margin: '8px 0' }} />}
                <div className={hasBoth ? 'md:w-1/2' : ''} style={{ overflowY: 'auto', maxHeight: '55vh', paddingLeft: hasBoth ? 6 : 0 }}>{bookingsSection}</div>
              </div>
            )
          })()}
        </div>
      </div>
    </div>,
    document.body
  )
}
