<template>
  <main class="detail">
    <header class="detail__header">
      <RouterLink to="/" class="detail__back" aria-label="Back to home">&larr;</RouterLink>
      <span class="detail__brand">fete</span>
    </header>

    <!-- Loading state -->
    <div v-if="state === 'loading'" class="detail__card" aria-busy="true" aria-label="Loading event details">
      <div class="skeleton skeleton--title" />
      <div class="skeleton skeleton--line" />
      <div class="skeleton skeleton--line skeleton--short" />
      <div class="skeleton skeleton--line" />
    </div>

    <!-- Loaded state -->
    <div v-else-if="state === 'loaded' && event" class="detail__card">
      <h1 class="detail__title">{{ event.title }}</h1>

      <dl class="detail__fields">
        <div class="detail__field">
          <dt class="detail__label">Date &amp; Time</dt>
          <dd class="detail__value">{{ formattedDateTime }}</dd>
        </div>

        <div v-if="event.description" class="detail__field">
          <dt class="detail__label">Description</dt>
          <dd class="detail__value">{{ event.description }}</dd>
        </div>

        <div v-if="event.location" class="detail__field">
          <dt class="detail__label">Location</dt>
          <dd class="detail__value">{{ event.location }}</dd>
        </div>

        <div class="detail__field">
          <dt class="detail__label">Attendees</dt>
          <dd class="detail__value">{{ event.attendeeCount }}</dd>
        </div>
      </dl>

      <div v-if="event.expired" class="detail__banner detail__banner--expired" role="status">
        This event has ended.
      </div>
    </div>

    <!-- Not found state -->
    <div v-else-if="state === 'not-found'" class="detail__card detail__card--center" role="status">
      <p class="detail__message">Event not found.</p>
    </div>

    <!-- Error state -->
    <div v-else-if="state === 'error'" class="detail__card detail__card--center" role="alert">
      <p class="detail__message">Something went wrong.</p>
      <button class="btn-primary" type="button" @click="fetchEvent">Retry</button>
    </div>

    <!-- RSVP bar (only for loaded, non-expired events) -->
    <RsvpBar
      v-if="state === 'loaded' && event && !event.expired && !isOrganizer"
      :has-rsvp="!!rsvpName"
      @open="sheetOpen = true"
    />

    <!-- RSVP bottom sheet -->
    <BottomSheet :open="sheetOpen" label="RSVP" @close="sheetOpen = false">
      <h2 class="sheet-title">RSVP</h2>
      <form class="rsvp-form" @submit.prevent="submitRsvp" novalidate>
        <div class="form-group">
          <label class="rsvp-form__label" for="rsvp-name">Your name</label>
          <input
            id="rsvp-name"
            v-model.trim="nameInput"
            class="form-field"
            type="text"
            placeholder="e.g. Max Mustermann"
            maxlength="100"
            required
            @input="nameError = ''"
          />
          <span v-if="nameError" class="rsvp-form__field-error" role="alert">{{ nameError }}</span>
        </div>
        <button class="btn-primary" type="submit" :disabled="submitting">
          {{ submitting ? 'Sending…' : "Count me in" }}
        </button>
        <p v-if="submitError" class="rsvp-form__field-error rsvp-form__error" role="alert">{{ submitError }}</p>
      </form>
    </BottomSheet>
  </main>
</template>

<script setup lang="ts">
import { ref, computed, onMounted } from 'vue'
import { RouterLink, useRoute } from 'vue-router'
import { api } from '@/api/client'
import { useEventStorage } from '@/composables/useEventStorage'
import BottomSheet from '@/components/BottomSheet.vue'
import RsvpBar from '@/components/RsvpBar.vue'
import type { components } from '@/api/schema'

type GetEventResponse = components['schemas']['GetEventResponse']
type State = 'loading' | 'loaded' | 'not-found' | 'error'

const route = useRoute()
const { saveRsvp, getRsvp, getOrganizerToken } = useEventStorage()

const state = ref<State>('loading')
const event = ref<GetEventResponse | null>(null)

// RSVP state
const sheetOpen = ref(false)
const nameInput = ref('')
const nameError = ref('')
const submitError = ref('')
const submitting = ref(false)
const rsvpName = ref<string | undefined>(undefined)
const isOrganizer = ref(false)

const formattedDateTime = computed(() => {
  if (!event.value) return ''
  const formatted = new Intl.DateTimeFormat(undefined, {
    dateStyle: 'long',
    timeStyle: 'short',
  }).format(new Date(event.value.dateTime))
  return `${formatted} (${event.value.timezone})`
})

async function fetchEvent() {
  state.value = 'loading'
  event.value = null

  try {
    const { data, error, response } = await api.GET('/events/{token}', {
      params: { path: { token: route.params.token as string } },
    })

    if (error) {
      state.value = response.status === 404 ? 'not-found' : 'error'
      return
    }

    event.value = data!
    state.value = 'loaded'

    // Check if current user is the organizer
    isOrganizer.value = !!getOrganizerToken(event.value.eventToken)

    // Restore RSVP status from localStorage
    const stored = getRsvp(event.value.eventToken)
    if (stored) {
      rsvpName.value = stored.rsvpName
    }
  } catch {
    state.value = 'error'
  }
}

async function submitRsvp() {
  nameError.value = ''
  submitError.value = ''

  if (!nameInput.value) {
    nameError.value = 'Please enter your name.'
    return
  }

  if (nameInput.value.length > 100) {
    nameError.value = 'Name must be 100 characters or fewer.'
    return
  }

  submitting.value = true

  try {
    const { data, error } = await api.POST('/events/{token}/rsvps', {
      params: { path: { token: route.params.token as string } },
      body: { name: nameInput.value },
    })

    if (error) {
      submitError.value = 'Could not submit RSVP. Please try again.'
      return
    }

    // Persist RSVP in localStorage
    saveRsvp(
      event.value!.eventToken,
      data!.rsvpToken,
      data!.name,
      event.value!.title,
      event.value!.dateTime,
    )

    // Update UI
    rsvpName.value = data!.name
    event.value!.attendeeCount += 1
    sheetOpen.value = false
    nameInput.value = ''
  } catch {
    submitError.value = 'Could not submit RSVP. Please try again.'
  } finally {
    submitting.value = false
  }
}

onMounted(fetchEvent)
</script>

<style scoped>
.detail {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-2xl);
  padding-top: var(--spacing-lg);
}

.detail__header {
  display: flex;
  align-items: center;
  gap: var(--spacing-sm);
}

.detail__back {
  color: var(--color-text-on-gradient);
  font-size: 1.5rem;
  text-decoration: none;
  line-height: 1;
}

.detail__brand {
  font-size: 1.3rem;
  font-weight: 700;
  color: var(--color-text-on-gradient);
}

.detail__card {
  background: var(--color-card);
  border-radius: var(--radius-card);
  padding: var(--spacing-xl);
  box-shadow: var(--shadow-card);
  display: flex;
  flex-direction: column;
  gap: var(--spacing-lg);
}

.detail__card--center {
  align-items: center;
  text-align: center;
}

.detail__title {
  font-size: 1.4rem;
  font-weight: 700;
  color: var(--color-text);
  word-break: break-word;
}

.detail__fields {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-md);
}

.detail__field {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
}

.detail__label {
  font-size: 0.8rem;
  font-weight: 700;
  color: #888;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.detail__value {
  font-size: 0.95rem;
  color: var(--color-text);
  word-break: break-word;
}

.detail__banner {
  padding: var(--spacing-sm) var(--spacing-md);
  border-radius: var(--radius-card);
  font-weight: 600;
  font-size: 0.9rem;
  text-align: center;
}

.detail__banner--expired {
  background: #fff3e0;
  color: #e65100;
}

.detail__message {
  font-size: 1rem;
  font-weight: 600;
  color: var(--color-text);
}

/* Skeleton sizes */
.skeleton--title {
  height: 1.6rem;
  width: 60%;
}

.skeleton--line {
  height: 1rem;
  width: 80%;
}

.skeleton--short {
  width: 40%;
}
</style>
