<template>
  <div v-if="show" class="bookaro-booking-modal" @click.self="$emit('close')">
    <div class="bookaro-booking-wrapper bookaro-details-wrapper bookaro-card">
      <button class="modal-close-button" @click="$emit('close')">&times;</button>
      <div class="details-header">
        <h3 class="details-title">{{ i18n.details }}</h3>
      </div>

      <div class="bookaro-booking-grid">
        <div class="bookaro-booking-col">
          <section class="details-section">
            <h4 class="details-section-title">{{ i18n.booking_info }}</h4>
            <div class="details-list">
              <div
                v-for="(item, idx) in detailItems"
                :key="`detail-${idx}`"
                :class="['detail-row', { 'detail-row--long': item.long }]"
              >
                <span class="detail-label">{{ item.label }}</span>
                <span class="detail-value">
                  <a v-if="item.url" :href="item.url" target="_blank" rel="noopener">
                    {{ item.value }}
                  </a>
                  <span v-else>{{ item.value }}</span>
                </span>
              </div>
            </div>
          </section>

          <section v-if="policyLines.length" class="details-section">
            <h4 class="details-section-title">{{ policyTitle }}</h4>
            <ul class="details-policy-list">
              <li v-for="(line, idx) in policyLines" :key="`policy-${idx}`">
                {{ line }}
              </li>
            </ul>
          </section>
        </div>

        <div class="bookaro-booking-col">
          <section class="details-section">
            <h4 class="details-section-title">{{ statusTimelineTitle }}</h4>
            <ol class="status-timeline">
              <li
                v-for="(step, idx) in timelineSteps"
                :key="`status-${step.key}-${idx}`"
                :class="['timeline-step', step.state]"
              >
                <span class="timeline-marker" aria-hidden="true"></span>
                <span class="timeline-label">{{ step.label }}</span>
              </li>
            </ol>
          </section>

        </div>
      </div>

      <footer class="bookaro-booking-actions">
        <button
            @click="$emit('close')"
            class="bookaro-btn bookaro-btn--outline"
        >
          {{ i18n.close }}
        </button>
      </footer>
    </div>
  </div>
</template>

<script>
import { getPolicyStatusLines } from '@bookaro-free/utils/bookingPolicies.js';

export default {
  name: 'DetailsModal',
  props: {
    show: Boolean,
    booking: { type: Object, required: true },
  },
  computed: {
    i18n() {
      return this.$root.i18n || {};
    },
    showProvider() {
      return (
        this.booking.provider_name ||
        this.booking.provider_email ||
        this.booking.provider_phone
      );
    },
    bookingStatusLabel() {
      const status = (this.booking.status || '').toString().toLowerCase();
      if (!status) {
        return '';
      }
      const map = {
        pending: this.i18n.status_pending || this.i18n.pending,
        approved: this.i18n.status_approved || this.i18n.approved,
        rejected: this.i18n.status_rejected || this.i18n.rejected,
        cancelled: this.i18n.status_cancelled || this.i18n.cancelled,
        completed: this.i18n.status_completed || this.i18n.completed,
        no_show: this.i18n.status_no_show || this.i18n.no_show
      };
      return map[status] || this.i18n.status_unknown || '';
    },
    bookingDateLabel() {
      const startRaw = this.booking.booking_date;
      if (!startRaw) {
        return '';
      }
      const format = this.i18n.date_time_format || 'DD/MM/YY HH:mm';
      const start = window.dayjs(startRaw);
      if (!start.isValid()) {
        return '';
      }
      let label = start.format(format);
      if (this.booking.booking_date_to) {
        const end = window.dayjs(this.booking.booking_date_to);
        if (end.isValid()) {
          label = `${label} -> ${end.format(format)}`;
        }
      }
      return label;
    },
    bookingDurationLabel() {
      // Bug 58: for range bookings (booking_date_to is set and differs
      // from booking_date by more than the service duration), the actual
      // span is what the customer sees on their calendar, not the service
      // config. Service duration here is the CURRENT service config,
      // which can drift after the booking was made; the email template
      // already does end.diff(start) and correctly reports "48h" while
      // this modal was reporting "1h" for a 2-day cancelled booking
      // because service 27 was reconfigured between create and view.
      // Trust the range when it exceeds service duration.
      let duration = Number(this.booking.service_duration || 0);
      if (this.booking.booking_date && this.booking.booking_date_to) {
        const start = window.dayjs(this.booking.booking_date);
        const end = window.dayjs(this.booking.booking_date_to);
        if (start.isValid() && end.isValid()) {
          const rangeMinutes = end.diff(start, 'minute');
          if (rangeMinutes > 0 && (rangeMinutes > duration || !Number.isFinite(duration) || duration <= 0)) {
            duration = rangeMinutes;
          }
        }
      }
      if (!Number.isFinite(duration) || duration <= 0) {
        return '';
      }
      if (duration >= 1440 && duration % 1440 === 0) {
        const days = duration / 1440;
        const unit = days === 1 ? this.i18n.day_unit : this.i18n.days_unit;
        return unit ? `${days} ${unit}` : String(days);
      }
      const hours = Math.floor(duration / 60);
      const mins = duration % 60;
      const hourLabel = this.i18n.hour_short || '';
      const minuteLabel = this.i18n.minute_short || '';
      if (hours > 0 && mins > 0) {
        return `${hours}${hourLabel} ${mins}${minuteLabel}`.trim();
      }
      if (hours > 0) {
        return `${hours}${hourLabel}`.trim();
      }
      return `${mins}${minuteLabel}`.trim();
    },
    detailItems() {
      const items = [];
      if (this.bookingStatusLabel) {
        items.push({ label: this.i18n.booking_detail_status, value: this.bookingStatusLabel });
      }
      if (this.booking.service_label) {
        items.push({ label: this.i18n.booking_detail_service, value: this.booking.service_label });
      }
      if (this.bookingDateLabel) {
        items.push({ label: this.i18n.booking_detail_date_time, value: this.bookingDateLabel });
      }
      if (this.bookingDurationLabel) {
        items.push({ label: this.i18n.booking_detail_duration, value: this.bookingDurationLabel });
      }
      if (this.booking.listing_title) {
        items.push({
          label: this.i18n.booking_detail_listing,
          value: this.booking.listing_title,
          url: this.withBookingAnchor(this.booking.listing_url || '')
        });
      }
      if (this.booking.listing_location) {
        items.push({ label: this.i18n.booking_detail_location, value: this.booking.listing_location });
      }
      if (this.showProvider) {
        if (this.booking.provider_name) {
          items.push({ label: this.i18n.booking_detail_provider, value: this.booking.provider_name });
        }
        if (this.booking.provider_email) {
          items.push({ label: this.i18n.booking_detail_provider_email, value: this.booking.provider_email });
        }
        if (this.booking.provider_phone) {
          items.push({ label: this.i18n.booking_detail_provider_phone, value: this.booking.provider_phone });
        }
      } else {
        if (this.booking.owner_name) {
          items.push({ label: this.i18n.owner_name, value: this.booking.owner_name });
        }
        if (this.booking.owner_email) {
          items.push({ label: this.i18n.email, value: this.booking.owner_email });
        }
        if (this.booking.customer_phone) {
          items.push({ label: this.i18n.phone_label, value: this.booking.customer_phone });
        }
      }
      if (this.booking.notes) {
        items.push({ label: this.i18n.booking_detail_notes, value: this.booking.notes, long: true });
      }
      if (this.booking.cancel_reason) {
        items.push({ label: this.i18n.cancel_reason_title, value: this.booking.cancel_reason, long: true });
      }
      return items;
    },
    policiesAvailable() {
      return window.BookaroData && Object.prototype.hasOwnProperty.call(window.BookaroData, 'policies');
    },
    policies() {
      return window.BookaroData?.policies || {};
    },
    cancelWindowHours() {
      const hours = Number(this.policies.cancel_window_hours ?? 0);
      return Number.isFinite(hours) ? hours : 0;
    },
    rescheduleWindowHours() {
      const hours = Number(this.policies.reschedule_window_hours ?? 0);
      return Number.isFinite(hours) ? hours : 0;
    },
    policyTitle() {
      return this.i18n.policy_title;
    },
    policyStatusLines() {
      return getPolicyStatusLines(this.booking);
    },
    paymentPolicyText() {
      return typeof this.policies?.payment_policy_text === 'string'
        ? this.policies.payment_policy_text.trim()
        : '';
    },
    depositPolicyText() {
      return typeof this.policies?.deposit_text === 'string'
        ? this.policies.deposit_text.trim()
        : '';
    },
    cancelFeePolicyText() {
      return typeof this.policies?.cancel_fee_text === 'string'
        ? this.policies.cancel_fee_text.trim()
        : '';
    },
    noShowFeePolicyText() {
      return typeof this.policies?.no_show_fee_text === 'string'
        ? this.policies.no_show_fee_text.trim()
        : '';
    },
    cancelPolicyText() {
      const custom = typeof this.policies?.cancel_text === 'string' ? this.policies.cancel_text.trim() : '';
      if (custom) {
        return this.applyPolicyTemplate(custom, this.cancelWindowHours);
      }
      if (this.cancelWindowHours > 0) {
        const template = this.i18n.policy_cancel_window;
        return template.replace('%d', String(this.cancelWindowHours));
      }
      return this.i18n.policy_cancel_anytime;
    },
    reschedulePolicyText() {
      const custom = typeof this.policies?.reschedule_text === 'string' ? this.policies.reschedule_text.trim() : '';
      if (custom) {
        return this.applyPolicyTemplate(custom, this.rescheduleWindowHours);
      }
      if (this.rescheduleWindowHours > 0) {
        const template = this.i18n.policy_reschedule_window;
        return template.replace('%d', String(this.rescheduleWindowHours));
      }
      return this.i18n.policy_reschedule_anytime;
    },
    policyLines() {
      if (!this.policiesAvailable) {
        return this.policyStatusLines;
      }
      return this.normalizePolicyLines([
        ...this.policyStatusLines,
        this.paymentPolicyText,
        this.depositPolicyText,
        this.cancelPolicyText,
        this.reschedulePolicyText,
        this.cancelFeePolicyText,
        this.noShowFeePolicyText
      ]);
    },
    statusTimelineTitle() {
      return this.i18n.status_timeline_title;
    },
    normalizedStatus() {
      const raw = (this.booking.status || '').toString().toLowerCase();
      return raw || 'pending';
    },
    timelineSteps() {
      const status = this.normalizedStatus;
      const requestedLabel = this.i18n.status_step_requested || this.i18n.pending;
      if (status === 'cancelled' || status === 'rejected' || status === 'no_show') {
        let terminalLabel = '';
        if (status === 'cancelled') {
          terminalLabel = this.i18n.status_step_cancelled || this.i18n.cancelled;
        } else if (status === 'rejected') {
          terminalLabel = this.i18n.status_step_rejected || this.i18n.rejected;
        } else {
          terminalLabel = this.i18n.status_step_no_show || this.i18n.no_show;
        }
        return [
          { key: 'pending', label: requestedLabel, state: 'complete' },
          { key: status, label: terminalLabel, state: 'terminal' }
        ];
      }

      const steps = [
        { key: 'pending', label: requestedLabel },
        { key: 'approved', label: this.i18n.status_step_confirmed || this.i18n.approved },
        { key: 'completed', label: this.i18n.status_step_completed || this.i18n.completed }
      ];
      const indexMap = { pending: 0, approved: 1, completed: 2 };
      const currentIndex = indexMap[status] ?? 0;
      return steps.map((step, idx) => ({
        ...step,
        state: idx < currentIndex ? 'complete' : (idx === currentIndex ? 'current' : 'upcoming')
      }));
    }
  },
  methods: {
    withBookingAnchor(url) {
      const raw = String(url || '').trim();
      if (!raw) {
        return '';
      }
      if (raw.includes('#')) {
        return raw;
      }
      return `${raw}#bookaro-booking-btn`;
    },
    applyPolicyTemplate(template, hours) {
      const raw = String(template || '').trim();
      if (!raw) {
        return '';
      }
      const hoursValue = Number.isFinite(Number(hours)) ? String(hours) : '0';
      return raw
        .replace(/{{\s*hours\s*}}/g, hoursValue)
        .replace(/{{\s*window_hours\s*}}/g, hoursValue)
        .replace(/{{\s*window\s*}}/g, hoursValue);
    },
    normalizePolicyLines(lines) {
      const unique = new Set();
      return (Array.isArray(lines) ? lines : [])
        .map((line) => String(line || '').trim())
        .filter((line) => {
          if (!line) {
            return false;
          }
          if (unique.has(line)) {
            return false;
          }
          unique.add(line);
          return true;
        });
    }
  }
};
</script>

<style scoped>
.details-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 16px;
}
.details-title {
  margin: 0;
  font-size: 1.75rem;
  font-weight: 700;
  color: #111827;
}
.details-section {
  border: 1px solid var(--bookaro-booking-slot_border, #e5e7eb);
  border-radius: 18px;
  padding: 16px 18px;
  background: var(--bookaro-booking-modal_bg, #fff);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.7);
}
.details-section-title {
  margin: 0 0 12px;
  font-size: 0.95rem;
  font-weight: 600;
  color: #111827;
}
.details-list {
  display: grid;
  gap: 10px;
}
.detail-row {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  align-items: flex-start;
}
.detail-label {
  font-size: 0.7rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: #64748b;
  margin-top: 2px;
}
.detail-value {
  font-weight: 600;
  color: #111827;
  text-align: right;
}
.detail-row a {
  color: var(--bookaro-dashboard-accent, #2563eb);
  text-decoration: none;
}
.detail-row a:hover {
  text-decoration: underline;
}
.detail-row--long {
  flex-direction: column;
  align-items: flex-start;
  gap: 4px;
}
.detail-row--long .detail-value {
  text-align: left;
  white-space: pre-wrap;
  font-weight: 500;
}
.details-policy-list {
  margin: 0;
  padding-left: 1rem;
  display: grid;
  gap: 6px;
  font-size: 0.85rem;
  color: #475569;
}
.status-timeline {
  list-style: none;
  margin: 0;
  padding: 0;
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.status-timeline::before {
  content: '';
  position: absolute;
  left: 16px;
  top: 4px;
  bottom: 4px;
  width: 2px;
  background: #e5e7eb;
}
.timeline-step {
  display: flex;
  align-items: center;
  gap: 12px;
  position: relative;
  color: #6b7280;
}
.timeline-marker {
  width: 18px;
  height: 18px;
  border-radius: 999px;
  background: #e5e7eb;
  border: 2px solid #e5e7eb;
  z-index: 1;
  flex-shrink: 0;
}
.timeline-label {
  font-size: 0.95rem;
  font-weight: 600;
  color: inherit;
}
.timeline-step.complete {
  color: #16a34a;
}
.timeline-step.current {
  color: #1f2937;
}
.timeline-step.upcoming {
  color: #9ca3af;
}
.timeline-step.complete .timeline-marker {
  background: #22c55e;
  border-color: #22c55e;
}
.timeline-step.current .timeline-marker {
  background: var(--bookaro-dashboard-accent, #3b82f6);
  border-color: var(--bookaro-dashboard-accent, #3b82f6);
  box-shadow: 0 0 0 4px rgba(var(--bookaro-dashboard-accent-rgb, 59, 130, 246), 0.2);
}
.timeline-step.terminal {
  color: #dc2626;
}
.timeline-step.terminal .timeline-marker {
  background: #ef4444;
  border-color: #ef4444;
}
</style>
