<script setup>
/**
 * Angebot (price quote) modal — opened from the partner edit page and the lead
 * edit page. Two internal steps:
 *  - edit:    customer data + assumptions + pricing (prefilled), with a live
 *             monthly forecast and volume-tier recommendations side panel
 *  - preview: server-rendered branded PDF in an iframe + email panel + send
 * Business math lives in composables/useOfferQuote.ts (client is the single
 * source of truth; the server only renders/sends what it receives).
 */
import sharedLang from '~/assets/langs/shared.js'

const props = defineProps({
  modelValue: {
    type: Boolean,
    default: false
  },
  // { source: 'partner'|'lead', recordId, recordUu?, company, contactName,
  //   email, phone, pricing?, storageQty? } — pricing null → pure list prices
  prefill: {
    type: Object,
    default: () => ({})
  }
})

const emit = defineEmits(['update:modelValue', 'sent'])

const language = useCookie('language')
const lang = computed(() => language.value || 'en-US')
const t = computed(() => sharedLang(lang.value))

const isOpen = computed({
  get: () => props.modelValue,
  set: (value) => emit('update:modelValue', value)
})

const step = ref('edit')
const form = ref(createQuoteForm(props.prefill))
const previewLoading = ref(false)
const sending = ref(false)
const sentOk = ref(false)
const errorMessage = ref('')
const attachWarning = ref('')
const pdfBase64 = ref('')
const pdfFilename = ref('')
const blobUrl = ref('')

const openSections = ref({
  customer: true,
  assumptions: true,
  fulfillment: true,
  storage: false,
  monthly: false,
  packaging: false
})
const toggleSection = (key) => { openSections.value[key] = !openSections.value[key] }

// Live calculator + recommendations
const forecast = computed(() => computeQuoteForecast(form.value))
const recommendations = computed(() => computeQuoteRecommendations(form.value))

const fmtEur = (v) => new Intl.NumberFormat(form.value.language === 'en' ? 'en-IE' : 'de-DE', { style: 'currency', currency: 'EUR' }).format(Number(v) || 0)

const forecastLabels = computed(() => ({
  fulfillment: `${t.value.quote_forecast_fulfillment || 'Fulfillment'} (${form.value.assumptions.ordersPerMonth || 0})`,
  returns: `${t.value.quote_forecast_returns || 'Retouren'} (~${form.value.assumptions.returnRatePct || 0} %)`,
  storage: t.value.quote_forecast_storage || 'Lagerung',
  serviceFee: t.value.quote_forecast_service_fee || 'Servicepauschale',
  packaging: `${t.value.quote_forecast_packaging || 'Verpackung'} (${String(form.value.assumptions.typicalCarton || 'm').toUpperCase()})`,
  shipping: t.value.quote_forecast_shipping || 'Versand (DHL, bis 2 kg)'
}))

const priceFieldLabels = computed(() => ({
  orderBaseprice: t.value.quote_order_baseprice || 'Basispreis pro Auftrag',
  orderPickprice: t.value.quote_pick_price || 'Preis pro Pick',
  returnBaseprice: t.value.quote_return_baseprice || 'Retoure Basispreis',
  returnPickprice: t.value.quote_return_pickprice || 'Retoure pro Artikel',
  hourlyRate: t.value.quote_hourly_rate || 'Stundensatz',
  monthlyFee: t.value.quote_monthly_fee || 'Servicepauschale',
  shelfSmallPrice: t.value.quote_shelf_small || 'Fachbodenregal M',
  shelfLargePrice: t.value.quote_shelf_large || 'Fachbodenregal L',
  palletPrice: t.value.quote_pallet_space || 'Palettenstellplatz'
}))

const applySuggestion = (s) => {
  form.value.pricing[s.field] = s.suggested
}

// Validation gates
const canPreview = computed(() =>
  String(form.value.customer.company).trim() !== '' && String(form.value.customer.contactName).trim() !== ''
)
const canSend = computed(() => /.+@.+\..+/.test(String(form.value.email.to).trim()))

// Email subject/message defaults follow the quote language; only overwrite
// values the user hasn't customized.
let lastEmailDefaults = { subject: '', message: '' }
const applyEmailDefaults = () => {
  const d = quoteEmailDefaults(
    form.value.language,
    form.value.customer.contactName,
    form.value.customer.company,
    form.value.meta.validDays
  )
  if (!form.value.email.subject || form.value.email.subject === lastEmailDefaults.subject) {
    form.value.email.subject = d.subject
  }
  if (!form.value.email.message || form.value.email.message === lastEmailDefaults.message) {
    form.value.email.message = d.message
  }
  lastEmailDefaults = d
}

// Re-seed on every open; lazily prefill the recipient from the partner's contacts
watch(() => props.modelValue, async (open) => {
  if (open) {
    step.value = 'edit'
    sentOk.value = false
    errorMessage.value = ''
    attachWarning.value = ''
    form.value = createQuoteForm(props.prefill)
    if (props.prefill?.source === 'partner' && !props.prefill?.email && props.prefill?.recordId) {
      try {
        const res = await $fetch(`/api/partners/partners/${props.prefill.recordId}/users`, {
          headers: useRequestHeaders(['cookie'])
        })
        const users = res?.records || res || []
        const withMail = Array.isArray(users) ? users.find((u) => u?.EMail) : null
        if (withMail && !form.value.email.to) {
          form.value.email.to = withMail.EMail
          form.value.customer.email = withMail.EMail
          if (!form.value.customer.contactName) form.value.customer.contactName = withMail.Name || ''
        }
      } catch { /* prefill only — recipient stays manually editable */ }
    }
  } else {
    revokeBlob()
  }
})

const revokeBlob = () => {
  if (blobUrl.value) {
    URL.revokeObjectURL(blobUrl.value)
    blobUrl.value = ''
  }
}

const base64ToBlobUrl = (b64) => {
  const bin = atob(b64)
  const bytes = new Uint8Array(bin.length)
  for (let i = 0; i < bin.length; i++) bytes[i] = bin.charCodeAt(i)
  return URL.createObjectURL(new Blob([bytes], { type: 'application/pdf' }))
}

const generatePreview = async () => {
  if (!canPreview.value || previewLoading.value) return
  previewLoading.value = true
  errorMessage.value = ''
  try {
    const payload = buildQuotePayload(form.value, forecast.value, false)
    const res = await $fetch('/api/offers/quote/preview', {
      method: 'POST',
      headers: useRequestHeaders(['cookie']),
      body: payload
    })
    if (Number(res?.status) === 200 && res?.pdfBase64) {
      pdfBase64.value = res.pdfBase64
      pdfFilename.value = res.filename
      revokeBlob()
      blobUrl.value = base64ToBlobUrl(res.pdfBase64)
      applyEmailDefaults()
      step.value = 'preview'
    } else {
      errorMessage.value = res?.message || t.value.quote_send_error || 'PDF generation failed'
    }
  } catch (err) {
    errorMessage.value = err?.data?.message || err?.message || 'PDF generation failed'
  }
  previewLoading.value = false
}

// Regenerate the preview when PDF-relevant toggles change while previewing
watch(() => [form.value.forecast.includeInPdf, form.value.language], () => {
  if (step.value === 'preview') {
    applyEmailDefaults()
    generatePreviewSilent()
  }
})

const generatePreviewSilent = async () => {
  previewLoading.value = true
  try {
    const payload = buildQuotePayload(form.value, forecast.value, false)
    const res = await $fetch('/api/offers/quote/preview', {
      method: 'POST',
      headers: useRequestHeaders(['cookie']),
      body: payload
    })
    if (Number(res?.status) === 200 && res?.pdfBase64) {
      pdfBase64.value = res.pdfBase64
      pdfFilename.value = res.filename
      revokeBlob()
      blobUrl.value = base64ToBlobUrl(res.pdfBase64)
    }
  } catch { /* keep the previous preview */ }
  previewLoading.value = false
}

const downloadPdf = () => {
  if (!blobUrl.value) return
  const a = document.createElement('a')
  a.href = blobUrl.value
  a.download = pdfFilename.value || 'Angebot_LogYou.pdf'
  document.body.appendChild(a)
  a.click()
  document.body.removeChild(a)
}

const sendQuote = async () => {
  if (!canSend.value || sending.value) return
  sending.value = true
  errorMessage.value = ''
  attachWarning.value = ''
  try {
    const payload = buildQuotePayload(form.value, forecast.value, true)
    const res = await $fetch('/api/offers/quote/send', {
      method: 'POST',
      headers: useRequestHeaders(['cookie']),
      body: payload
    })
    if (Number(res?.status) === 200) {
      sentOk.value = true
      if (res?.warning) attachWarning.value = res.warning
      emit('sent', res)
      setTimeout(() => {
        isOpen.value = false
      }, attachWarning.value ? 4000 : 1800)
    } else {
      errorMessage.value = res?.message || t.value.quote_send_error || 'Sending failed'
    }
  } catch (err) {
    errorMessage.value = err?.data?.message || err?.message || 'Sending failed'
  }
  sending.value = false
}

const handleClose = () => {
  if (sending.value || previewLoading.value) return
  isOpen.value = false
}

onBeforeUnmount(() => revokeBlob())
</script>

<template>
  <div class="modal-overlay" v-if="isOpen">
    <div class="modal-wrapper" @click.self="handleClose">
      <div class="modalContent quote-modal">
        <div class="modalHeader quote-header">
          <div class="quote-header-left">
            <img src="/assets/logyou-logo-color.png" alt="LogYou" class="quote-logo" />
            <h3 class="modalTitle">{{ t.create_quote || 'Angebot erstellen' }}</h3>
          </div>
          <div class="quote-header-right">
            <div class="quote-lang-toggle">
              <button type="button" :class="{ active: form.language === 'de' }" @click="form.language = 'de'">DE</button>
              <button type="button" :class="{ active: form.language === 'en' }" @click="form.language = 'en'">EN</button>
            </div>
            <div class="cursor-pointer" @click="handleClose">
              <span class="tf-icon ti ti-x ti-sm me-1"></span>
            </div>
          </div>
        </div>

        <!-- ==================== STEP: EDIT ==================== -->
        <div v-if="step === 'edit'" class="modalBody quote-body">
          <div class="quote-columns">
            <div class="quote-form-col">
              <!-- Kunde -->
              <div class="quote-section">
                <div class="quote-section-head" @click="toggleSection('customer')">
                  <span><i class="ti ti-user"></i> {{ t.quote_customer_section || 'Kunde' }}</span>
                  <i class="ti" :class="openSections.customer ? 'ti-chevron-up' : 'ti-chevron-down'"></i>
                </div>
                <div v-show="openSections.customer" class="quote-section-body">
                  <div class="columns is-multiline is-variable is-2">
                    <div class="column is-6">
                      <div class="field">
                        <label class="label">{{ t.quote_company || 'Firma' }} <span class="req">*</span></label>
                        <input class="input" v-model="form.customer.company" />
                      </div>
                    </div>
                    <div class="column is-6">
                      <div class="field">
                        <label class="label">{{ t.quote_contact_name || 'Ansprechpartner' }} <span class="req">*</span></label>
                        <input class="input" v-model="form.customer.contactName" />
                      </div>
                    </div>
                    <div class="column is-6">
                      <div class="field">
                        <label class="label">{{ t.quote_recipient_email || 'E-Mail' }}</label>
                        <input class="input" type="email" v-model="form.email.to" />
                      </div>
                    </div>
                    <div class="column is-6">
                      <div class="field">
                        <label class="label">{{ t.phone || 'Telefon' }}</label>
                        <input class="input" v-model="form.customer.phone" />
                      </div>
                    </div>
                    <div class="column is-12">
                      <div class="field">
                        <label class="label">{{ t.quote_street || 'Straße' }}</label>
                        <input class="input" v-model="form.customer.street" />
                      </div>
                    </div>
                    <div class="column is-3">
                      <div class="field">
                        <label class="label">{{ t.quote_zip || 'PLZ' }}</label>
                        <input class="input" v-model="form.customer.zip" />
                      </div>
                    </div>
                    <div class="column is-5">
                      <div class="field">
                        <label class="label">{{ t.quote_city || 'Stadt' }}</label>
                        <input class="input" v-model="form.customer.city" />
                      </div>
                    </div>
                    <div class="column is-4">
                      <div class="field">
                        <label class="label">{{ t.quote_country || 'Land' }}</label>
                        <input class="input" v-model="form.customer.country" />
                      </div>
                    </div>
                  </div>
                </div>
              </div>

              <!-- Annahmen -->
              <div class="quote-section">
                <div class="quote-section-head" @click="toggleSection('assumptions')">
                  <span><i class="ti ti-list-check"></i> {{ t.quote_assumptions_section || 'Annahmen' }}</span>
                  <i class="ti" :class="openSections.assumptions ? 'ti-chevron-up' : 'ti-chevron-down'"></i>
                </div>
                <div v-show="openSections.assumptions" class="quote-section-body">
                  <div class="columns is-multiline is-variable is-2">
                    <div class="column is-4">
                      <div class="field">
                        <label class="label">{{ t.quote_business_model || 'Geschäftsmodell' }}</label>
                        <div class="select is-fullwidth">
                          <select v-model="form.assumptions.businessModel">
                            <option value="B2C">B2C</option>
                            <option value="B2B">B2B</option>
                            <option value="B2C+B2B">B2C + B2B</option>
                          </select>
                        </div>
                      </div>
                    </div>
                    <div class="column is-4">
                      <div class="field">
                        <label class="label">{{ t.quote_planned_start || 'Geplanter Start' }}</label>
                        <input class="input" type="date" v-model="form.assumptions.plannedStart" />
                      </div>
                    </div>
                    <div class="column is-4">
                      <div class="field">
                        <label class="label">{{ t.quote_shop_system || 'Shopsystem' }}</label>
                        <input class="input" v-model="form.assumptions.shopSystem" placeholder="Shopify / JTL / ..." />
                      </div>
                    </div>
                    <div class="column is-3">
                      <div class="field">
                        <label class="label">{{ t.quote_orders_per_month || 'Aufträge / Monat' }}</label>
                        <input class="input" type="number" min="0" step="1" v-model.number="form.assumptions.ordersPerMonth" />
                      </div>
                    </div>
                    <div class="column is-3">
                      <div class="field">
                        <label class="label">{{ t.quote_avg_picks || 'Ø Picks / Auftrag' }}</label>
                        <input class="input" type="number" min="0" step="0.1" v-model.number="form.assumptions.avgPicksPerOrder" />
                      </div>
                    </div>
                    <div class="column is-3">
                      <div class="field">
                        <label class="label">{{ t.quote_sku_count || 'Artikel (SKUs)' }}</label>
                        <input class="input" type="number" min="0" step="1" v-model.number="form.assumptions.skuCount" />
                      </div>
                    </div>
                    <div class="column is-3">
                      <div class="field">
                        <label class="label">{{ t.quote_return_rate || 'Retourenquote %' }}</label>
                        <input class="input" type="number" min="0" max="100" step="0.5" v-model.number="form.assumptions.returnRatePct" />
                      </div>
                    </div>
                    <div class="column is-3">
                      <div class="field">
                        <label class="label">{{ t.quote_typical_carton || 'Typ. Karton' }}</label>
                        <div class="select is-fullwidth">
                          <select v-model="form.assumptions.typicalCarton">
                            <option value="s">S</option>
                            <option value="m">M</option>
                            <option value="l">L</option>
                            <option value="xl">XL</option>
                          </select>
                        </div>
                      </div>
                    </div>
                    <div class="column is-3">
                      <div class="field">
                        <label class="label">{{ t.quote_shelf_small || 'Fachboden M' }} ({{ t.quantity || 'Anzahl' }})</label>
                        <input class="input" type="number" min="0" step="1" v-model.number="form.assumptions.storage.shelfSmallQty" />
                      </div>
                    </div>
                    <div class="column is-3">
                      <div class="field">
                        <label class="label">{{ t.quote_shelf_large || 'Fachboden L' }} ({{ t.quantity || 'Anzahl' }})</label>
                        <input class="input" type="number" min="0" step="1" v-model.number="form.assumptions.storage.shelfLargeQty" />
                      </div>
                    </div>
                    <div class="column is-3">
                      <div class="field">
                        <label class="label">{{ t.quote_pallet_space || 'Paletten' }} ({{ t.quantity || 'Anzahl' }})</label>
                        <input class="input" type="number" min="0" step="1" v-model.number="form.assumptions.storage.palletQty" />
                      </div>
                    </div>
                    <div class="column is-3">
                      <div class="field">
                        <label class="label">{{ t.quote_volume_m3 || 'Volumen m³' }}</label>
                        <input class="input" type="number" min="0" step="0.5" v-model.number="form.assumptions.storage.volumeM3" />
                      </div>
                    </div>
                  </div>
                </div>
              </div>

              <!-- Preise Fulfillment & Retoure -->
              <div class="quote-section">
                <div class="quote-section-head" @click="toggleSection('fulfillment')">
                  <span><i class="ti ti-package"></i> {{ t.quote_pricing_fulfillment || 'Preise Fulfillment & Retoure' }}</span>
                  <i class="ti" :class="openSections.fulfillment ? 'ti-chevron-up' : 'ti-chevron-down'"></i>
                </div>
                <div v-show="openSections.fulfillment" class="quote-section-body">
                  <div class="columns is-multiline is-variable is-2">
                    <div class="column is-3">
                      <div class="field">
                        <label class="label">{{ t.quote_order_baseprice || 'Basispreis / Auftrag' }} €</label>
                        <input class="input" type="number" min="0" step="0.01" v-model.number="form.pricing.orderBaseprice" />
                      </div>
                    </div>
                    <div class="column is-3">
                      <div class="field">
                        <label class="label">{{ t.quote_pick_price || 'Preis / Pick' }} €</label>
                        <input class="input" type="number" min="0" step="0.01" v-model.number="form.pricing.orderPickprice" />
                      </div>
                    </div>
                    <div class="column is-3">
                      <div class="field">
                        <label class="label">{{ t.quote_pickfree || 'Picks frei' }}</label>
                        <input class="input" type="number" min="0" step="1" v-model.number="form.pricing.qtyPickfree" />
                      </div>
                    </div>
                    <div class="column is-3">
                      <div class="field">
                        <label class="label">{{ t.quote_customs_surcharge || 'Zoll-Zuschlag' }} €</label>
                        <input class="input" type="number" min="0" step="0.01" v-model.number="form.pricing.customsSurcharge" />
                      </div>
                    </div>
                    <div class="column is-3">
                      <div class="field">
                        <label class="label">{{ t.quote_return_baseprice || 'Retoure Basis' }} €</label>
                        <input class="input" type="number" min="0" step="0.01" v-model.number="form.pricing.returnBaseprice" />
                      </div>
                    </div>
                    <div class="column is-3">
                      <div class="field">
                        <label class="label">{{ t.quote_return_pickprice || 'Retoure / Artikel' }} €</label>
                        <input class="input" type="number" min="0" step="0.01" v-model.number="form.pricing.returnPickprice" />
                      </div>
                    </div>
                    <div class="column is-3">
                      <div class="field">
                        <label class="label">{{ t.quote_hourly_rate || 'Stundensatz' }} €/h</label>
                        <input class="input" type="number" min="0" step="0.5" v-model.number="form.pricing.hourlyRate" />
                      </div>
                    </div>
                    <div class="column is-3">
                      <div class="field">
                        <label class="label">{{ t.quote_pallet_move || 'Palette Ein-/Auslag.' }} €</label>
                        <input class="input" type="number" min="0" step="0.01" v-model.number="form.pricing.palletMovePrice" />
                      </div>
                    </div>
                  </div>
                </div>
              </div>

              <!-- Preise Lagerung + Monatliche Kosten -->
              <div class="quote-section">
                <div class="quote-section-head" @click="toggleSection('storage')">
                  <span><i class="ti ti-building-warehouse"></i> {{ t.quote_pricing_storage || 'Lagerung & Monatliche Kosten' }}</span>
                  <i class="ti" :class="openSections.storage ? 'ti-chevron-up' : 'ti-chevron-down'"></i>
                </div>
                <div v-show="openSections.storage" class="quote-section-body">
                  <div class="columns is-multiline is-variable is-2">
                    <div class="column is-3">
                      <div class="field">
                        <label class="label">{{ t.quote_shelf_small || 'Fachboden M' }} €/M.</label>
                        <input class="input" type="number" min="0" step="0.01" v-model.number="form.pricing.shelfSmallPrice" />
                      </div>
                    </div>
                    <div class="column is-3">
                      <div class="field">
                        <label class="label">{{ t.quote_shelf_large || 'Fachboden L' }} €/M.</label>
                        <input class="input" type="number" min="0" step="0.01" v-model.number="form.pricing.shelfLargePrice" />
                      </div>
                    </div>
                    <div class="column is-3">
                      <div class="field">
                        <label class="label">{{ t.quote_pallet_space || 'Palette' }} €/M.</label>
                        <input class="input" type="number" min="0" step="0.01" v-model.number="form.pricing.palletPrice" />
                      </div>
                    </div>
                    <div class="column is-3">
                      <div class="field">
                        <label class="label">{{ t.quote_volume_m3_price || 'Preis / m³' }} €/M.</label>
                        <input class="input" type="number" min="0" step="0.01" v-model.number="form.pricing.volumeM3Price" />
                      </div>
                    </div>
                    <div class="column is-3">
                      <div class="field">
                        <label class="label">{{ t.quote_monthly_fee || 'Servicepauschale' }} €/M.</label>
                        <input class="input" type="number" min="0" step="0.01" v-model.number="form.pricing.monthlyFee" />
                      </div>
                    </div>
                  </div>
                  <p v-if="form.source === 'partner'" class="quote-hint">
                    <i class="ti ti-info-circle"></i>
                    {{ t.quote_partner_prices_hint || 'Dauerhafte Preisänderungen bitte im Fulfillment-Tab des Partners pflegen.' }}
                  </p>
                </div>
              </div>

              <!-- Verpackung & Versand -->
              <div class="quote-section">
                <div class="quote-section-head" @click="toggleSection('packaging')">
                  <span><i class="ti ti-box"></i> {{ t.quote_pricing_packaging || 'Verpackung & Versand' }}</span>
                  <i class="ti" :class="openSections.packaging ? 'ti-chevron-up' : 'ti-chevron-down'"></i>
                </div>
                <div v-show="openSections.packaging" class="quote-section-body">
                  <table class="table is-narrow is-fullwidth quote-mini-table">
                    <thead>
                      <tr>
                        <th>{{ t.quote_carton_size || 'Karton' }}</th>
                        <th class="has-text-right">{{ t.quote_carton_price || 'Preis' }} €</th>
                        <th class="has-text-right">{{ t.quote_paper_price || 'Packpapier' }} €</th>
                      </tr>
                    </thead>
                    <tbody>
                      <tr v-for="size in ['s', 'm', 'l', 'xl']" :key="size">
                        <td class="quote-size-label">{{ size.toUpperCase() }}</td>
                        <td><input class="input is-small has-text-right" type="number" min="0" step="0.01" v-model.number="form.pricing.cartons[size].price" /></td>
                        <td><input class="input is-small has-text-right" type="number" min="0" step="0.01" v-model.number="form.pricing.cartons[size].paper" /></td>
                      </tr>
                      <tr>
                        <td class="quote-size-label">{{ t.quote_einwegpalette || 'Einwegpalette' }}</td>
                        <td><input class="input is-small has-text-right" type="number" min="0" step="0.01" v-model.number="form.pricing.einwegpalettePrice" /></td>
                        <td></td>
                      </tr>
                    </tbody>
                  </table>
                  <table class="table is-narrow is-fullwidth quote-mini-table">
                    <thead>
                      <tr>
                        <th>{{ t.quote_dhl_tiers || 'DHL National' }}</th>
                        <th class="has-text-right">€</th>
                      </tr>
                    </thead>
                    <tbody>
                      <tr v-for="(tierLabel, tierKey) in { kg1: '≤ 1 kg', kg2: '≤ 2 kg', kg5: '≤ 5 kg', kg10: '≤ 10 kg', kg20: '≤ 20 kg', kg30: '≤ 31,5 kg' }" :key="tierKey">
                        <td class="quote-size-label">{{ tierLabel }}</td>
                        <td><input class="input is-small has-text-right" type="number" min="0" step="0.01" v-model.number="form.pricing.dhlTiers[tierKey]" /></td>
                      </tr>
                    </tbody>
                  </table>
                  <div class="field">
                    <label class="label">{{ t.quote_spedition_note || 'Speditionsversand' }}</label>
                    <input class="input" v-model="form.pricing.speditionNote" :placeholder="form.language === 'en' ? 'daily rate on request' : 'Tagespreis auf Anfrage'" />
                  </div>
                </div>
              </div>
            </div>

            <!-- ===== Sticky side panel: forecast + recommendations ===== -->
            <div class="quote-side-col">
              <div class="quote-forecast-card">
                <div class="quote-forecast-title">
                  <i class="ti ti-calculator"></i> {{ t.quote_forecast_title || 'Monatliche Prognose' }}
                </div>
                <div v-for="line in forecast.lines" :key="line.key" class="quote-forecast-line">
                  <span>{{ forecastLabels[line.key] }}</span>
                  <span>{{ fmtEur(line.monthly) }}</span>
                </div>
                <div class="quote-forecast-total">
                  <span>{{ t.quote_forecast_total || 'Gesamt / Monat' }}</span>
                  <span>{{ fmtEur(forecast.totalMonthly) }}</span>
                </div>
                <div class="quote-forecast-line quote-forecast-perorder">
                  <span>{{ t.quote_forecast_per_order || 'Effektiv pro Auftrag' }}</span>
                  <span>{{ fmtEur(forecast.perOrder) }}</span>
                </div>
              </div>

              <div class="quote-reco-card" v-if="recommendations.suggestions.length || recommendations.warnings.length">
                <div class="quote-reco-title">
                  <i class="ti ti-bulb"></i> {{ t.quote_recommendations_title || 'Empfehlungen' }}
                </div>
                <div v-for="s in recommendations.suggestions" :key="s.field" class="quote-reco-line">
                  <div class="quote-reco-text">
                    <strong>{{ priceFieldLabels[s.field] }}</strong><br />
                    {{ fmtEur(s.current) }} → <strong>{{ fmtEur(s.suggested) }}</strong>
                    <span class="quote-reco-reason">({{ s.orders }} {{ t.quote_orders_short || 'Auftr./Monat' }})</span>
                  </div>
                  <button type="button" class="button is-small quote-apply-btn" @click="applySuggestion(s)">
                    {{ t.quote_apply_suggestion || 'Übernehmen' }}
                  </button>
                </div>
                <div v-for="w in recommendations.warnings" :key="'w-' + w.field" class="quote-warning-chip">
                  <i class="ti ti-alert-triangle"></i>
                  {{ priceFieldLabels[w.field] }} {{ fmtEur(w.current) }} — {{ t.quote_below_list_warning || 'unter Listenpreis' }} ({{ fmtEur(w.floor) }})
                </div>
              </div>
            </div>
          </div>
        </div>

        <!-- ==================== STEP: PREVIEW ==================== -->
        <div v-else class="modalBody quote-body quote-preview-body">
          <div class="quote-preview-columns">
            <div class="quote-preview-frame">
              <div v-if="previewLoading" class="quote-preview-loading">
                <i class="ti ti-loader-2 quote-spin"></i>
              </div>
              <iframe v-else-if="blobUrl" :src="blobUrl" title="PDF"></iframe>
            </div>
            <div class="quote-email-panel">
              <div class="field">
                <label class="label">{{ t.quote_recipient_email || 'Empfänger' }} <span class="req">*</span></label>
                <input class="input" type="email" v-model="form.email.to" />
                <p v-if="!canSend" class="help is-danger">{{ t.quote_validation_email || 'Empfänger-E-Mail erforderlich' }}</p>
              </div>
              <div class="field">
                <label class="label">{{ t.quote_cc_label || 'CC' }}</label>
                <input class="input" v-model="form.email.cc" />
              </div>
              <div class="field">
                <label class="label">{{ t.quote_email_subject_label || 'Betreff' }}</label>
                <input class="input" v-model="form.email.subject" />
              </div>
              <div class="field">
                <label class="label">{{ t.quote_email_message_label || 'Nachricht' }}</label>
                <textarea class="textarea" rows="9" v-model="form.email.message"></textarea>
              </div>
              <label class="checkbox quote-include-forecast">
                <input type="checkbox" v-model="form.forecast.includeInPdf" />
                {{ t.quote_forecast_include_pdf || 'Kalkulations-Prognose im PDF anzeigen' }}
              </label>
              <div v-if="sentOk" class="notification is-success is-light quote-sent-note">
                <i class="ti ti-circle-check"></i> {{ t.quote_send_success || 'Angebot versendet & angehängt' }}
                <div v-if="attachWarning" class="quote-attach-warning">{{ attachWarning }}</div>
              </div>
            </div>
          </div>
        </div>

        <div class="modalFooter quote-footer">
          <div v-if="errorMessage" class="quote-error">
            <i class="ti ti-alert-circle"></i> {{ errorMessage }}
          </div>
          <div class="buttons">
            <template v-if="step === 'edit'">
              <button type="button" class="button" @click="handleClose">{{ t.cancel || 'Abbrechen' }}</button>
              <button
                type="button"
                class="button is-primary"
                :disabled="!canPreview || previewLoading"
                :title="!canPreview ? (t.quote_required_fields_hint || 'Firma und Ansprechpartner sind Pflichtfelder') : ''"
                @click="generatePreview"
              >
                <i class="ti" :class="previewLoading ? 'ti-loader-2 quote-spin' : 'ti-eye'"></i>&nbsp;
                {{ t.quote_preview_button || 'Vorschau ansehen' }}
              </button>
            </template>
            <template v-else>
              <button type="button" class="button" :disabled="sending" @click="step = 'edit'">
                <i class="ti ti-arrow-left"></i>&nbsp;{{ t.quote_back_edit || 'Zurück bearbeiten' }}
              </button>
              <button type="button" class="button" :disabled="!blobUrl" @click="downloadPdf">
                <i class="ti ti-download"></i>&nbsp;{{ t.quote_download_pdf || 'Nur PDF herunterladen' }}
              </button>
              <button
                type="button"
                class="button is-primary"
                :disabled="!canSend || sending || sentOk"
                @click="sendQuote"
              >
                <i class="ti" :class="sending ? 'ti-loader-2 quote-spin' : 'ti-send'"></i>&nbsp;
                {{ t.quote_send_button || 'Senden & anhängen' }}
              </button>
            </template>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<style scoped>
.modal-overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  width: 100vw;
  height: 100vh;
  background-color: rgba(0, 0, 0, 0.5);
  z-index: 9999;
  display: flex;
  align-items: center;
  justify-content: center;
}

.modal-wrapper {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
}

.quote-modal {
  max-width: 1150px;
  width: 100%;
  max-height: 92vh;
  display: flex;
  flex-direction: column;
  background: var(--theme-bg-primary, #fff);
  border-radius: 10px;
  overflow: hidden;
}

.quote-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 20px;
  border-bottom: 3px solid #f15924;
  background: var(--theme-bg-primary, #fff);
}

.quote-header-left {
  display: flex;
  align-items: center;
  gap: 14px;
}

.quote-logo {
  height: 26px;
  width: auto;
}

.quote-header-right {
  display: flex;
  align-items: center;
  gap: 16px;
}

.quote-lang-toggle {
  display: flex;
  border: 1px solid #d5dbe1;
  border-radius: 6px;
  overflow: hidden;
}

.quote-lang-toggle button {
  border: none;
  background: transparent;
  padding: 4px 12px;
  cursor: pointer;
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--theme-text-primary, #33414e);
}

.quote-lang-toggle button.active {
  background: #1c324b;
  color: #fff;
}

.quote-body {
  flex: 1;
  overflow: hidden;
  padding: 0;
}

.quote-columns {
  display: flex;
  gap: 0;
  height: 100%;
  max-height: calc(92vh - 128px);
}

.quote-form-col {
  flex: 1 1 62%;
  overflow-y: auto;
  padding: 16px 20px;
}

.quote-side-col {
  flex: 1 1 38%;
  max-width: 400px;
  overflow-y: auto;
  padding: 16px 20px 16px 0;
}

.quote-section {
  border: 1px solid var(--theme-border, #e3e7ec);
  border-radius: 8px;
  margin-bottom: 12px;
  overflow: hidden;
}

.quote-section-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 14px;
  cursor: pointer;
  font-weight: 600;
  color: #1c324b;
  background: var(--theme-bg-secondary, #f6f8fa);
  user-select: none;
}

.quote-section-head span i {
  color: #f15924;
  margin-right: 6px;
}

.quote-section-body {
  padding: 14px;
}

.req {
  color: #f15924;
}

.quote-hint {
  font-size: 0.78rem;
  color: var(--theme-text-secondary, #5a6b7c);
  margin-top: 4px;
}

.quote-hint i {
  color: #f15924;
}

.quote-mini-table td,
.quote-mini-table th {
  vertical-align: middle;
  font-size: 0.82rem;
}

.quote-mini-table .input.is-small {
  max-width: 110px;
  margin-left: auto;
}

.quote-size-label {
  font-weight: 600;
  white-space: nowrap;
}

/* Forecast card */
.quote-forecast-card {
  background: #1c324b;
  color: #fff;
  border-radius: 10px;
  padding: 16px;
  position: sticky;
  top: 0;
}

/* Explicit white on every descendant — global/theme text rules must not
   darken the card's content against the navy background. */
.quote-forecast-card,
.quote-forecast-card span,
.quote-forecast-card div {
  color: #ffffff;
}

.quote-forecast-title {
  font-weight: 700;
  font-size: 0.95rem;
  margin-bottom: 10px;
}

.quote-forecast-title i {
  color: #f15924;
}

.quote-forecast-line {
  display: flex;
  justify-content: space-between;
  font-size: 0.82rem;
  padding: 3px 0;
}

.quote-forecast-total {
  display: flex;
  justify-content: space-between;
  font-weight: 700;
  font-size: 1.02rem;
  border-top: 1px solid rgba(255, 255, 255, 0.25);
  margin-top: 8px;
  padding-top: 8px;
}

.quote-forecast-total,
.quote-forecast-total span {
  color: #f15924;
}

.quote-forecast-perorder {
  font-weight: 600;
}

/* Recommendations card */
.quote-reco-card {
  border: 1px solid var(--theme-border, #e3e7ec);
  border-radius: 10px;
  padding: 14px;
  margin-top: 12px;
}

.quote-reco-title {
  font-weight: 700;
  color: #1c324b;
  margin-bottom: 8px;
  font-size: 0.9rem;
}

.quote-reco-title i {
  color: #f15924;
}

.quote-reco-line {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 7px 0;
  border-bottom: 1px dashed var(--theme-border, #e3e7ec);
  font-size: 0.8rem;
}

.quote-reco-line:last-of-type {
  border-bottom: none;
}

.quote-reco-reason {
  color: var(--theme-text-secondary, #5a6b7c);
  font-size: 0.72rem;
}

.quote-apply-btn {
  background: #f15924;
  color: #fff;
  border: none;
}

.quote-apply-btn:hover {
  background: #d94b1a;
  color: #fff;
}

.quote-warning-chip {
  background: #fdeee7;
  color: #b23c11;
  border-radius: 6px;
  padding: 6px 10px;
  font-size: 0.75rem;
  margin-top: 6px;
}

/* Preview step */
.quote-preview-body {
  padding: 0;
}

.quote-preview-columns {
  display: flex;
  height: 100%;
  max-height: calc(92vh - 128px);
}

.quote-preview-frame {
  flex: 1 1 60%;
  background: #4a5568;
  position: relative;
  min-height: 400px;
}

.quote-preview-frame iframe {
  width: 100%;
  height: 100%;
  border: none;
  display: block;
}

.quote-preview-loading {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  font-size: 2rem;
}

.quote-email-panel {
  flex: 1 1 40%;
  max-width: 420px;
  overflow-y: auto;
  padding: 16px 20px;
}

.quote-include-forecast {
  display: block;
  font-size: 0.85rem;
  margin: 6px 0 10px;
}

.quote-sent-note {
  margin-top: 10px;
  font-size: 0.85rem;
}

.quote-attach-warning {
  font-size: 0.75rem;
  margin-top: 4px;
  color: #946c00;
}

/* Footer */
.quote-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 20px;
  border-top: 1px solid var(--theme-border, #e3e7ec);
}

.quote-footer .buttons {
  margin-left: auto;
  margin-bottom: 0;
}

.quote-error {
  color: #cc0f35;
  font-size: 0.82rem;
}

.quote-spin {
  display: inline-block;
  animation: quote-rotate 1s linear infinite;
}

@keyframes quote-rotate {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}

@media (max-width: 900px) {
  /* Fullscreen modal; the body scrolls as ONE column while header/footer stay fixed. */
  .modal-wrapper {
    padding: 0;
    align-items: stretch;
  }

  .quote-modal {
    height: 100vh;
    height: 100dvh;
    max-height: 100vh;
    max-height: 100dvh;
    border-radius: 0;
  }

  .quote-body {
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
  }

  .quote-columns,
  .quote-preview-columns {
    flex-direction: column;
    height: auto;
    max-height: none;
  }

  /* Inner columns stop scrolling themselves — the body scrolls instead. */
  .quote-form-col,
  .quote-side-col,
  .quote-email-panel {
    flex: none;
    max-width: none;
    overflow-y: visible;
  }

  .quote-side-col {
    padding: 0 20px 16px;
  }

  .quote-forecast-card {
    position: static;
  }

  .quote-preview-frame {
    flex: none;
    min-height: 65vh;
  }

  .quote-preview-frame iframe {
    height: 65vh;
  }

  .quote-footer {
    flex-wrap: wrap;
  }
}
</style>
