<template>
  <div ref="rootEl" class="time-picker-popover">
    <button type="button" class="time-display" @click="toggleOpen" :class="{ open: isOpen }">
      {{ formattedTime }}
    </button>

    <div v-if="isOpen" class="popover-panel">
      <div class="columns">
        <!-- Hours column -->
        <div class="col">
          <div class="col-header">Hour</div>
          <div class="col-scroll">
            <button
              v-for="h in HOURS"
              :key="h"
              type="button"
              class="col-item"
              :class="{ selected: displayHour === h }"
              @click="selectHour(h)"
            >
              {{ h }}
            </button>
          </div>
        </div>

        <div class="col-divider">:</div>

        <!-- Minutes column -->
        <div class="col">
          <div class="col-header">Min</div>
          <div class="col-scroll">
            <button
              v-for="m in MINUTES"
              :key="m"
              type="button"
              class="col-item"
              :class="{ selected: props.modelValue.minute === m }"
              @click="selectMinute(m)"
            >
              {{ String(m).padStart(2, '0') }}
            </button>
          </div>
        </div>

        <!-- AM/PM column -->
        <div class="col ampm-col">
          <div class="col-header">AM/PM</div>
          <div class="col-scroll">
            <button
              type="button"
              class="col-item"
              :class="{ selected: period === 'AM' }"
              @click="selectPeriod('AM')"
            >
              AM
            </button>
            <button
              type="button"
              class="col-item"
              :class="{ selected: period === 'PM' }"
              @click="selectPeriod('PM')"
            >
              PM
            </button>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onUnmounted } from 'vue'

interface TimeValue {
  hour: number // 0–23
  minute: number // 0, 15, 30, 45
}

const props = defineProps<{ modelValue: TimeValue }>()
const emit = defineEmits<{ (e: 'update:modelValue', val: TimeValue): void }>()

const HOURS = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
const MINUTES = [0, 15, 30, 45]

const rootEl = ref<HTMLElement | null>(null)
const isOpen = ref(false)

const period = computed(() => (props.modelValue.hour < 12 ? 'AM' : 'PM'))

const displayHour = computed(() => {
  const h = props.modelValue.hour % 12
  return h === 0 ? 12 : h
})

const formattedTime = computed(() => {
  const h = displayHour.value
  const m = String(props.modelValue.minute).padStart(2, '0')
  return `${String(h).padStart(2, '0')}:${m} ${period.value}`
})

function toggleOpen() {
  if (isOpen.value) {
    close()
  } else {
    isOpen.value = true
    document.addEventListener('mousedown', onDocumentMouseDown, { capture: true })
  }
}

function close() {
  isOpen.value = false
  document.removeEventListener('mousedown', onDocumentMouseDown, { capture: true })
}

function onDocumentMouseDown(e: MouseEvent) {
  if (rootEl.value && !rootEl.value.contains(e.target as Node)) {
    close()
  }
}

function selectHour(h: number) {
  // h is 1–12 display; convert to 0–23 preserving period
  const isPm = period.value === 'PM'
  let hour24: number
  if (h === 12) {
    hour24 = isPm ? 12 : 0
  } else {
    hour24 = isPm ? h + 12 : h
  }
  emit('update:modelValue', { hour: hour24, minute: props.modelValue.minute })
}

function selectMinute(m: number) {
  emit('update:modelValue', { hour: props.modelValue.hour, minute: m })
}

function selectPeriod(p: 'AM' | 'PM') {
  const currentPeriod = period.value
  if (p === currentPeriod) return
  const newHour = p === 'PM' ? props.modelValue.hour + 12 : props.modelValue.hour - 12
  emit('update:modelValue', { hour: newHour, minute: props.modelValue.minute })
}

onUnmounted(() => {
  document.removeEventListener('mousedown', onDocumentMouseDown, { capture: true })
})
</script>

<style scoped>
.time-picker-popover {
  position: relative;
  display: inline-block;
}

.time-display {
  display: inline-flex;
  align-items: center;
  padding: 0.35rem 0.75rem;
  border: 1.5px solid var(--kebab-menu-border, #bcc1c9);
  border-radius: 8px;
  background: var(--modal-bg, #fff);
  color: var(--secondary, #7257b3);
  font-size: 0.95rem;
  font-weight: 700;
  cursor: pointer;
  transition:
    border-color 0.15s,
    box-shadow 0.15s;
  white-space: nowrap;
  font-family: inherit;
}

.time-display:hover,
.time-display.open {
  border-color: var(--btn-primary, #667eea);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--btn-primary, #667eea) 20%, transparent);
}

.popover-panel {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  z-index: 200;
  background: var(--modal-bg, #fff);
  border: 1.5px solid var(--kebab-menu-border, #bcc1c9);
  border-radius: 10px;
  box-shadow: 0 4px 18px var(--modal-shadow, rgba(0, 0, 0, 0.15));
  padding: 0.5rem;
}

.columns {
  display: flex;
  align-items: flex-start;
  gap: 0.25rem;
}

.col {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  min-width: 3rem;
}

.ampm-col {
  min-width: 3.2rem;
}

.col-header {
  font-size: 0.7rem;
  font-weight: 700;
  text-align: center;
  color: var(--primary, #667eea);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin-bottom: 0.35rem;
  padding: 0 0.15rem;
}

.col-scroll {
  display: flex;
  flex-direction: column;
  gap: 0.18rem;
  max-height: 12rem;
  overflow-y: auto;
  scrollbar-width: thin;
}

.col-item {
  padding: 0.3rem 0.4rem;
  border: none;
  border-radius: 6px;
  background: transparent;
  color: var(--secondary, #7257b3);
  font-size: 0.9rem;
  font-weight: 600;
  text-align: center;
  cursor: pointer;
  transition:
    background 0.12s,
    color 0.12s;
  font-family: inherit;
}

.col-item:hover {
  background: var(--menu-item-hover-bg, rgba(102, 126, 234, 0.1));
}

.col-item.selected {
  background: var(--btn-primary, #667eea);
  color: #fff;
}

.col-divider {
  font-size: 1.1rem;
  font-weight: 700;
  color: var(--secondary, #7257b3);
  padding-top: 1.6rem;
  align-self: flex-start;
}
</style>
