import React, { useCallback, useEffect, useMemo, useState } from 'react'
import DateTimePicker from '../ui/DateTimePicker'

/**
 * SchedulePublishPicker
 *
 * Toggle between "Publish now" and "Schedule publish".
 * When scheduled, shows a date + time input with validation
 * (must be >= now + 5 minutes).
 *
 * Props:
 *   mode            'now' | 'schedule'
 *   scheduledAt     ISO string | null  – current scheduled datetime (UTC)
 *   timezone        string             – IANA tz (e.g. 'Europe/Ljubljana')
 *   onModeChange    (mode) => void
 *   onScheduleAt    (iso | null) => void
 *   disabled        bool
 */
function toLocalDateTimeString(isoString, tz) {
  if (!isoString) return { date: '', time: '' }
  try {
    const d = new Date(isoString)
    const opts = { timeZone: tz, year: 'numeric', month: '2-digit', day: '2-digit' }
    const dateStr = new Intl.DateTimeFormat('en-CA', opts).format(d) // en-CA gives YYYY-MM-DD
    const timeStr = new Intl.DateTimeFormat('en-GB', {
      timeZone: tz,
      hour: '2-digit',
      minute: '2-digit',
      hour12: false,
    }).format(d)
    return { date: dateStr, time: timeStr }
  } catch {
    return { date: '', time: '' }
  }
}

function formatPreviewLabel(isoString, tz) {
  if (!isoString) return null
  try {
    return new Intl.DateTimeFormat('en-GB', {
      timeZone: tz,
      weekday: 'short',
      day: 'numeric',
      month: 'short',
      year: 'numeric',
      hour: '2-digit',
      minute: '2-digit',
      hour12: false,
      timeZoneName: 'short',
    }).format(new Date(isoString))
  } catch {
    return isoString
  }
}

function localToUtcIso(dateStr, timeStr, tz) {
  if (!dateStr || !timeStr) return null
  try {
    const dtStr = `${dateStr}T${timeStr}:00`
    const local = new Date(
      new Date(dtStr).toLocaleString('en-US', { timeZone: tz })
    )
    const utcOffset = new Date(dtStr) - local
    const utcDate = new Date(new Date(dtStr).getTime() + utcOffset)
    return utcDate.toISOString()
  } catch {
    return null
  }
}

const MIN_FUTURE_MS = 5 * 60 * 1000 // 5 minutes

export default function SchedulePublishPicker({
  mode = 'now',
  scheduledAt = null,
  timezone = Intl.DateTimeFormat().resolvedOptions().timeZone,
  onModeChange,
  onScheduleAt,
  disabled = false,
}) {
  const initial = useMemo(
    () => toLocalDateTimeString(scheduledAt, timezone),
    // eslint-disable-next-line react-hooks/exhaustive-deps
    []
  )
  const [localDateTime, setLocalDateTime] = useState(initial.date && initial.time ? `${initial.date}T${initial.time}` : '')
  const [error, setError] = useState('')
  const minScheduleLocalDateTime = (() => {
    const next = toLocalDateTimeString(new Date(Date.now() + MIN_FUTURE_MS).toISOString(), timezone)
    return next.date && next.time ? `${next.date}T${next.time}` : ''
  })()

  const validate = useCallback(
    (value) => {
      const [datePart = '', timePart = ''] = String(value || '').split('T')
      if (!datePart || !timePart) return 'Date and time are required.'
      const iso = localToUtcIso(datePart, timePart.slice(0, 5), timezone)
      if (!iso) return 'Invalid date or time.'
      const target = new Date(iso)
      if (Number.isNaN(target.getTime())) return 'Invalid date or time.'
      if (target.getTime() - Date.now() < MIN_FUTURE_MS) {
        return 'Scheduled time must be at least 5 minutes in the future.'
      }
      return ''
    },
    [timezone]
  )

  useEffect(() => {
    const next = toLocalDateTimeString(scheduledAt, timezone)
    setLocalDateTime(next.date && next.time ? `${next.date}T${next.time}` : '')
  }, [scheduledAt, timezone])

  useEffect(() => {
    if (mode !== 'schedule') {
      setError('')
      return
    }
    if (!localDateTime) {
      setError('')
      onScheduleAt?.(null)
      return
    }
    const err = validate(localDateTime)
    setError(err)
    if (!err) {
      const [datePart = '', timePart = ''] = localDateTime.split('T')
      onScheduleAt?.(localToUtcIso(datePart, timePart.slice(0, 5), timezone))
    } else {
      onScheduleAt?.(null)
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [localDateTime, mode, timezone])

  const previewLabel = useMemo(() => {
    if (mode !== 'schedule' || error) return null
    const [datePart = '', timePart = ''] = localDateTime.split('T')
    const iso = localToUtcIso(datePart, timePart.slice(0, 5), timezone)
    return formatPreviewLabel(iso, timezone)
  }, [mode, error, localDateTime, timezone])

  return (
    <div className="space-y-3">
      <div className="flex gap-2" role="group" aria-label="Publish mode">
        <button
          type="button"
          disabled={disabled}
          onClick={() => {
            onModeChange?.('now')
            setError('')
          }}
          className={[
            'flex-1 rounded-lg border py-2 text-sm transition',
            mode === 'now'
              ? 'border-sky-300/60 bg-sky-500/25 text-white'
              : 'border-white/15 bg-white/6 text-white/60 hover:bg-white/10',
            disabled ? 'cursor-not-allowed opacity-50' : '',
          ].join(' ')}
          aria-pressed={mode === 'now'}
        >
          Publish now
        </button>
        <button
          type="button"
          disabled={disabled}
          onClick={() => onModeChange?.('schedule')}
          className={[
            'flex-1 rounded-lg border py-2 text-sm transition',
            mode === 'schedule'
              ? 'border-sky-300/60 bg-sky-500/25 text-white'
              : 'border-white/15 bg-white/6 text-white/60 hover:bg-white/10',
            disabled ? 'cursor-not-allowed opacity-50' : '',
          ].join(' ')}
          aria-pressed={mode === 'schedule'}
        >
          Schedule
        </button>
      </div>

      {mode === 'schedule' && (
        <div className="space-y-2 rounded-xl border border-white/10 bg-white/[0.03] p-3">
          <DateTimePicker
            id="schedule-datetime"
            label="Release date and time"
            value={localDateTime}
            onChange={setLocalDateTime}
            placeholder="Pick a release slot"
            disabled={disabled}
            minDateTime={minScheduleLocalDateTime}
            clearable
            hint={`Timezone: ${timezone}`}
            error={error}
          />

          {previewLabel && (
            <p className="text-xs text-emerald-300/80">
              Will publish on: <span className="font-medium">{previewLabel}</span>
            </p>
          )}
        </div>
      )}
    </div>
  )
}
