<template>
  <main class="create">
    <header class="create__header">
      <RouterLink to="/" class="create__back" aria-label="Back to home">&larr;</RouterLink>
      <h1 class="create__title">Create</h1>
    </header>

    <form class="create__form" novalidate @submit.prevent="handleSubmit">
      <div class="form-group">
        <label for="title" class="form-label">Title *</label>
        <input
          id="title"
          v-model="form.title"
          type="text"
          class="form-field"
          required
          maxlength="200"
          placeholder="What's the event?"
          :aria-invalid="!!errors.title"
          :aria-describedby="errors.title ? 'title-error' : undefined"
        />
        <span v-if="errors.title" id="title-error" class="field-error" role="alert">{{ errors.title }}</span>
      </div>

      <div class="form-group">
        <label for="description" class="form-label">Description</label>
        <textarea
          id="description"
          v-model="form.description"
          class="form-field"
          maxlength="2000"
          placeholder="Tell people more about it…"
          :aria-invalid="!!errors.description"
          :aria-describedby="errors.description ? 'description-error' : undefined"
        />
        <span v-if="errors.description" id="description-error" class="field-error" role="alert">{{ errors.description }}</span>
      </div>

      <div class="form-group">
        <label for="dateTime" class="form-label">Date &amp; Time *</label>
        <input
          id="dateTime"
          v-model="form.dateTime"
          type="datetime-local"
          class="form-field"
          required
          :aria-invalid="!!errors.dateTime"
          :aria-describedby="errors.dateTime ? 'dateTime-error' : undefined"
        />
        <span v-if="errors.dateTime" id="dateTime-error" class="field-error" role="alert">{{ errors.dateTime }}</span>
      </div>

      <div class="form-group">
        <label for="location" class="form-label">Location</label>
        <input
          id="location"
          v-model="form.location"
          type="text"
          class="form-field"
          maxlength="500"
          placeholder="Where is it?"
          :aria-invalid="!!errors.location"
          :aria-describedby="errors.location ? 'location-error' : undefined"
        />
        <span v-if="errors.location" id="location-error" class="field-error" role="alert">{{ errors.location }}</span>
      </div>

      <div class="form-group">
        <label for="expiryDate" class="form-label">Expiry Date *</label>
        <input
          id="expiryDate"
          v-model="form.expiryDate"
          type="date"
          class="form-field"
          required
          :min="tomorrow"
          :aria-invalid="!!errors.expiryDate"
          :aria-describedby="errors.expiryDate ? 'expiryDate-error' : undefined"
        />
        <span v-if="errors.expiryDate" id="expiryDate-error" class="field-error" role="alert">{{ errors.expiryDate }}</span>
      </div>

      <button type="submit" class="btn-primary" :disabled="submitting">
        {{ submitting ? 'Creating…' : 'Create Event' }}
      </button>

      <p v-if="serverError" class="field-error text-center" role="alert">{{ serverError }}</p>
    </form>
  </main>
</template>

<script setup lang="ts">
import { reactive, ref, computed, watch } from 'vue'
import { RouterLink, useRouter } from 'vue-router'
import { api } from '@/api/client'
import { useEventStorage } from '@/composables/useEventStorage'

const router = useRouter()
const { saveCreatedEvent } = useEventStorage()

const form = reactive({
  title: '',
  description: '',
  dateTime: '',
  location: '',
  expiryDate: '',
})

const errors = reactive({
  title: '',
  description: '',
  dateTime: '',
  location: '',
  expiryDate: '',
})

const submitting = ref(false)
const serverError = ref('')

const tomorrow = computed(() => {
  const d = new Date()
  d.setDate(d.getDate() + 1)
  return d.toISOString().split('T')[0]
})

function clearErrors() {
  errors.title = ''
  errors.description = ''
  errors.dateTime = ''
  errors.location = ''
  errors.expiryDate = ''
  serverError.value = ''
}

// Clear individual field errors when the user types
watch(() => form.title, () => { errors.title = ''; serverError.value = '' })
watch(() => form.dateTime, () => { errors.dateTime = ''; serverError.value = '' })
watch(() => form.expiryDate, () => { errors.expiryDate = ''; serverError.value = '' })
watch(() => form.description, () => { serverError.value = '' })
watch(() => form.location, () => { serverError.value = '' })

function validate(): boolean {
  clearErrors()
  let valid = true

  if (!form.title.trim()) {
    errors.title = 'Title is required.'
    valid = false
  }

  if (!form.dateTime) {
    errors.dateTime = 'Date and time are required.'
    valid = false
  }

  if (!form.expiryDate) {
    errors.expiryDate = 'Expiry date is required.'
    valid = false
  } else if (form.expiryDate <= (new Date().toISOString().split('T')[0] ?? '')) {
    errors.expiryDate = 'Expiry date must be in the future.'
    valid = false
  }

  return valid
}

async function handleSubmit() {
  if (!validate()) return

  submitting.value = true

  // Build ISO 8601 dateTime with local timezone offset
  const localDate = new Date(form.dateTime)
  const offsetMinutes = -localDate.getTimezoneOffset()
  const sign = offsetMinutes >= 0 ? '+' : '-'
  const absOffset = Math.abs(offsetMinutes)
  const offsetHours = String(Math.floor(absOffset / 60)).padStart(2, '0')
  const offsetMins = String(absOffset % 60).padStart(2, '0')
  const dateTimeWithOffset = form.dateTime + ':00' + sign + offsetHours + ':' + offsetMins

  try {
    const { data, error } = await api.POST('/events', {
      body: {
        title: form.title.trim(),
        description: form.description.trim() || undefined,
        dateTime: dateTimeWithOffset,
        timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
        location: form.location.trim() || undefined,
        expiryDate: form.expiryDate,
      },
    })

    submitting.value = false

    if (error) {
      if ('fieldErrors' in error && Array.isArray(error.fieldErrors)) {
        for (const fe of error.fieldErrors) {
          const field = fe.field as keyof typeof errors
          if (field in errors) {
            errors[field] = fe.message
          }
        }
      } else {
        serverError.value = error.detail || 'Something went wrong. Please try again.'
      }
      return
    }

    if (data) {
      saveCreatedEvent({
        eventToken: data.eventToken,
        organizerToken: data.organizerToken,
        title: data.title,
        dateTime: data.dateTime,
        expiryDate: data.expiryDate,
      })

      router.push({ name: 'event', params: { token: data.eventToken } })
    }
  } catch {
    submitting.value = false
    serverError.value = 'Could not reach the server. Please try again.'
  }
}
</script>

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

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

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

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

.create__form {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-lg);
}
</style>
