<template>
  <IonPage>
    <IonHeader>
      <IonToolbar color="primary">
        <IonButtons slot="start">
          <IonMenuButton />
        </IonButtons>
        <IonTitle>Manage Bookings</IonTitle>
        <IonButtons slot="end">
          <IonButton @click="openCreate">
            <IonIcon slot="icon-only" :icon="addOutline" />
          </IonButton>
        </IonButtons>
      </IonToolbar>
    </IonHeader>

    <IonContent class="ion-padding">
      <!-- Filters -->
      <div class="filter-row">
        <IonSelect
          v-model="filterBoatId"
          placeholder="All boats"
          interface="action-sheet"
          class="boat-filter"
        >
          <IonSelectOption value="">All boats</IonSelectOption>
          <IonSelectOption v-for="b in boats" :key="b.id" :value="b.id">
            {{ b.display_name || b.name }}
          </IonSelectOption>
        </IonSelect>
        <IonInput v-model="filterDateFrom" type="date" class="date-filter" />
        <IonInput v-model="filterDateTo" type="date" class="date-filter" />
      </div>

      <div v-if="loading" class="ion-text-center ion-padding">
        <IonSpinner name="crescent" />
      </div>
      <p v-else-if="filteredReservations.length === 0" class="empty-text">No bookings found.</p>

      <IonCard v-else v-for="r in filteredReservations" :key="r.id" class="res-card">
        <IonCardContent>
          <div class="res-header">
            <div class="res-main">
              <div class="res-boat">{{ boatName(r.boat_id) }}</div>
              <div class="res-member">{{ authStore.getUserNameById(r.user_id) }}</div>
              <div class="res-time">
                {{ formatDate(r.start_time) }}
                {{ formatTime(r.start_time) }}–{{ formatTime(r.end_time) }}
              </div>
              <div v-if="r.reason" class="res-reason">{{ r.reason }}</div>
            </div>
            <div class="res-right">
              <IonBadge :color="statusColor(r.status)" class="status-badge">{{ r.status }}</IonBadge>
              <div class="res-actions">
                <IonButton fill="clear" @click="openEdit(r)">
                  <IonIcon slot="icon-only" :icon="pencilOutline" />
                </IonButton>
                <IonButton fill="clear" color="danger" @click="confirmDelete(r)">
                  <IonIcon slot="icon-only" :icon="trashOutline" />
                </IonButton>
              </div>
            </div>
          </div>
        </IonCardContent>
      </IonCard>

      <!-- Create / Edit modal -->
      <IonModal :is-open="showModal" @did-dismiss="closeModal">
        <IonHeader>
          <IonToolbar>
            <IonTitle>{{ editing ? 'Edit Booking' : 'New Booking' }}</IonTitle>
            <IonButtons slot="end">
              <IonButton @click="closeModal">Cancel</IonButton>
            </IonButtons>
          </IonToolbar>
        </IonHeader>
        <IonContent class="ion-padding">
          <IonList lines="full">
            <IonItem>
              <IonLabel position="stacked">Boat <span class="required">*</span></IonLabel>
              <IonSelect v-model="form.boat_id" 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">Member <span class="required">*</span></IonLabel>
              <IonSelect v-model="form.user_id" placeholder="Select member" interface="action-sheet">
                <IonSelectOption v-for="m in members" :key="m.user_id" :value="m.user_id">
                  {{ m.first_name }} {{ m.last_name }} ({{ m.email }})
                </IonSelectOption>
              </IonSelect>
            </IonItem>
            <IonItem>
              <IonLabel position="stacked">Date <span class="required">*</span></IonLabel>
              <IonInput v-model="form.date" type="date" />
            </IonItem>
            <IonItem>
              <IonLabel position="stacked">Start Time <span class="required">*</span></IonLabel>
              <IonInput v-model="form.startTime" type="time" />
            </IonItem>
            <IonItem>
              <IonLabel position="stacked">End Time <span class="required">*</span></IonLabel>
              <IonInput v-model="form.endTime" type="time" />
            </IonItem>
            <IonItem>
              <IonLabel position="stacked">Status</IonLabel>
              <IonSelect v-model="form.status" interface="action-sheet">
                <IonSelectOption value="pending">Pending</IonSelectOption>
                <IonSelectOption value="tentative">Tentative</IonSelectOption>
                <IonSelectOption value="confirmed">Confirmed</IonSelectOption>
              </IonSelect>
            </IonItem>
            <IonItem>
              <IonLabel position="stacked">Reason</IonLabel>
              <IonInput v-model="form.reason" placeholder="e.g. Day sail" />
            </IonItem>
            <IonItem>
              <IonLabel position="stacked">Comment</IonLabel>
              <IonTextarea v-model="form.comment" :rows="2" placeholder="Optional admin note" />
            </IonItem>
          </IonList>

          <IonButton
            expand="block"
            class="ion-margin-top"
            :disabled="!formValid || saving"
            @click="saveReservation"
          >
            <IonSpinner v-if="saving" name="crescent" slot="start" />
            {{ saving ? 'Saving…' : 'Save Booking' }}
          </IonButton>
        </IonContent>
      </IonModal>

      <IonAlert
        :is-open="deleteAlert.show"
        header="Delete Booking"
        message="Delete this booking? This cannot be undone."
        :buttons="[
          { text: 'Cancel', role: 'cancel', handler: () => { deleteAlert.show = false } },
          { text: 'Delete', role: 'destructive', handler: deleteReservation },
        ]"
        @did-dismiss="deleteAlert.show = false"
      />

      <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, IonCardContent, IonBadge,
  IonList, IonItem, IonLabel, IonInput, IonTextarea, IonSelect, IonSelectOption,
  IonSpinner, IonModal, IonAlert, IonToast,
} from '@ionic/vue'
import { addOutline, pencilOutline, trashOutline } from 'ionicons/icons'
import type { Database } from '~/types/supabase'
import { useAuthStore } from '~/stores/auth'

type Boat = Database['public']['Tables']['boats']['Row']
type Reservation = Database['public']['Tables']['reservations']['Row']
type Member = Database['public']['Tables']['members']['Row']

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

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

const loading = ref(true)
const saving = ref(false)
const showModal = ref(false)
const editing = ref<Reservation | null>(null)
const reservations = ref<Reservation[]>([])
const boats = ref<Boat[]>([])
const members = ref<Member[]>([])
const toast = reactive({ show: false, message: '', color: 'success' })
const deleteAlert = reactive({ show: false, id: '' })

// Filters — default to current week ± 4 weeks
const today = new Date()
const filterDateFrom = ref(toIso(new Date(today.getFullYear(), today.getMonth(), today.getDate() - 14)))
const filterDateTo = ref(toIso(new Date(today.getFullYear(), today.getMonth(), today.getDate() + 28)))
const filterBoatId = ref('')

const form = reactive({
  boat_id: '',
  user_id: '',
  date: toIso(today),
  startTime: '09:00',
  endTime: '13:00',
  status: 'confirmed' as 'pending' | 'tentative' | 'confirmed',
  reason: '',
  comment: '',
})

const formValid = computed(() =>
  !!form.boat_id && !!form.user_id && !!form.date && !!form.startTime && !!form.endTime
)

const filteredReservations = computed(() => {
  return reservations.value.filter(r => {
    if (filterBoatId.value && r.boat_id !== filterBoatId.value) return false
    return true
  })
})

onMounted(async () => {
  await Promise.all([fetchBoats(), fetchMembers()])
  await fetchReservations()
})

watch([filterDateFrom, filterDateTo], fetchReservations)

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

async function fetchMembers() {
  const { data } = await supabase
    .from('members')
    .select('*')
    .order('last_name')
  members.value = data ?? []
}

async function fetchReservations() {
  loading.value = true
  const from = filterDateFrom.value + 'T00:00:00Z'
  const to = filterDateTo.value + 'T23:59:59Z'

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

  reservations.value = data ?? []
  loading.value = false
}

function openCreate() {
  editing.value = null
  form.boat_id = ''
  form.user_id = ''
  form.date = toIso(today)
  form.startTime = '09:00'
  form.endTime = '13:00'
  form.status = 'confirmed'
  form.reason = ''
  form.comment = ''
  showModal.value = true
}

function openEdit(r: Reservation) {
  editing.value = r
  form.boat_id = r.boat_id
  form.user_id = r.user_id
  form.date = r.start_time.slice(0, 10)
  form.startTime = new Date(r.start_time).toTimeString().slice(0, 5)
  form.endTime = new Date(r.end_time).toTimeString().slice(0, 5)
  form.status = r.status as 'pending' | 'tentative' | 'confirmed'
  form.reason = r.reason
  form.comment = r.comment
  showModal.value = true
}

function closeModal() {
  showModal.value = false
  editing.value = null
}

async function saveReservation() {
  saving.value = true

  const payload = {
    boat_id: form.boat_id,
    user_id: form.user_id,
    start_time: new Date(`${form.date}T${form.startTime}:00`).toISOString(),
    end_time: new Date(`${form.date}T${form.endTime}:00`).toISOString(),
    status: form.status,
    reason: form.reason,
    comment: form.comment,
  }

  let error
  if (editing.value) {
    ;({ error } = await supabase.from('reservations').update(payload).eq('id', editing.value.id))
  } else {
    ;({ error } = await supabase.from('reservations').insert(payload))
  }

  saving.value = false
  if (error) { showToast('Save failed: ' + error.message, 'danger'); return }

  closeModal()
  await fetchReservations()
  showToast(editing.value ? 'Booking updated' : 'Booking created', 'success')
}

function confirmDelete(r: Reservation) {
  deleteAlert.id = r.id
  deleteAlert.show = true
}

async function deleteReservation() {
  deleteAlert.show = false
  const { error } = await supabase.from('reservations').delete().eq('id', deleteAlert.id)
  if (error) { showToast('Delete failed: ' + error.message, 'danger'); return }
  await fetchReservations()
  showToast('Booking deleted', 'success')
}

function boatName(id: string) {
  const b = boats.value.find(b => b.id === id)
  return b ? (b.display_name || b.name) : id
}

function statusColor(status: string) {
  return status === 'confirmed' ? 'success' : status === 'tentative' ? 'primary' : 'warning'
}

function formatDate(iso: string) {
  return new Date(iso).toLocaleDateString('en-CA', { weekday: 'short', month: 'short', day: 'numeric' })
}

function formatTime(iso: string) {
  return new Date(iso).toLocaleTimeString('en-CA', { hour: '2-digit', minute: '2-digit', hour12: false })
}

function toIso(d: Date) { return d.toISOString().slice(0, 10) }

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

<style scoped>
.filter-row {
  display: flex;
  gap: 0.5rem;
  margin-bottom: 1rem;
  flex-wrap: wrap;
  align-items: center;
}
.boat-filter { flex: 1; min-width: 120px; }
.date-filter { flex: 1; min-width: 130px; }

.res-card { margin: 0 0 0.6rem; }
.res-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 0.5rem;
}
.res-main { flex: 1; min-width: 0; }
.res-boat { font-weight: 600; font-size: 0.95rem; }
.res-member { font-size: 0.85rem; color: var(--ion-color-medium); }
.res-time { font-size: 0.85rem; margin: 0.15rem 0; }
.res-reason { font-size: 0.8rem; color: var(--ion-color-medium); font-style: italic; }
.res-right {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 0.25rem;
}
.status-badge { font-size: 0.7rem; }
.res-actions { display: flex; }

.required { color: var(--ion-color-danger); }
.empty-text { color: var(--ion-color-medium); text-align: center; padding: 2rem 0; }
</style>
