<script setup lang="ts">
import { ref, computed, onMounted } from 'vue'
import { fetchOrders, cancelOrder, type Order } from '@/api/orders'
import { fetchSwishInfo } from '@/api/payment'
import { RouterLink } from 'vue-router'
import {
  ORDER_STATUS_BADGE,
  ORDER_STATUS_LABELS,
} from '@/constants/orderStatus'

const ORDER_AMOUNT_FALLBACK = 49

const orders = ref<Order[]>([])
const orderAmount = ref(ORDER_AMOUNT_FALLBACK)
const loading = ref(true)
const error = ref('')
const actionError = ref('')
const cancellingId = ref<string | null>(null)
const expandedPreviewIds = ref<Set<string>>(new Set())

const PREVIEW_CHAR_LIMIT = 120

function isLongMessage(text: string): boolean {
  return text.length > PREVIEW_CHAR_LIMIT
}

function isPreviewExpanded(orderId: string): boolean {
  return expandedPreviewIds.value.has(orderId)
}

function togglePreview(orderId: string) {
  const next = new Set(expandedPreviewIds.value)
  if (next.has(orderId)) {
    next.delete(orderId)
  } else {
    next.add(orderId)
  }
  expandedPreviewIds.value = next
}

const pendingOrders = computed(() =>
  orders.value.filter((order) => order.status === 'pending_payment'),
)

const completedOrders = computed(() =>
  orders.value.filter((order) => order.status !== 'pending_payment'),
)

function formatDate(iso: string): string {
  return new Date(iso).toLocaleDateString('sv-SE', {
    year: 'numeric',
    month: 'short',
    day: 'numeric',
  })
}

async function loadOrders() {
  try {
    const [fetchedOrders, swishInfo] = await Promise.all([
      fetchOrders(),
      fetchSwishInfo().catch(() => ({
        number: '',
        amount: ORDER_AMOUNT_FALLBACK,
      })),
    ])
    orders.value = fetchedOrders
    orderAmount.value = swishInfo.amount
  } catch {
    error.value = 'Kunde inte hämta beställningar. Försök igen senare.'
  } finally {
    loading.value = false
  }
}

async function handleCancel(order: Order) {
  if (
    !window.confirm(
      'Vill du avbryta beställningen? Den kan inte återställas efteråt.',
    )
  ) {
    return
  }

  actionError.value = ''
  cancellingId.value = order.id

  try {
    const updated = await cancelOrder(order.id)
    orders.value = orders.value.map((o) => (o.id === updated.id ? updated : o))
  } catch {
    actionError.value = 'Kunde inte avbryta beställningen. Försök igen senare.'
  } finally {
    cancellingId.value = null
  }
}

onMounted(loadOrders)
</script>

<template>
  <div class="page">
    <h1 class="page__title">Mina beställningar</h1>
    <p class="page__subtitle">Här kan du se dina tidigare beställningar.</p>

    <p
      v-if="loading"
      class="text-muted text-center orders__loading"
      role="status"
    >
      Laddar beställningar...
    </p>

    <div v-else-if="error" class="message message--error" role="alert">
      {{ error }}
    </div>

    <div v-else-if="orders.length === 0" class="orders__empty">
      <div class="orders__empty-card">
        <p class="orders__empty-title">Inga beställningar ännu</p>
        <p class="orders__empty-text">
          Följ dina brev och se tidigare skickade hälsningar.
        </p>
        <RouterLink to="/" class="btn btn--primary orders__empty-cta">
          Skicka första brevet
        </RouterLink>
      </div>
    </div>

    <template v-else>
      <div
        v-if="actionError"
        class="message message--error orders__action-error"
        role="alert"
      >
        {{ actionError }}
      </div>

      <section v-if="pendingOrders.length" class="orders__section">
        <h2 class="orders__section-title">Obetalda beställningar</h2>
        <div class="orders__list">
          <div
            v-for="order in pendingOrders"
            :key="order.id"
            class="orders__card orders__card--pending"
          >
            <div class="orders__card-content">
              <div class="orders__card-head">
                <p class="orders__plate-badge">
                  <span class="orders__plate-label">Regnr</span>
                  <span class="orders__plate-value">{{ order.plate }}</span>
                </p>
                <span class="badge badge--warning">
                  {{ ORDER_STATUS_LABELS[order.status] }}
                </span>
              </div>

              <div class="orders__preview-box">
                <p
                  class="orders__preview"
                  :class="{
                    'orders__preview--expanded': isPreviewExpanded(order.id),
                  }"
                >
                  {{ order.letterText }}
                </p>
                <button
                  v-if="isLongMessage(order.letterText)"
                  type="button"
                  class="orders__preview-toggle"
                  @click="togglePreview(order.id)"
                >
                  {{ isPreviewExpanded(order.id) ? 'Visa mindre' : 'Visa mer' }}
                </button>
              </div>

              <p class="orders__order-date">
                Skapad {{ formatDate(order.createdAt) }}
              </p>

              <div class="orders__order-ref orders__order-ref--highlight">
                <p class="orders__order-ref-label">Beställnings-ID</p>
                <p class="orders__order-id">{{ order.id }}</p>
              </div>

              <div class="orders__price-row">
                <span class="orders__price-label">Att betala</span>
                <span class="orders__price-amount">{{ orderAmount }} kr</span>
              </div>

              <RouterLink
                :to="{
                  name: 'payment',
                  params: { orderId: order.id },
                  query: { plate: order.plate },
                }"
                class="btn btn--primary orders__pay-btn"
              >
                Betala {{ orderAmount }} kr
              </RouterLink>

              <div class="orders__links">
                <RouterLink
                  :to="{
                    name: 'edit-order',
                    params: { orderId: order.id },
                  }"
                  class="orders__text-link orders__edit-btn"
                >
                  Redigera brev
                </RouterLink>
                <span class="orders__link-sep" aria-hidden="true">·</span>
                <button
                  type="button"
                  class="orders__text-link orders__text-link--danger orders__cancel-btn"
                  spellcheck="false"
                  :disabled="cancellingId === order.id"
                  @click="handleCancel(order)"
                >
                  {{
                    cancellingId === order.id
                      ? 'Avbryter...'
                      : 'Avbryt beställning'
                  }}
                </button>
              </div>
            </div>
          </div>
        </div>
      </section>

      <section v-if="completedOrders.length" class="orders__section">
        <h2 v-if="pendingOrders.length" class="orders__section-title">
          Tidigare beställningar
        </h2>
        <div class="orders__list">
          <div
            v-for="order in completedOrders"
            :key="order.id"
            class="orders__card"
          >
            <div class="orders__card-content">
              <div class="orders__card-head">
                <p class="orders__plate-badge">
                  <span class="orders__plate-label">Regnr</span>
                  <span class="orders__plate-value">{{ order.plate }}</span>
                </p>
                <span
                  class="badge"
                  :class="ORDER_STATUS_BADGE[order.status] || 'badge--muted'"
                >
                  {{ ORDER_STATUS_LABELS[order.status] || order.status }}
                </span>
              </div>

              <div class="orders__preview-box">
                <p
                  class="orders__preview"
                  :class="{
                    'orders__preview--expanded': isPreviewExpanded(order.id),
                  }"
                >
                  {{ order.letterText }}
                </p>
                <button
                  v-if="isLongMessage(order.letterText)"
                  type="button"
                  class="orders__preview-toggle"
                  @click="togglePreview(order.id)"
                >
                  {{ isPreviewExpanded(order.id) ? 'Visa mindre' : 'Visa mer' }}
                </button>
              </div>

              <p class="orders__order-date">
                Skapad {{ formatDate(order.createdAt) }}
              </p>

              <a
                v-if="order.trackingId"
                class="btn btn--ghost orders__tracking-btn"
                :href="`https://www.postnord.se/verktyg/spara/?id=${order.trackingId}`"
                target="_blank"
                rel="noopener noreferrer"
              >
                Spåra brev · {{ order.trackingId }}
              </a>

              <div class="orders__order-ref">
                <p class="orders__order-ref-label">Beställnings-ID</p>
                <p class="orders__order-id">{{ order.id }}</p>
              </div>
            </div>
          </div>
        </div>
      </section>
    </template>
  </div>
</template>

<style scoped>
.page {
  max-width: 48rem;
  margin: clamp(var(--space-xl), 6vw, var(--space-3xl)) auto 0;
  padding: 0 var(--page-gutter);
}

.page__title {
  margin: 0 0 var(--space-sm) 0;
  font-size: 1.5rem;
  color: var(--color-ink);
}

.page__subtitle {
  margin: 0 0 var(--space-xl) 0;
  font-size: 0.875rem;
  color: var(--color-muted);
}

.orders__action-error {
  margin-bottom: var(--space-md);
}

.orders__section + .orders__section {
  margin-top: var(--space-xl);
}

.orders__section-title {
  margin: 0 0 var(--space-md) 0;
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--color-muted);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.orders__list {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
}

.orders__card {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: var(--shadow-md);
}

.orders__card-content {
  padding: var(--space-lg);
}

.orders__card--pending .orders__order-date {
  margin-bottom: var(--space-md);
}

.orders__card-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-md);
  margin-bottom: var(--space-md);
}

.orders__plate-badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-sm);
  background: var(--color-primary-soft);
  padding: var(--space-sm) var(--space-md);
  border-radius: var(--radius-full);
  margin: 0;
}

.orders__plate-label {
  font-size: 0.75rem;
  font-weight: 600;
  text-transform: uppercase;
  color: var(--color-muted);
}

.orders__plate-value {
  font-size: 0.9375rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  color: var(--color-primary-dark);
}

.orders__preview-box {
  background: var(--color-border-light);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-md);
  margin-bottom: var(--space-sm);
}

.orders__preview {
  margin: 0;
  font-family: var(--font-serif);
  font-size: 0.9375rem;
  line-height: 1.6;
  color: var(--color-ink);
  white-space: pre-wrap;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  line-clamp: 3;
  overflow: hidden;
}

.orders__preview--expanded {
  display: block;
  -webkit-line-clamp: unset;
  line-clamp: unset;
  overflow: visible;
}

.orders__preview-toggle {
  margin-top: var(--space-sm);
  font-size: 0.8125rem;
  font-weight: 500;
  color: var(--color-primary);
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
}

.orders__preview-toggle:hover {
  text-decoration: underline;
  text-underline-offset: 2px;
}

.orders__order-date {
  margin: 0 0 var(--space-sm) 0;
  font-size: 0.8125rem;
  color: var(--color-muted);
}

.orders__tracking-btn {
  width: 100%;
  justify-content: center;
  margin: var(--space-md) 0 var(--space-sm);
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--color-primary-dark);
  border-color: #ddd6fe;
  background: var(--color-primary-soft);
}

.orders__tracking-btn:hover {
  background: #dbeafe;
  border-color: #93c5fd;
}

.orders__order-ref {
  margin: var(--space-md) 0 0;
  padding-top: var(--space-md);
  border-top: 1px solid var(--color-border);
}

.orders__order-ref--highlight {
  margin: 0 0 var(--space-md);
  padding: var(--space-md);
  background: var(--color-border-light);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
}

.orders__order-ref-label {
  margin: 0 0 var(--space-xs) 0;
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--color-muted);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.orders__order-id {
  margin: 0;
  font-family: ui-monospace, monospace;
  font-size: 0.8125rem;
  color: var(--color-ink);
  word-break: break-all;
  line-height: 1.5;
}

.orders__price-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: var(--space-md);
  padding-bottom: var(--space-md);
  border-bottom: 1px solid var(--color-border);
}

.orders__price-label {
  font-size: 0.875rem;
  color: var(--color-muted);
}

.orders__price-amount {
  font-size: 1.25rem;
  font-weight: 700;
  color: var(--color-ink);
}

.orders__pay-btn {
  width: 100%;
  justify-content: center;
  margin-bottom: var(--space-md);
}

.orders__links {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-sm);
  flex-wrap: wrap;
}

.orders__text-link {
  font-size: 0.8125rem;
  font-weight: 500;
  color: var(--color-primary);
  text-decoration: none;
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
}

.orders__text-link:hover:not(:disabled) {
  text-decoration: underline;
  text-underline-offset: 2px;
}

.orders__text-link--danger {
  color: var(--color-danger);
}

.orders__text-link--danger:hover:not(:disabled) {
  color: #991b1b;
}

.orders__text-link:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

.orders__link-sep {
  color: var(--color-soft);
  user-select: none;
}

.orders__empty {
  padding: var(--space-2xl) 0;
  text-align: center;
}

.orders__empty-card {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-xl);
  padding: var(--space-2xl);
  box-shadow: var(--shadow-card);
}

.orders__empty-title {
  font-size: 1.125rem;
  font-weight: 600;
  color: var(--color-ink);
  margin: 0 0 var(--space-sm) 0;
}

.orders__empty-text {
  font-size: 0.875rem;
  color: var(--color-muted);
  margin: 0;
}

.orders__empty-cta {
  margin-top: var(--space-md);
  display: inline-flex;
}

.orders__loading {
  padding: var(--space-2xl) 0;
}

@media (max-width: 639px) {
  .orders__card-head {
    flex-direction: column;
    align-items: flex-start;
  }

  .orders__plate-badge {
    max-width: 100%;
  }

  .orders__links {
    flex-direction: column;
    align-items: stretch;
    gap: var(--space-sm);
  }

  .orders__link-sep {
    display: none;
  }

  .orders__text-link {
    padding: 0.5rem 0;
    min-height: 2.75rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }
}
</style>
