<script setup lang="ts" generic="S extends TimeSpanLabel">
import { computed } from 'vue';
import { spanToDays, type TimeSpanLabel } from '@/types/spans';
import { daysVisibleRange, shiftLocalDays, shiftLocalMonths } from '@/utils/date';

const props = defineProps<{
  mode: 'days' | 'month';
  currentDate: Date;
  spans?: readonly S[];
  selectedSpan?: S;
}>();

const emit = defineEmits<{
  'update:current-date': [date: Date];
  'update:span': [span: S];
}>();

const spanDays = computed(() => props.selectedSpan ? spanToDays(props.selectedSpan) : 1);

function previousPeriod() {
  emit('update:current-date', props.mode === 'month'
    ? shiftLocalMonths(props.currentDate, -1)
    : shiftLocalDays(props.currentDate, -spanDays.value));
}

function nextPeriod() {
  emit('update:current-date', props.mode === 'month'
    ? shiftLocalMonths(props.currentDate, 1)
    : shiftLocalDays(props.currentDate, spanDays.value));
}

function goToToday() {
  emit('update:current-date', new Date());
}

const periodLabel = computed(() => {
  if (props.mode === 'month') {
    return props.currentDate.toLocaleDateString('en-US', { month: 'long', year: 'numeric' });
  }

  const range = daysVisibleRange(props.currentDate, spanDays.value);
  const start = new Date(range.start);
  const end = shiftLocalDays(new Date(range.end), -1);
  const formatOptions: Intl.DateTimeFormatOptions = { month: 'short', day: 'numeric' };

  if (spanDays.value === 1) {
    return start.toLocaleDateString('en-US', { month: 'long', day: 'numeric', year: 'numeric' });
  }

  if (start.getMonth() === end.getMonth()) {
    return `${start.toLocaleDateString('en-US', formatOptions)} - ${end.getDate()}, ${start.getFullYear()}`;
  }

  return `${start.toLocaleDateString('en-US', formatOptions)} - ${end.toLocaleDateString('en-US', formatOptions)}, ${end.getFullYear()}`;
});
</script>

<template>
  <div class="view-controls">
    <div class="view-navigation">
      <v-btn size="x-small" variant="text" icon="mdi-chevron-left" @click="previousPeriod" />
      <v-btn size="x-small" variant="tonal" @click="goToToday">Today</v-btn>
      <v-btn size="x-small" variant="text" icon="mdi-chevron-right" @click="nextPeriod" />
      <span class="current-period">{{ periodLabel }}</span>
    </div>
    <v-spacer />
    <div v-if="spans?.length" class="view-selector">
      <v-btn
        v-for="span in spans"
        :key="span"
        size="x-small"
        variant="text"
        :color="selectedSpan === span ? 'primary' : undefined"
        @click="emit('update:span', span)"
      >
        {{ span.toUpperCase() }}
      </v-btn>
    </div>
  </div>
</template>

<style scoped>
.view-controls {
  display: flex;
  align-items: center;
  padding: 4px 8px;
  border-bottom: 1px solid rgb(var(--v-border-color));
  background-color: rgb(var(--v-theme-surface));
  flex-shrink: 0;
}

.view-navigation {
  display: flex;
  align-items: center;
  gap: 4px;
}

.current-period {
  font-size: 14px;
  font-weight: 500;
  margin-left: 8px;
  white-space: nowrap;
}

.view-selector {
  display: flex;
  align-items: center;
  gap: 2px;
}
</style>
