<script setup lang="ts">
import { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue'
import {
  calendarDiffYmd,
  totalHoursBetween,
  ymdInShanghai,
} from '../utils/togetherDuration'

export type TogetherMilestone = {
  title: string
  /** `YYYY-MM-DD` */
  date: string
}

const props = withDefaults(
  defineProps<{
    togetherSinceIso: string | null | undefined
    serverOffsetMs: number
    milestones?: TogetherMilestone[]
  }>(),
  { milestones: () => [] },
)

const tick = ref(0)
let tickTimer: ReturnType<typeof setInterval> | undefined

const slideIndex = ref(0)
let slideTimer: ReturnType<typeof setInterval> | undefined

function serverNowMs(): number {
  return Date.now() + props.serverOffsetMs
}

const parts = computed(() => {
  tick.value
  const raw = props.togetherSinceIso
  if (!raw) return null
  const startMs = Date.parse(raw)
  if (!Number.isFinite(startMs)) return null
  const endMs = serverNowMs()
  if (endMs < startMs) {
    return { years: 0, months: 0, days: 0, hoursTotal: 0 }
  }
  const startYmd = ymdInShanghai(startMs)
  const endYmd = ymdInShanghai(endMs)
  const { years, months, days } = calendarDiffYmd(startYmd, endYmd)
  const hoursTotal = totalHoursBetween(startMs, endMs, 1)
  return { years, months, days, hoursTotal }
})

const slideCount = computed(() => {
  let n = 0
  if (parts.value) n += 1
  n += props.milestones.length
  return n
})

function formatCnDate(dateStr: string): string {
  const m = /^(\d{4})-(\d{1,2})-(\d{1,2})$/.exec(dateStr.trim())
  if (!m) return dateStr
  return `${Number(m[1])}年${Number(m[2])}月${Number(m[3])}日`
}

function eventStartMs(dateStr: string): number {
  const m = /^(\d{4})-(\d{1,2})-(\d{1,2})$/.exec(dateStr.trim())
  if (!m) return NaN
  const y = m[1].padStart(4, '0')
  const mo = m[2].padStart(2, '0')
  const d = m[3].padStart(2, '0')
  return Date.parse(`${y}-${mo}-${d}T00:00:00+08:00`)
}

function milestoneMeta(m: TogetherMilestone) {
  const start = eventStartMs(m.date)
  if (!Number.isFinite(start)) {
    return { label: formatCnDate(m.date), rel: '' as string }
  }
  const now = serverNowMs()
  const dayMs = 86_400_000
  const diffDays = Math.floor((now - start) / dayMs)
  const rel =
    diffDays >= 0
      ? `自那天起已满 ${diffDays} 个自然日`
      : `还有 ${-diffDays} 个自然日`
  return { label: formatCnDate(m.date), rel }
}

type Slide = { kind: 'together' } | { kind: 'milestone'; index: number }

const currentSlide = computed((): Slide | null => {
  const n = slideCount.value
  if (n === 0) return null
  const i = slideIndex.value % n
  if (parts.value) {
    if (i === 0) return { kind: 'together' }
    return { kind: 'milestone', index: i - 1 }
  }
  return { kind: 'milestone', index: i }
})

const milestoneView = computed(() => {
  tick.value
  const s = currentSlide.value
  if (!s || s.kind !== 'milestone') return null
  const m = props.milestones[s.index]
  if (!m) return null
  const meta = milestoneMeta(m)
  return { title: m.title, label: meta.label, rel: meta.rel }
})

watch(slideCount, (n) => {
  if (n <= 0) {
    slideIndex.value = 0
    return
  }
  slideIndex.value %= n
})

onMounted(() => {
  tickTimer = setInterval(() => {
    tick.value += 1
  }, 30_000)
  slideTimer = setInterval(() => {
    const n = slideCount.value
    if (n <= 0) return
    slideIndex.value = (slideIndex.value + 1) % n
  }, 5_000)
})

onBeforeUnmount(() => {
  if (tickTimer) clearInterval(tickTimer)
  if (slideTimer) clearInterval(slideTimer)
})
</script>

<template>
  <div
    v-if="currentSlide"
    class="min-h-[4.25rem] text-sm tabular-nums text-ink-muted transition-opacity duration-300"
  >
    <template v-if="currentSlide.kind === 'together' && parts">
      <div class="space-y-1">
        <p>
          我们在一起
          <span class="font-medium text-lokta-deep">{{ parts.years }}</span>
          年
          <span class="font-medium text-lokta-deep">{{ parts.months }}</span>
          月
          <span class="font-medium text-lokta-deep">{{ parts.days }}</span>
          天
        </p>
        <p>
          相当于约
          <span class="font-medium text-lokta-deep">{{ parts.hoursTotal }}</span>
          小时
        </p>
      </div>
    </template>
    <template v-else-if="milestoneView">
      <div class="space-y-1">
        <p class="font-medium text-lokta-deep">
          {{ milestoneView.title }}
        </p>
        <p>{{ milestoneView.label }}</p>
        <p v-if="milestoneView.rel" class="text-xs">
          {{ milestoneView.rel }}
        </p>
      </div>
    </template>
  </div>
  <p v-else class="min-h-[4.25rem] text-xs text-ink-muted">
    请在后台配置「在一起」的起始时间，或载入手帐章节以展示纪念日期。
  </p>
</template>
