<template>
  <div class="public-booking-page">
    <!-- Property picker (no slug in route) -->
    <div v-if="phase === 'picker'" class="picker-wrap">
      <div class="picker-card card">
        <h2>Rezervă un spațiu</h2>
        <p class="subtitle">Alege o proprietate pentru a continua rezervarea, fără cont</p>
        <div v-if="loadingPicker" class="loading-inline">Se încarcă proprietățile...</div>
        <div v-else-if="pickerError" class="error-banner">
          {{ pickerError }}
          <button class="btn-retry" @click="loadPicker">Reîncearcă</button>
        </div>
        <div v-else-if="pickerProperties.length === 0" class="empty-msg">
          Nu există proprietăți publice disponibile momentan.
        </div>
        <div v-else class="property-list">
          <div
            v-for="prop in pickerProperties"
            :key="prop.id"
            class="selectable-card"
            @click="goToProperty(prop)"
          >
            <h4>{{ prop.name }}</h4>
            <p v-if="prop.description" class="card-desc">{{ prop.description }}</p>
            <p v-if="prop.address" class="card-meta">{{ prop.address }}</p>
            <span class="card-count">{{ prop.space_count || 0 }} spații</span>
          </div>
        </div>
        <p class="login-hint">
          Ai deja cont? <router-link to="/login">Autentifică-te</router-link>
        </p>
      </div>
    </div>

    <!-- Resolving property -->
    <div v-else-if="phase === 'resolving'" class="state-wrap">
      <div class="loading-inline">Se încarcă pagina de rezervare...</div>
    </div>

    <!-- Not found / private -->
    <div v-else-if="phase === 'notfound'" class="state-wrap">
      <div class="state-card card">
        <h3>Pagina de rezervare nu mai e disponibilă</h3>
        <p>Linkul folosit nu (mai) corespunde unei proprietăți publice.</p>
        <router-link to="/book" class="btn btn-primary">Vezi proprietăți disponibile</router-link>
      </div>
    </div>

    <!-- Load error -->
    <div v-else-if="phase === 'error'" class="state-wrap">
      <div class="state-card card">
        <h3>A apărut o eroare</h3>
        <p>{{ loadError }}</p>
        <button class="btn btn-primary" @click="init">Reîncearcă</button>
      </div>
    </div>

    <!-- Ready: calendar booking -->
    <div v-else-if="phase === 'ready'" class="booking-wrap">
      <div v-if="isDemoProperty" class="demo-banner">
        Mediu demo — rezervările se șterg automat la 3 ore.
      </div>

      <header class="booking-header">
        <h2>{{ property?.name }}</h2>
        <p v-if="property?.address" class="address">{{ property.address }}</p>
        <p v-if="property?.require_approval" class="approval-note">Necesită aprobare</p>
      </header>

      <div v-if="successBooking" class="success-state card">
        <div class="success-icon">&#10003;</div>
        <h3>Cererea a fost trimisă!</h3>
        <p>
          Vei primi actualizări la <strong>{{ successBooking.guest_email }}</strong>.
        </p>
        <p class="ref-code">Cod de referință: <strong>#RB-{{ successBooking.id }}</strong></p>
        <button class="btn btn-primary" @click="bookAnother">Fă o altă rezervare</button>
      </div>

      <template v-else>
        <div v-if="loadingSpaces" class="loading-inline">Se încarcă spațiile...</div>
        <div v-else-if="spaces.length === 0" class="empty-msg">
          Această proprietate nu are spații disponibile pentru rezervare.
        </div>
        <template v-else>
          <div class="space-tabs-row">
            <div class="space-tabs">
              <button
                v-for="sp in visibleTabs"
                :key="sp.id"
                type="button"
                class="space-tab"
                :class="{ active: selectedSpace?.id === sp.id }"
                @click="setSpace(sp)"
              >
                {{ sp.name }}
              </button>
            </div>
            <select
              v-if="spaces.length > 6"
              class="space-select"
              :value="selectedSpace?.id"
              @change="onSelectChange"
            >
              <option v-for="sp in spaces" :key="sp.id" :value="sp.id">{{ sp.name }}</option>
            </select>
          </div>

          <div class="booking-layout" :class="{ 'has-selection': !!selection }">
            <div class="calendar-pane">
              <PublicCalendar
                v-if="selectedSpace"
                ref="calendarRef"
                v-model:selection="selection"
                :space-id="selectedSpace.id"
                :working-hours-start="selectedSpace.working_hours_start"
                :working-hours-end="selectedSpace.working_hours_end"
              />
            </div>
            <div class="form-pane" ref="formPaneRef">
              <GuestBookingForm
                v-if="selectedSpace"
                :space-id="selectedSpace.id"
                :selection="selection"
                :submitting="submitting"
                :submit-error="submitError"
                :require-approval="!!property?.require_approval"
                :busy-loaded="true"
                @submit="handleSubmit"
              />
            </div>
          </div>
        </template>
      </template>

      <p class="login-hint">
        Ai deja cont? <router-link to="/login">Autentifică-te</router-link>
      </p>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, watch, nextTick } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { AxiosError } from 'axios'
import { publicApi, handleApiError } from '@/services/api'
import type { Property, Space, Booking, AnonymousBookingCreate } from '@/types'
import PublicCalendar from '@/components/PublicCalendar.vue'
import GuestBookingForm from '@/components/GuestBookingForm.vue'

const route = useRoute()
const router = useRouter()

type Phase = 'picker' | 'resolving' | 'notfound' | 'error' | 'ready'

const phase = ref<Phase>('resolving')
const loadError = ref('')

const loadingPicker = ref(false)
const pickerError = ref('')
const pickerProperties = ref<Property[]>([])

const property = ref<Property | null>(null)
const spaces = ref<Space[]>([])
const loadingSpaces = ref(false)
const selectedSpace = ref<Space | null>(null)

const selection = ref<{ date: string; start: string; end: string } | null>(null)
const submitting = ref(false)
const submitError = ref('')
const successBooking = ref<Booking | null>(null)

const calendarRef = ref<InstanceType<typeof PublicCalendar> | null>(null)
const formPaneRef = ref<HTMLElement | null>(null)

const isDemoProperty = computed(() => property.value?.slug === 'proprietate-demo')
const visibleTabs = computed(() => spaces.value.slice(0, 6))

async function loadPicker() {
  loadingPicker.value = true
  pickerError.value = ''
  try {
    pickerProperties.value = await publicApi.getProperties()
  } catch (err) {
    pickerError.value = handleApiError(err)
  } finally {
    loadingPicker.value = false
  }
}

function goToProperty(prop: Property) {
  router.push(`/book/${prop.slug || prop.id}`)
}

async function loadSpaces(slugOrId: string) {
  loadingSpaces.value = true
  try {
    spaces.value = await publicApi.getPropertySpaces(slugOrId)
    selectedSpace.value = spaces.value[0] ?? null
  } catch (err) {
    spaces.value = []
  } finally {
    loadingSpaces.value = false
  }
}

async function resolveProperty(slugOrId: string) {
  phase.value = 'resolving'
  loadError.value = ''
  try {
    property.value = await publicApi.getProperty(slugOrId)
    await loadSpaces(slugOrId)
    phase.value = 'ready'
  } catch (err) {
    if (err instanceof AxiosError && err.response?.status === 404) {
      phase.value = 'notfound'
    } else {
      loadError.value = handleApiError(err)
      phase.value = 'error'
    }
  }
}

function init() {
  const slug = route.params.slug as string | undefined
  if (slug) {
    resolveProperty(slug)
  } else {
    phase.value = 'picker'
    loadPicker()
  }
}

function setSpace(sp: Space) {
  selectedSpace.value = sp
  selection.value = null
  submitError.value = ''
}

function onSelectChange(e: Event) {
  const id = Number((e.target as HTMLSelectElement).value)
  const sp = spaces.value.find((s) => s.id === id)
  if (sp) setSpace(sp)
}

async function handleSubmit(payload: AnonymousBookingCreate) {
  submitting.value = true
  submitError.value = ''
  try {
    const booking = await publicApi.createBooking(payload)
    successBooking.value = booking
    selection.value = null
  } catch (err) {
    if (err instanceof AxiosError && (err.response?.status === 400 || err.response?.status === 409)) {
      submitError.value = 'Slotul tocmai a fost ocupat, alege altul'
      calendarRef.value?.markOccupied(selection.value)
      selection.value = null
      calendarRef.value?.refreshBusy()
    } else {
      submitError.value = handleApiError(err)
    }
  } finally {
    submitting.value = false
  }
}

function bookAnother() {
  successBooking.value = null
  selection.value = null
  submitError.value = ''
}

watch(selection, (sel) => {
  if (sel && window.innerWidth < 768) {
    nextTick(() => {
      formPaneRef.value?.scrollIntoView({ behavior: 'smooth', block: 'start' })
    })
  }
})

watch(
  () => route.params.slug,
  () => init()
)

init()
</script>

<style scoped>
.public-booking-page {
  min-height: 100vh;
  background: var(--color-bg-primary);
  padding: 1.5rem clamp(1rem, 3vw, 2.5rem) 3rem;
}

.picker-wrap {
  display: flex;
  justify-content: center;
  padding-top: 1.5rem;
}

.picker-card {
  width: 100%;
  max-width: 560px;
}

.state-wrap {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 60vh;
}

.state-card {
  max-width: 480px;
  text-align: center;
  display: flex;
  flex-direction: column;
  gap: 12px;
  align-items: center;
}

h2 {
  color: var(--color-text-primary);
  margin: 0 0 0.25rem;
}

.subtitle {
  color: var(--color-text-secondary);
  margin-bottom: 1.5rem;
}

.loading-inline {
  text-align: center;
  padding: 24px;
  color: var(--color-text-secondary);
}

.empty-msg {
  text-align: center;
  padding: 24px;
  color: var(--color-text-muted);
}

.error-banner {
  display: flex;
  flex-direction: column;
  gap: 8px;
  align-items: center;
  padding: 16px;
  background: color-mix(in srgb, var(--color-danger) 10%, transparent);
  border-radius: var(--radius-sm);
  color: var(--color-danger);
}

.btn-retry {
  background: var(--color-danger);
  color: white;
  border: none;
  border-radius: var(--radius-sm);
  padding: 6px 14px;
  cursor: pointer;
}

.property-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.selectable-card {
  padding: 16px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  cursor: pointer;
  transition: all var(--transition-fast);
  background: var(--color-bg-secondary);
}

.selectable-card:hover {
  border-color: var(--color-accent);
  box-shadow: var(--shadow-sm);
}

.selectable-card h4 {
  margin: 0 0 4px;
  font-size: 16px;
  color: var(--color-text-primary);
}

.card-desc {
  font-size: 14px;
  color: var(--color-text-secondary);
  margin: 0 0 4px;
}

.card-meta {
  font-size: 13px;
  color: var(--color-text-muted);
  margin: 0 0 4px;
}

.card-count {
  font-size: 12px;
  font-weight: 500;
  color: var(--color-accent);
}

.booking-wrap {
  max-width: 1200px;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
}

.demo-banner {
  padding: 10px 16px;
  background: color-mix(in srgb, var(--color-warning) 15%, transparent);
  border-left: 3px solid var(--color-warning);
  border-radius: var(--radius-sm);
  color: var(--color-text-primary);
  font-size: 14px;
  font-weight: 500;
}

.booking-header .address {
  color: var(--color-text-secondary);
  margin: 2px 0;
}

.approval-note {
  display: inline-block;
  font-size: 12px;
  font-weight: 600;
  color: var(--color-warning);
  background: color-mix(in srgb, var(--color-warning) 12%, transparent);
  padding: 3px 10px;
  border-radius: 999px;
  margin-top: 4px;
}

.space-tabs-row {
  display: flex;
  align-items: center;
  gap: 12px;
}

.space-tabs {
  display: flex;
  gap: 8px;
  overflow-x: auto;
  padding-bottom: 4px;
  flex: 1;
}

.space-tab {
  flex-shrink: 0;
  padding: 10px 16px;
  min-height: 44px;
  border: 1px solid var(--color-border);
  background: var(--color-surface);
  border-radius: var(--radius-md);
  cursor: pointer;
  font-size: 14px;
  color: var(--color-text-secondary);
  white-space: nowrap;
}

.space-tab.active {
  background: var(--color-accent);
  border-color: var(--color-accent);
  color: white;
  font-weight: 600;
}

.space-select {
  padding: 8px 12px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  background: var(--color-surface);
  color: var(--color-text-primary);
  min-height: 44px;
}

.booking-layout {
  display: grid;
  grid-template-columns: 1.5fr 1fr;
  gap: 1.5rem;
  align-items: start;
}

.calendar-pane {
  min-width: 0;
}

.form-pane {
  position: sticky;
  top: 1rem;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: 1.25rem;
}

@media (max-width: 900px) {
  .booking-layout {
    grid-template-columns: 1fr;
  }
  .form-pane {
    position: static;
  }
}

.success-state {
  text-align: center;
  padding: 32px 24px;
  max-width: 480px;
  margin: 0 auto;
}

.success-icon {
  width: 64px;
  height: 64px;
  border-radius: 50%;
  background: color-mix(in srgb, var(--color-success) 15%, transparent);
  color: var(--color-success);
  font-size: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0 auto 16px;
}

.success-state h3 {
  color: var(--color-success);
  margin-bottom: 8px;
}

.ref-code {
  font-size: 14px;
  color: var(--color-text-secondary);
}

.login-hint {
  text-align: center;
  margin-top: 1.5rem;
  padding-top: 1rem;
  border-top: 1px solid var(--color-border);
  color: var(--color-text-secondary);
  font-size: 14px;
}

.login-hint a {
  color: var(--color-accent);
  text-decoration: none;
}

.login-hint a:hover {
  text-decoration: underline;
}

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 10px 20px;
  border: none;
  border-radius: var(--radius-sm);
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  transition: all var(--transition-fast);
  text-decoration: none;
}

.btn-primary {
  background: var(--color-accent);
  color: white;
}

.btn-primary:hover {
  background: var(--color-accent-hover);
}
</style>
