import DayColumn from './DayColumn'
import { getDeviceAccentClass } from './TestCard'

function addDays(date, n) {
  const d = new Date(date)
  d.setDate(d.getDate() + n)
  return d
}

function formatDateRange(monday) {
  const sunday = addDays(monday, 6)
  const opts = { month: 'short', day: 'numeric' }
  const startStr = monday.toLocaleDateString('en-US', opts)
  const endStr   = sunday.toLocaleDateString('en-US', {
    month: sunday.getMonth() !== monday.getMonth() ? 'short' : undefined,
    day: 'numeric',
  })
  return `${startStr} – ${endStr}`
}

function toDateKey(date) {
  return date.toISOString().slice(0, 10)
}

function getMondayOfWeek(date) {
  const d = new Date(date)
  const day = d.getDay()
  d.setDate(d.getDate() + (day === 0 ? -6 : 1 - day))
  d.setHours(0, 0, 0, 0)
  return d
}

// Returns the two shifts that form the next/active test window.
// Window = Shift 3 of day D  →  Shift 1 of day D+1
function getNextTestWindow() {
  const now  = new Date()
  const hour = now.getHours()
  const tod  = new Date(now); tod.setHours(0, 0, 0, 0)

  // midnight–1AM: still inside shift 3 that started yesterday
  if (hour < 1) {
    return { shift3Date: toDateKey(addDays(tod, -1)), shift1Date: toDateKey(tod) }
  }
  // 1AM–5PM: shift 1 finished or in daytime gap — next window starts at 5PM today
  // 5PM–midnight: currently inside shift 3 of today
  // Both cases: upcoming/active window is shift 3 today + shift 1 tomorrow
  return { shift3Date: toDateKey(tod), shift1Date: toDateKey(addDays(tod, 1)) }
}

// scheduleData: { "YYYY-MM-DD": { shift1: [...], shift2: [...], shift3: [...] }, ... }
export default function Calendar({
  scheduleData = {},
  daytimeDateKey = null,
  weekStart,
  onWeekChange,
  dualDeviceWeekendWeekEnabled = false,
  onDualDeviceWeekendWeekEnabledChange,
  windowLookup = new Map(),
  onWindowSelect,
}) {
  const today = new Date()
  today.setHours(0, 0, 0, 0)

  const activeWindow = getNextTestWindow()

  const days = Array.from({ length: 7 }, (_, i) => addDays(weekStart, i))

  // Reorder columns: Sun Mon Tue Wed Thu Fri Sat
  // weekStart is Monday, so days[0]=Mon ... days[6]=Sun → put Sunday first
  const orderedDays = [ ...days.slice(0, 7)]
  const deviceLegendItems = Array.from(
    new Set(
      Object.values(scheduleData)
        .flatMap((day) => [
          ...(day?.shift1 ?? []),
          ...(day?.shift2 ?? []),
          ...(day?.shift3 ?? []),
        ])
        .map((test) => test?.device)
        .filter(Boolean),
    ),
  ).sort((a, b) => String(a).localeCompare(String(b)))

  return (
    <div className="flex flex-col gap-3 h-full">
      {/* Week navigation */}
      <div className="flex items-center gap-3">
        <button
          onClick={() => onWeekChange(addDays(weekStart, -7))}
          className="p-1 text-gray-400 hover:text-white hover:bg-gray-700 rounded transition-colors"
          title="Previous week"
        >
          <svg xmlns="http://www.w3.org/2000/svg" className="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
            <path strokeLinecap="round" strokeLinejoin="round" d="M15 19l-7-7 7-7" />
          </svg>
        </button>
        <span className="text-sm font-medium text-gray-300 min-w-36 text-center">
          {formatDateRange(weekStart)}
        </span>
        <button
          onClick={() => onWeekChange(addDays(weekStart, 7))}
          className="p-1 text-gray-400 hover:text-white hover:bg-gray-700 rounded transition-colors"
          title="Next week"
        >
          <svg xmlns="http://www.w3.org/2000/svg" className="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
            <path strokeLinecap="round" strokeLinejoin="round" d="M9 5l7 7-7 7" />
          </svg>
        </button>
                <button
          onClick={() => onWeekChange(getMondayOfWeek(new Date()))}
          className="px-2 py-1 text-xs font-semibold text-gray-300 border border-gray-600 rounded hover:bg-gray-700 hover:text-white transition-colors"
          title="Jump to this week"
        >
          Today
        </button>
        <div className="ml-auto flex items-center gap-2 text-xs text-gray-300 select-none">
          <span>Run both devices on weekend this week</span>
          <button
            type="button"
            role="switch"
            aria-checked={dualDeviceWeekendWeekEnabled}
            onClick={() => onDualDeviceWeekendWeekEnabledChange?.(!dualDeviceWeekendWeekEnabled)}
            className={`relative inline-flex h-5 w-9 shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors focus:outline-none focus:ring-2 focus:ring-blue-500/70 ${
              dualDeviceWeekendWeekEnabled ? 'bg-blue-600' : 'bg-gray-600'
            }`}
            title="Toggle dual-device weekend-start scheduling for this week"
          >
            <span
              className={`pointer-events-none inline-block h-4 w-4 rounded-full bg-white shadow transform transition-transform ${
                dualDeviceWeekendWeekEnabled ? 'translate-x-4' : 'translate-x-0'
              }`}
            />
          </button>
        </div>
      </div>

      {/* 7-day grid */}
      <div className="flex gap-1.5 flex-1 overflow-x-auto">
        {orderedDays.map((date) => {
          const key    = toDateKey(date)
          const shifts = scheduleData[key] ?? { shift1: [], shift2: [], shift3: [] }
          const isToday   = date.getTime() === today.getTime()
          const isWeekend  = date.getDay() === 0 || date.getDay() === 6
          // Which shifts on this date are part of the active test window?
          const activeShifts = new Set()
          if (key === activeWindow.shift3Date) activeShifts.add(3)
          if (key === activeWindow.shift1Date) activeShifts.add(1)
          return (
            <DayColumn
              key={key}
              date={date}
              isToday={isToday}
              activeShifts={activeShifts}
              shifts={shifts}
              showShift2={isWeekend || (daytimeDateKey !== null && key === daytimeDateKey)}
              windowLookup={windowLookup}
              onWindowSelect={onWindowSelect}
            />
          )
        })}
      </div>

      {/* Legend */}
      <div className="flex flex-wrap gap-x-6 gap-y-2 text-xs text-gray-400">
        <span className="flex items-center gap-1.5"><span className="w-2.5 h-2.5 rounded-sm bg-gray-500 inline-block" />Pending</span>
        <span className="flex items-center gap-1.5"><span className="w-2.5 h-2.5 rounded-sm bg-green-700 inline-block" />Completed</span>
        <span className="flex items-center gap-1.5"><span className="w-2.5 h-2.5 rounded-sm bg-red-700 inline-block" />Rerun Required</span>
        {deviceLegendItems.map((device) => (
          <span key={device} className="flex items-center gap-1.5">
            <span className={`w-2.5 h-2.5 rounded-sm inline-block ${getDeviceAccentClass(device)}`} />
            {device}
          </span>
        ))}
      </div>
    </div>
  )
}

