'use client'

import { useState, useEffect } from 'react'
import { BASE } from '@/lib/basepath'
import type { DeliveryTier } from '@/lib/delivery'
import type { TimeSlot } from '@/lib/slots'
import type { HoursConfig } from '@/lib/hours-config'
import CalendarPicker from './CalendarPicker'

export interface DeliverySelection {
  date:         string   // YYYY-MM-DD
  slotISO:      string   // UTC ISO start time
  label:        string   // human label e.g. "10:00 AM"
  driveMinutes: number
}

interface Props {
  address:  string
  tier:     DeliveryTier
  value:    DeliverySelection | null
  onChange: (v: DeliverySelection | null) => void
}

type SlotState = 'idle' | 'loading' | 'loaded' | 'error'

const maxDate = new Date(Date.now() + 90 * 86400_000).toISOString().slice(0, 10)

export default function DeliveryDatePicker({ address, tier, value, onChange }: Props) {
  const [date,         setDate]         = useState(value?.date ?? '')
  const [slots,        setSlots]        = useState<TimeSlot[]>([])
  const [drive,        setDrive]        = useState(0)
  const [status,       setStatus]       = useState<SlotState>('idle')
  const [errMsg,       setErrMsg]       = useState('')
  const [leadTimeHours, setLeadTimeHours] = useState(48)

  // Dates that returned 0 slots — shown as strikethrough on the calendar
  const [noSlotDates, setNoSlotDates] = useState<Set<string>>(new Set())

  // Busy dates from CalDAV — shown with an orange dot
  const [busyDates, setBusyDates] = useState<Set<string>>(new Set())

  const minDate = new Date(Date.now() + leadTimeHours * 60 * 60 * 1000).toISOString().slice(0, 10)

  // Pre-mark all closed delivery days from admin hours config
  useEffect(() => {
    fetch(`${BASE}/api/hours`)
      .then(r => r.ok ? r.json() : null)
      .then((config: HoursConfig | null) => {
        if (!config) return
        const lead   = config.leadTimeHours ?? 48
        setLeadTimeHours(lead)
        const closed = new Set<string>()
        const start  = Date.now() + lead * 60 * 60 * 1000
        for (let i = 0; i < 90; i++) {
          const dateStr = new Date(start + i * 86400_000).toISOString().slice(0, 10)
          const dow     = new Date(`${dateStr}T12:00:00Z`).getUTCDay()
          if (!config.delivery[String(dow)]) closed.add(dateStr)
        }
        setNoSlotDates(closed)
      })
      .catch(() => {/* non-fatal */})
  }, [])

  // Fetch busy dates once on mount
  useEffect(() => {
    if (!process.env.NEXT_PUBLIC_SITE_URL && typeof window === 'undefined') return
    fetch(`${BASE}/api/availability?days=90`)
      .then(r => r.ok ? r.json() : null)
      .then((data) => {
        if (!data?.busy) return
        const dates = new Set<string>(
          (data.busy as Array<{ start: string }>).map(b => b.start.slice(0, 10))
        )
        setBusyDates(dates)
      })
      .catch(() => {/* non-fatal */})
  }, [])

  // Fetch slots when date or address changes
  useEffect(() => {
    if (!date || !address) return
    setStatus('loading')
    setSlots([])
    onChange(null)

    const params = new URLSearchParams({ date, address, tier })
    fetch(`${BASE}/api/slots?${params}`)
      .then((r) => r.json())
      .then((data) => {
        if (data.error) { setErrMsg(data.error); setStatus('error'); return }
        const fetched: TimeSlot[] = data.slots ?? []
        setSlots(fetched)
        setDrive(data.driveMinutes ?? 0)
        setStatus('loaded')
        if (fetched.length === 0) {
          setNoSlotDates(prev => { const s = new Set(prev); s.add(date); return s })
        }
      })
      .catch(() => { setErrMsg('Could not load time slots.'); setStatus('error') })
  }, [date, address, tier]) // eslint-disable-line react-hooks/exhaustive-deps

  const selectSlot = (slot: TimeSlot) => {
    onChange({ date, slotISO: slot.startISO, label: slot.label, driveMinutes: drive })
  }

  return (
    <div style={{ marginBottom: '0.75rem' }}>
      <p style={{ fontWeight: 'bold', fontSize: '0.85rem', marginBottom: '0.5rem' }}>
        Delivery date &amp; time
      </p>

      <div style={{ border: '1px solid #e0e0e0', borderRadius: '8px', padding: '0.6rem', marginBottom: '0.5rem' }}>
        <CalendarPicker
          selected={date}
          onSelect={(d) => { setDate(d); onChange(null) }}
          minDate={minDate}
          maxDate={maxDate}
          disabledDates={noSlotDates}
          busyDates={busyDates}
        />
      </div>

      {status === 'loading' && (
        <p className="is-size-7 has-text-grey">Checking availability…</p>
      )}

      {status === 'error' && (
        <p style={{ fontSize: '0.75rem', color: '#cc3333', lineHeight: 1.4 }}>
          {errMsg}{' '}
          <a href="https://beachpartyballoons.com/contact/" style={{ color: '#cc3333', textDecoration: 'underline' }}>
            Contact us
          </a>{' '}
          to book manually.
        </p>
      )}

      {status === 'loaded' && slots.length === 0 && (
        <p style={{ fontSize: '0.78rem', color: '#888' }}>
          No availability on this date — please try another day, or{' '}
          <a href="https://beachpartyballoons.com/contact/" style={{ textDecoration: 'underline' }}>
            contact us
          </a>.
        </p>
      )}

      {status === 'loaded' && slots.length > 0 && (
        <>
          <p className="is-size-7 has-text-grey" style={{ marginBottom: '0.35rem' }}>
            ~{drive} min drive &nbsp;·&nbsp; Please reserve <strong>at least 1 hour</strong> at your venue &nbsp;·&nbsp; select a start time
          </p>
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: '5px' }}>
            {slots.map((slot) => {
              const chosen = value?.slotISO === slot.startISO
              return (
                <button
                  key={slot.startISO}
                  type="button"
                  onClick={() => selectSlot(slot)}
                  style={{
                    padding:      '5px 4px',
                    fontSize:     '0.78rem',
                    borderRadius: '6px',
                    border:       `1px solid ${chosen ? '#11b3be' : '#d0d0d0'}`,
                    background:   chosen ? '#11b3be' : '#fff',
                    color:        chosen ? '#fff' : '#333',
                    cursor:       'pointer',
                    fontWeight:   chosen ? 'bold' : 'normal',
                    fontFamily:   'inherit',
                  }}
                >
                  {slot.label}
                </button>
              )
            })}
          </div>
        </>
      )}
    </div>
  )
}
