import { ref, computed, watch } from 'vue'
import { localDateStr, startOfWeek, startOfMonth } from 'src/composables/useHelpers'

// Buffer: 1 period before, 2 after — biased toward the future for natural right-scroll
const BUFFER_BEFORE = 1
const BUFFER_AFTER  = 2

export function usePeriodNavigation () {
  const currentView = ref(localStorage.getItem('sbv2-view') || 'week')
  const savedDate = localStorage.getItem('sbv2-date')
  let initDate = new Date()
  if (savedDate && /^\d{4}-\d{2}-\d{2}$/.test(savedDate)) {
    const d = new Date(savedDate + 'T00:00:00')
    if (!isNaN(d.getTime())) initDate = d
  }
  const anchorDate = ref(initDate)

  watch(currentView, v => localStorage.setItem('sbv2-view', v))
  watch(anchorDate, d => localStorage.setItem('sbv2-date', localDateStr(d)))

  const periodStart = computed(() => {
    const d = new Date(anchorDate.value); d.setHours(0,0,0,0)
    if (currentView.value === 'day')   return d
    if (currentView.value === 'week')  return startOfWeek(d)
    return startOfMonth(d)
  })

  // The "core" period length (what the label describes)
  const periodDays = computed(() => {
    if (currentView.value === 'day')  return 1
    if (currentView.value === 'week') return 7
    const s = periodStart.value
    return new Date(s.getFullYear(), s.getMonth()+1, 0).getDate()
  })

  // Buffer: extra periods before/after for seamless scroll (week only, not day)
  const bufferDaysBefore = computed(() => {
    if (currentView.value !== 'week') return 0
    return periodDays.value * BUFFER_BEFORE
  })

  const renderedDays = computed(() => {
    if (currentView.value !== 'week') return periodDays.value
    return periodDays.value * (1 + BUFFER_BEFORE + BUFFER_AFTER)
  })

  // The start date of all rendered columns (buffer included)
  const renderedStart = computed(() => {
    const ps = periodStart.value
    if (!ps || isNaN(ps.getTime())) return new Date()
    const d = new Date(ps)
    d.setDate(d.getDate() - bufferDaysBefore.value)
    return d
  })

  // dayColumns spans the full rendered range (prev + current + next)
  const dayColumns = computed(() => {
    const cols = []
    const base = renderedStart.value
    if (!base || isNaN(base.getTime())) return cols
    for (let i = 0; i < renderedDays.value; i++) {
      const d = new Date(base); d.setDate(d.getDate() + i); cols.push(d)
    }
    return cols
  })

  function safeFmt (d, opts) {
    try { return d.toLocaleDateString('fr-CA', opts) } catch { return localDateStr(d) }
  }
  const periodLabel = computed(() => {
    const s = periodStart.value
    if (!s || isNaN(s.getTime())) return '—'
    if (currentView.value === 'day')
      return safeFmt(s, { weekday:'long', day:'numeric', month:'long', year:'numeric' })
    if (currentView.value === 'week') {
      const e = new Date(s); e.setDate(e.getDate() + 6)
      return `${safeFmt(s,{day:'numeric',month:'short'})} – ${safeFmt(e,{day:'numeric',month:'short',year:'numeric'})}`
    }
    return safeFmt(s, { month:'long', year:'numeric' })
  })
  const todayStr = localDateStr(new Date())

  function prevPeriod () {
    const d = new Date(anchorDate.value)
    if (currentView.value === 'day')   d.setDate(d.getDate()-1)
    if (currentView.value === 'week')  d.setDate(d.getDate()-7)
    if (currentView.value === 'month') d.setMonth(d.getMonth()-1)
    anchorDate.value = d
  }
  function nextPeriod () {
    const d = new Date(anchorDate.value)
    if (currentView.value === 'day')   d.setDate(d.getDate()+1)
    if (currentView.value === 'week')  d.setDate(d.getDate()+7)
    if (currentView.value === 'month') d.setMonth(d.getMonth()+1)
    anchorDate.value = d
  }
  function goToToday () { anchorDate.value = new Date(); currentView.value = 'day' }
  function goToDay (d) { anchorDate.value = new Date(d); currentView.value = 'day' }

  return {
    currentView, anchorDate, periodStart, periodDays, dayColumns, periodLabel, todayStr,
    bufferDaysBefore, renderedDays,
    prevPeriod, nextPeriod, goToToday, goToDay,
  }
}
