<template>
  <IonPage>
    <IonHeader>
      <IonToolbar color="primary">
        <IonButtons slot="start">
          <IonMenuButton />
        </IonButtons>
        <IonTitle>Manage Slots</IonTitle>
        <IonButtons slot="end">
          <IonButton @click="showWeekApply = true">
            <IonIcon slot="icon-only" :icon="calendarOutline" />
          </IonButton>
          <IonButton @click="showAddSlot = true">
            <IonIcon slot="icon-only" :icon="addOutline" />
          </IonButton>
        </IonButtons>
      </IonToolbar>
    </IonHeader>

    <IonContent class="ion-padding">
      <!-- Date selector -->
      <h3 class="section-title">Date</h3>
      <div class="date-strip">
        <button
          v-for="d in dateOptions"
          :key="d.iso"
          class="date-chip"
          :class="{ active: selectedDate === d.iso }"
          @click="selectedDate = d.iso"
        >
          <span class="day-name">{{ d.dayName }}</span>
          <span class="day-num">{{ d.dayNum }}</span>
          <span class="month">{{ d.month }}</span>
        </button>
      </div>

      <div v-if="loading" class="ion-text-center ion-padding">
        <IonSpinner name="crescent" />
      </div>

      <template v-else>
        <IonCard v-for="boat in boats" :key="boat.id" class="boat-card">
          <IonCardHeader>
            <div class="boat-header">
              <div>
                <IonCardTitle>{{ boat.display_name || boat.name }}</IonCardTitle>
                <IonCardSubtitle v-if="boat.class">{{ boat.class }}</IonCardSubtitle>
              </div>
              <IonToggle
                :checked="boat.booking_available"
                :enable-on-off-labels="true"
                color="success"
                @ion-change="toggleBoatAvailability(boat, $event.detail.checked)"
              />
            </div>
          </IonCardHeader>
          <IonCardContent>
            <p v-if="!boat.booking_available" class="out-of-service">
              <IonIcon :icon="constructOutline" /> Out of service
            </p>
            <div class="apply-template-row">
              <IonSelect
                placeholder="Apply template..."
                interface="action-sheet"
                @ion-change="applyTemplate(boat.id, $event.detail.value)"
              >
                <IonSelectOption v-for="t in templates" :key="t.id" :value="t.id">
                  {{ t.name }}
                </IonSelectOption>
              </IonSelect>
            </div>

            <p v-if="slotsByBoat[boat.id]?.length === 0" class="empty-text">No slots for this date.</p>
            <IonList v-else lines="full">
              <IonItem v-for="slot in slotsByBoat[boat.id]" :key="slot.id">
                <IonIcon slot="start" :icon="timeOutline" />
                <IonLabel>{{ formatTime(slot.start_time) }} – {{ formatTime(slot.end_time) }}</IonLabel>
                <IonButton
                  slot="end"
                  fill="clear"
                  color="danger"
                  @click="deleteSlot(slot.id)"
                >
                  <IonIcon slot="icon-only" :icon="trashOutline" />
                </IonButton>
              </IonItem>
            </IonList>
          </IonCardContent>
        </IonCard>
      </template>

      <!-- Add slot modal -->
      <IonModal :is-open="showAddSlot" @did-dismiss="showAddSlot = false">
        <IonHeader>
          <IonToolbar>
            <IonTitle>Add Slot</IonTitle>
            <IonButtons slot="end">
              <IonButton @click="showAddSlot = false">Cancel</IonButton>
            </IonButtons>
          </IonToolbar>
        </IonHeader>
        <IonContent class="ion-padding">
          <IonList lines="full">
            <IonItem>
              <IonLabel position="stacked">Boat</IonLabel>
              <IonSelect v-model="newSlot.boatId" placeholder="Select boat" interface="action-sheet">
                <IonSelectOption v-for="b in boats" :key="b.id" :value="b.id">
                  {{ b.display_name || b.name }}
                </IonSelectOption>
              </IonSelect>
            </IonItem>
            <IonItem>
              <IonLabel position="stacked">Start Time</IonLabel>
              <IonInput v-model="newSlot.startTime" type="time" />
            </IonItem>
            <IonItem>
              <IonLabel position="stacked">End Time</IonLabel>
              <IonInput v-model="newSlot.endTime" type="time" />
            </IonItem>
          </IonList>
          <IonButton
            expand="block"
            class="ion-margin-top"
            :disabled="!newSlot.boatId || !newSlot.startTime || !newSlot.endTime || addingSlot"
            @click="addSlot"
          >
            <IonSpinner v-if="addingSlot" name="crescent" slot="start" />
            Add Slot
          </IonButton>
        </IonContent>
      </IonModal>

      <!-- Apply to Week modal -->
      <IonModal :is-open="showWeekApply" @did-dismiss="showWeekApply = false">
        <IonHeader>
          <IonToolbar>
            <IonTitle>Apply Template to Week</IonTitle>
            <IonButtons slot="end">
              <IonButton @click="showWeekApply = false">Cancel</IonButton>
            </IonButtons>
          </IonToolbar>
        </IonHeader>
        <IonContent class="ion-padding">
          <IonList lines="full">
            <IonItem>
              <IonLabel position="stacked">Template</IonLabel>
              <IonSelect v-model="weekApply.templateId" placeholder="Select template" interface="action-sheet">
                <IonSelectOption v-for="t in templates" :key="t.id" :value="t.id">{{ t.name }}</IonSelectOption>
              </IonSelect>
            </IonItem>
            <IonItem>
              <IonLabel position="stacked">Boat</IonLabel>
              <IonSelect v-model="weekApply.boatId" placeholder="Select boat" interface="action-sheet">
                <IonSelectOption v-for="b in boats" :key="b.id" :value="b.id">{{ b.display_name || b.name }}</IonSelectOption>
              </IonSelect>
            </IonItem>
          </IonList>

          <h4 class="section-title ion-margin-top">Days to apply</h4>
          <IonList lines="none">
            <IonItem v-for="(day, i) in weekDays" :key="day.iso">
              <IonCheckbox v-model="weekApply.days[i]" slot="start" />
              <IonLabel>{{ day.label }}</IonLabel>
            </IonItem>
          </IonList>

          <IonButton
            expand="block"
            class="ion-margin-top"
            :disabled="!weekApply.templateId || !weekApply.boatId || !weekApply.days.some(Boolean) || weekApply.applying"
            @click="applyTemplateToWeek"
          >
            <IonSpinner v-if="weekApply.applying" name="crescent" slot="start" />
            Apply to Selected Days
          </IonButton>
        </IonContent>
      </IonModal>

      <IonToast
        v-model:is-open="toast.show"
        :message="toast.message"
        :color="toast.color"
        :duration="2500"
        position="bottom"
      />
    </IonContent>
  </IonPage>
</template>

<script setup lang="ts">
import {
  IonPage, IonHeader, IonToolbar, IonTitle, IonContent, IonButtons,
  IonMenuButton, IonButton, IonIcon, IonCard, IonCardHeader, IonCardTitle,
  IonCardSubtitle, IonCardContent, IonList, IonItem, IonLabel, IonToggle,
  IonSelect, IonSelectOption, IonSpinner, IonModal, IonInput, IonToast, IonCheckbox,
  onIonViewWillEnter,
} from '@ionic/vue'
import {
  addOutline, timeOutline, trashOutline, constructOutline, calendarOutline,
} from 'ionicons/icons'
import type { Database, TimeTuple } from '~/types/supabase'

type Boat = Database['public']['Tables']['boats']['Row']
type Interval = Database['public']['Tables']['intervals']['Row']
type Template = Database['public']['Tables']['interval_templates']['Row']

definePageMeta({ layout: false, middleware: ['auth'] })

// eslint-disable-next-line @typescript-eslint/no-explicit-any
const supabase = useSupabaseClient() as any

const loading = ref(false)
const addingSlot = ref(false)
const showAddSlot = ref(false)
const showWeekApply = ref(false)
const weekApply = reactive({ templateId: '', boatId: '', applying: false, days: [] as boolean[] })

watch(showWeekApply, (open) => {
  if (open) weekApply.days = Array(7).fill(true)
})
const weekDays = computed(() => {
  const base = new Date(selectedDate.value + 'T12:00:00')
  const dow = base.getDay() // 0=Sun
  const monday = new Date(base)
  monday.setDate(base.getDate() - ((dow + 6) % 7))
  return Array.from({ length: 7 }, (_, i) => {
    const d = new Date(monday)
    d.setDate(monday.getDate() + i)
    return { iso: d.toISOString().slice(0, 10), label: d.toLocaleDateString('en-CA', { weekday: 'short', month: 'short', day: 'numeric' }) }
  })
})
const selectedDate = ref(todayIso())
const boats = ref<Boat[]>([])
const templates = ref<Template[]>([])
const slotsByBoat = ref<Record<string, Interval[]>>({})
const toast = reactive({ show: false, message: '', color: 'success' })

const newSlot = reactive({ boatId: '', startTime: '08:00', endTime: '12:00' })

const dateOptions = computed(() => {
  const out = []
  const base = new Date()
  for (let i = 0; i < 14; i++) {
    const d = new Date(base)
    d.setDate(base.getDate() + i)
    out.push({
      iso: toIso(d),
      dayName: d.toLocaleDateString('en-CA', { weekday: 'short' }),
      dayNum: d.getDate(),
      month: d.toLocaleDateString('en-CA', { month: 'short' }),
    })
  }
  return out
})

async function loadAll() {
  await Promise.all([fetchBoats(), fetchTemplates()])
  await fetchSlots()
}

const user = useSupabaseUser()
watch(user, (val) => { if (val) loadAll() }, { immediate: true })
onIonViewWillEnter(() => { if (user.value) loadAll() })

watch(selectedDate, () => { if (user.value) fetchSlots() })

async function fetchBoats() {
  const { data } = await supabase.from('boats').select('*').order('name')
  boats.value = data ?? []
}

async function fetchTemplates() {
  const { data } = await supabase.from('interval_templates').select('*').order('name')
  templates.value = data ?? []
}

async function fetchSlots() {
  loading.value = true
  const dayStart = selectedDate.value + 'T00:00:00Z'
  const dayEnd = selectedDate.value + 'T23:59:59Z'

  const { data } = await supabase
    .from('intervals')
    .select('*')
    .gte('start_time', dayStart)
    .lte('start_time', dayEnd)
    .order('start_time', { ascending: true })

  const grouped: Record<string, Interval[]> = {}
  for (const boat of boats.value) grouped[boat.id] = []
  for (const slot of (data ?? []) as Interval[]) {
    if (!grouped[slot.boat_id]) grouped[slot.boat_id] = []
    grouped[slot.boat_id]!.push(slot)
  }
  slotsByBoat.value = grouped
  loading.value = false
}

async function addSlot() {
  addingSlot.value = true
  const start = new Date(`${selectedDate.value}T${newSlot.startTime}:00`)
  const end = new Date(`${selectedDate.value}T${newSlot.endTime}:00`)

  const { error } = await supabase.from('intervals').insert({
    boat_id: newSlot.boatId,
    start_time: start.toISOString(),
    end_time: end.toISOString(),
  })

  addingSlot.value = false
  if (error) {
    showToast('Failed to add slot: ' + error.message, 'danger')
    return
  }
  showAddSlot.value = false
  newSlot.boatId = ''
  await fetchSlots()
  showToast('Slot added', 'success')
}

async function deleteSlot(id: string) {
  const { error } = await supabase.from('intervals').delete().eq('id', id)
  if (error) { showToast('Failed to delete: ' + error.message, 'danger'); return }
  await fetchSlots()
  showToast('Slot removed', 'success')
}

async function toggleBoatAvailability(boat: Boat, available: boolean) {
  const { error } = await supabase
    .from('boats')
    .update({ booking_available: available })
    .eq('id', boat.id)
  if (error) { showToast('Update failed: ' + error.message, 'danger'); return }
  boat.booking_available = available
  showToast(available ? 'Boat back in service' : 'Boat out of service', available ? 'success' : 'warning')
}

async function applyTemplate(boatId: string, templateId: string) {
  const template = templates.value.find(t => t.id === templateId)
  if (!template) return

  const inserts = (template.time_tuples as TimeTuple[]).map(([start, end]) => ({
    boat_id: boatId,
    start_time: new Date(`${selectedDate.value}T${start}:00`).toISOString(),
    end_time: new Date(`${selectedDate.value}T${end}:00`).toISOString(),
  }))

  const { error } = await supabase.from('intervals').insert(inserts)
  if (error) { showToast('Failed to apply template: ' + error.message, 'danger'); return }
  await fetchSlots()
  showToast(`Template "${template.name}" applied`, 'success')
}

async function applyTemplateToWeek() {
  const template = templates.value.find(t => t.id === weekApply.templateId)
  if (!template) return
  weekApply.applying = true

  const selectedDays = weekDays.value.filter((_, i) => weekApply.days[i])
  const inserts = selectedDays.flatMap(day =>
    (template.time_tuples as TimeTuple[]).map(([start, end]) => ({
      boat_id: weekApply.boatId,
      start_time: new Date(`${day.iso}T${start}:00`).toISOString(),
      end_time: new Date(`${day.iso}T${end}:00`).toISOString(),
    }))
  )

  const { error } = await supabase.from('intervals').insert(inserts)
  weekApply.applying = false
  if (error) { showToast('Failed to apply: ' + error.message, 'danger'); return }
  showWeekApply.value = false
  await fetchSlots()
  showToast(`Template applied to ${selectedDays.length} day(s)`, 'success')
}

function showToast(message: string, color: string) {
  toast.message = message
  toast.color = color
  toast.show = true
}

function todayIso() { return toIso(new Date()) }
function toIso(d: Date) { return d.toISOString().slice(0, 10) }
function formatTime(iso: string) {
  return new Date(iso).toLocaleTimeString('en-CA', { hour: '2-digit', minute: '2-digit', hour12: false })
}
</script>

<style scoped>
.section-title { font-size: 1rem; font-weight: 600; margin: 0 0 0.5rem; }

.date-strip {
  display: flex;
  gap: 0.5rem;
  overflow-x: auto;
  padding-bottom: 0.5rem;
  scrollbar-width: none;
  margin-bottom: 1rem;
}
.date-strip::-webkit-scrollbar { display: none; }

.date-chip {
  display: flex;
  flex-direction: column;
  align-items: center;
  min-width: 52px;
  padding: 0.4rem 0.6rem;
  border: 1px solid var(--ion-color-light-shade);
  border-radius: 0.5rem;
  background: var(--ion-color-light);
  cursor: pointer;
  font-size: 0.75rem;
  gap: 2px;
  flex-shrink: 0;
}
.date-chip.active {
  background: var(--ion-color-primary);
  color: white;
  border-color: var(--ion-color-primary);
}
.day-name { font-weight: 600; text-transform: uppercase; font-size: 0.65rem; }
.day-num { font-size: 1.1rem; font-weight: 700; }
.month { font-size: 0.65rem; }

.boat-card { margin: 0 0 1rem; }
.boat-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
}

.out-of-service {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  color: var(--ion-color-danger);
  font-size: 0.85rem;
  margin-bottom: 0.5rem;
}

.apply-template-row { margin-bottom: 0.75rem; }

.empty-text { color: var(--ion-color-medium); font-size: 0.9rem; }
</style>
