<template>
  <Transition name="modal-fade">
    <div v-if="show && booking" class="preview-overlay" @click.self="$emit('close')">
      <div class="preview-modal" @keydown.escape="$emit('close')">
        <button class="preview-close" @click="$emit('close')" title="Close">
          <X :size="18" />
        </button>

        <div class="preview-header">
          <h3>{{ booking.title }}</h3>
          <span :class="['preview-badge', `preview-badge-${booking.status}`]">
            {{ booking.status }}
          </span>
        </div>

        <div class="preview-details">
          <div class="detail-row">
            <Building2 :size="16" class="detail-icon" />
            <span>{{ booking.space?.name || 'Unknown Space' }}</span>
          </div>

          <div v-if="booking.is_anonymous && booking.guest_name" class="detail-row">
            <UserIcon :size="16" class="detail-icon" />
            <span>
              {{ booking.guest_name }}
              <span class="detail-guest-badge">Guest</span>
              <span v-if="booking.guest_email" class="detail-muted">
                &middot; {{ booking.guest_email }}
              </span>
              <span v-if="booking.guest_organization" class="detail-muted">
                &middot; {{ booking.guest_organization }}
              </span>
            </span>
          </div>

          <div v-else-if="isAdmin && booking.user" class="detail-row">
            <UserIcon :size="16" class="detail-icon" />
            <span>
              {{ booking.user.full_name }}
              <span v-if="booking.user.organization" class="detail-muted">
                &middot; {{ booking.user.organization }}
              </span>
            </span>
          </div>

          <div class="detail-row">
            <CalendarDays :size="16" class="detail-icon" />
            <span>{{ formatDate(booking.start_datetime) }}</span>
          </div>

          <div class="detail-row">
            <Clock :size="16" class="detail-icon" />
            <span>{{ formatTimeRange(booking.start_datetime, booking.end_datetime) }}</span>
          </div>
        </div>

        <div v-if="booking.description" class="preview-description">
          <p :class="{ truncated: !showFullDesc && isLongDesc }">
            {{ booking.description }}
          </p>
          <button
            v-if="isLongDesc"
            class="show-more-btn"
            @click="showFullDesc = !showFullDesc"
          >
            {{ showFullDesc ? 'Show less' : 'Show more' }}
          </button>
        </div>

        <div v-if="actionButtons.length > 0" class="preview-actions">
          <button
            v-for="action in actionButtons"
            :key="action.key"
            :class="['preview-action-btn', `preview-action-${action.key}`]"
            @click="$emit(action.key as any, booking)"
          >
            <component :is="action.icon" :size="16" />
            {{ action.label }}
          </button>
        </div>
      </div>
    </div>
  </Transition>
</template>

<script setup lang="ts">
import { ref, computed, watch, onMounted, onUnmounted, type Component } from 'vue'
import { X, Building2, User as UserIcon, CalendarDays, Clock, Check, XCircle, Pencil, Ban } from 'lucide-vue-next'
import { formatDate as formatDateUtil, formatTime as formatTimeUtil } from '@/utils/datetime'
import { useAuthStore } from '@/stores/auth'
import type { Booking } from '@/types'

const props = defineProps<{
  booking: Booking | null
  isAdmin: boolean
  show: boolean
}>()

const emit = defineEmits<{
  close: []
  approve: [booking: Booking]
  reject: [booking: Booking]
  cancel: [booking: Booking]
  edit: [booking: Booking]
}>()

const authStore = useAuthStore()
const userTimezone = computed(() => authStore.user?.timezone || 'UTC')

const showFullDesc = ref(false)
const DESC_MAX_LENGTH = 150

const isLongDesc = computed(() =>
  (props.booking?.description?.length || 0) > DESC_MAX_LENGTH
)

// Reset show more when booking changes
watch(() => props.booking?.id, () => {
  showFullDesc.value = false
})

const formatDate = (datetime: string): string =>
  formatDateUtil(datetime, userTimezone.value)

const formatTimeRange = (start: string, end: string): string =>
  `${formatTimeUtil(start, userTimezone.value)} – ${formatTimeUtil(end, userTimezone.value)}`

interface ActionButton {
  key: string
  label: string
  icon: Component
}

const actionButtons = computed<ActionButton[]>(() => {
  if (!props.booking) return []
  const status = props.booking.status
  const buttons: ActionButton[] = []

  if (props.isAdmin && status === 'pending') {
    buttons.push({ key: 'approve', label: 'Approve', icon: Check })
    buttons.push({ key: 'reject', label: 'Reject', icon: XCircle })
  }

  if (status === 'pending' || status === 'approved') {
    buttons.push({ key: 'edit', label: 'Edit', icon: Pencil })
  }

  if (status === 'pending' || status === 'approved') {
    buttons.push({ key: 'cancel', label: 'Cancel', icon: Ban })
  }

  return buttons
})

// ESC key handler
const handleKeyDown = (e: KeyboardEvent) => {
  if (e.key === 'Escape' && props.show) {
    emit('close')
  }
}

onMounted(() => {
  document.addEventListener('keydown', handleKeyDown)
})

onUnmounted(() => {
  document.removeEventListener('keydown', handleKeyDown)
})
</script>

<style scoped>
.preview-overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.45);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
}

.preview-modal {
  background: var(--color-surface);
  border-radius: var(--radius-lg);
  padding: 24px;
  max-width: 400px;
  width: 90%;
  box-shadow: var(--shadow-lg);
  position: relative;
}

.preview-close {
  position: absolute;
  top: 12px;
  right: 12px;
  background: transparent;
  border: none;
  color: var(--color-text-muted);
  cursor: pointer;
  padding: 4px;
  border-radius: var(--radius-sm);
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all var(--transition-fast);
}

.preview-close:hover {
  background: var(--color-bg-secondary);
  color: var(--color-text-primary);
}

.preview-header {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  margin-bottom: 16px;
  padding-right: 28px;
}

.preview-header h3 {
  margin: 0;
  font-size: 18px;
  font-weight: 600;
  color: var(--color-text-primary);
  flex: 1;
  line-height: 1.3;
}

.preview-badge {
  display: inline-flex;
  align-items: center;
  padding: 3px 10px;
  font-size: 11px;
  font-weight: 600;
  border-radius: 10px;
  text-transform: capitalize;
  white-space: nowrap;
  flex-shrink: 0;
}

.preview-badge-pending {
  background: color-mix(in srgb, var(--color-warning) 15%, transparent);
  color: var(--color-warning);
}

.preview-badge-approved {
  background: color-mix(in srgb, var(--color-success) 15%, transparent);
  color: var(--color-success);
}

.preview-badge-rejected {
  background: color-mix(in srgb, var(--color-danger) 15%, transparent);
  color: var(--color-danger);
}

.preview-badge-canceled {
  background: var(--color-bg-tertiary);
  color: var(--color-text-muted);
}

/* Details */
.preview-details {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-bottom: 16px;
}

.detail-row {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
  color: var(--color-text-primary);
}

.detail-icon {
  color: var(--color-text-muted);
  flex-shrink: 0;
}

.detail-muted {
  color: var(--color-text-muted);
}

.detail-guest-badge {
  display: inline-block;
  padding: 1px 6px;
  font-size: 10px;
  font-weight: 600;
  border-radius: 6px;
  background: color-mix(in srgb, var(--color-warning) 15%, transparent);
  color: var(--color-warning);
  vertical-align: middle;
  margin-left: 4px;
}

/* Description */
.preview-description {
  background: var(--color-bg-secondary);
  border-radius: var(--radius-sm);
  padding: 12px;
  margin-bottom: 16px;
}

.preview-description p {
  margin: 0;
  font-size: 13px;
  color: var(--color-text-secondary);
  line-height: 1.5;
  white-space: pre-wrap;
}

.preview-description p.truncated {
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.show-more-btn {
  margin-top: 6px;
  padding: 0;
  background: none;
  border: none;
  color: var(--color-accent);
  font-size: 12px;
  font-weight: 500;
  cursor: pointer;
}

.show-more-btn:hover {
  text-decoration: underline;
}

/* Actions */
.preview-actions {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

.preview-action-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 14px;
  border-radius: var(--radius-sm);
  border: 1px solid transparent;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  transition: all var(--transition-fast);
  font-family: inherit;
}

.preview-action-approve {
  background: color-mix(in srgb, var(--color-success) 12%, transparent);
  color: var(--color-success);
  border-color: color-mix(in srgb, var(--color-success) 25%, transparent);
}

.preview-action-approve:hover {
  background: var(--color-success);
  color: #fff;
}

.preview-action-reject {
  background: color-mix(in srgb, var(--color-danger) 12%, transparent);
  color: var(--color-danger);
  border-color: color-mix(in srgb, var(--color-danger) 25%, transparent);
}

.preview-action-reject:hover {
  background: var(--color-danger);
  color: #fff;
}

.preview-action-edit {
  background: color-mix(in srgb, var(--color-warning) 12%, transparent);
  color: var(--color-warning);
  border-color: color-mix(in srgb, var(--color-warning) 25%, transparent);
}

.preview-action-edit:hover {
  background: var(--color-warning);
  color: #fff;
}

.preview-action-cancel {
  background: var(--color-bg-tertiary);
  color: var(--color-text-secondary);
  border-color: var(--color-border);
}

.preview-action-cancel:hover {
  background: var(--color-border);
  color: var(--color-text-primary);
}

/* Modal transition */
.modal-fade-enter-active,
.modal-fade-leave-active {
  transition: opacity 0.2s ease;
}

.modal-fade-enter-active .preview-modal,
.modal-fade-leave-active .preview-modal {
  transition: transform 0.2s ease, opacity 0.2s ease;
}

.modal-fade-enter-from,
.modal-fade-leave-to {
  opacity: 0;
}

.modal-fade-enter-from .preview-modal,
.modal-fade-leave-to .preview-modal {
  transform: scale(0.95);
  opacity: 0;
}

/* Mobile */
@media (max-width: 640px) {
  .preview-modal {
    max-width: none;
    width: calc(100% - 32px);
    margin: 16px;
  }

  .preview-actions {
    flex-direction: column;
  }

  .preview-action-btn {
    justify-content: center;
  }
}
</style>
