<script setup>
import { toast } from 'bulma-toast'

// Full quick-add order flow (same as /pages/partners/partners/add.vue) rendered
// inside a large modal. Logic kept aligned with that page so behaviour matches.

const props = defineProps({
  modelValue: { type: Boolean, default: false }
})
const emit = defineEmits(['update:modelValue', 'created'])

const config = useRuntimeConfig()
const router = useRouter()
const activeSave = useActiveSave()

const organization = useCookie('logship_organization')
const organizationId = useCookie('logship_organization_id')
const user = useCookie('logship_user')
const userId = useCookie('logship_user_id')

const open = computed(() => !!props.modelValue)
const close = () => {
  if (form.value?.alert?.processing) return
  emit('update:modelValue', false)
}

const orgDefaults = ref({})
const ready = ref(false)

const loadDefaults = async () => {
  orgDefaults.value = {}
  // Use the dedicated /org-defaults endpoint — it resolves the org's linked
  // c_bpartner using a service token, which is required for limited / customer
  // roles that can't read c_bpartner directly.
  if (organizationId.value) {
    try {
      const response = await $fetch('/api/partners/partners/org-defaults', {
        method: 'GET',
        headers: useRequestHeaders(['cookie']),
        query: { orgId: organizationId.value }
      })
      if (response?.status === 200 && response?.defaults) {
        orgDefaults.value = response.defaults
        console.log('[OrderQuickAddModal] org defaults:', orgDefaults.value)
      } else {
        console.warn('[OrderQuickAddModal] org-defaults returned no defaults', response)
      }
    } catch (error) {
      console.error('[OrderQuickAddModal] Error fetching org defaults:', error)
    }
  }
  resetForms()
  ready.value = true
}

const form = ref(null)
const form2 = ref(null)
const form3 = ref(null)
const form4 = ref(null)

const resetForms = () => {
  form.value = {
    id: '', uid: '', client: '', clientId: '',
    organization: organization.value?.Name || '',
    organizationId: organizationId.value || '',
    name: '', name2: '', value: '',
    isActive: true, isSummary: false,
    isVendor: false,
    isCustomer: config.public.iscustomer ?? false,
    isProspect: false,
    isEmployee: false, isSalesRep: false, isOneTime: false,
    isTaxExempt: false, isDiscountPrinted: false,
    sendEMail: false, EMail: '',
    totalOpenBalance: 0,
    isPOTaxExempt: false, isManufacturer: false, is1099Vendor: false,
    poReference: '', referenceNo: '', rating: '',
    taxID: '', URL: '', NAICS: '', DUNS: '',
    documentCopies: 0, soDescription: '',
    flatDiscount: 0, shelfLifeMinPct: 0,
    isFulfillmentCustomer: false,
    deliveryRule: '', deliveryRuleId: '',
    deliveryViaRule: '', deliveryViaRuleId: '',
    invoiceSchedule: '', invoiceScheduleId: '',
    greeting: '', greetingId: '',
    printFormat: '', printFormatId: '',
    salesRep: user.value?.Name ?? '',
    salesRepId: user.value?.id ?? userId.value ?? '',
    invoiceRule: '', invoiceRuleId: '',
    paymentRule: '', paymentRuleId: '',
    paymentRulePO: '', paymentRulePOId: '',
    soCreditStatus: '', soCreditStatusId: '',
    partnerGroup: config.public.partnergroupvalue ?? 'Standard',
    partnerGroupId: config.public.partnergroupid ?? '103',
    priceList: orgDefaults.value.priceList || config.public.pricelistvalue || 'Standard',
    priceListId: orgDefaults.value.priceListId || config.public.pricelistid || '101',
    poPriceList: '', poPriceListId: '',
    discountSchema: '', discountSchemaId: '',
    poDiscountSchema: '', poDiscountSchemaId: '',
    paymentTerm: '', paymentTermId: '',
    poPaymentTerm: '', poPaymentTermId: '',
    languageId: 'en_US',
    dunning: '', dunningId: '',
    orderSource: orgDefaults.value.orderSource || '',
    orderSourceId: orgDefaults.value.orderSourceId || '',
    processing: false,
    alert: { status: '', message: '', processing: false }
  }

  const baseLocation = {
    id: '', uid: '', client: '', clientId: '',
    organization: organization.value?.Name || '',
    organizationId: organizationId.value || '',
    isActive: true,
    address1: '', address2: '', address3: '', address4: '',
    city: '', postal: '', regionName: '',
    isValid: true,
    country: config.public.countryvalue ?? 'Germany',
    countryId: config.public.countryid ?? '101',
    region: '', regionId: '',
    alert: { status: '', message: '', processing: false }
  }
  form2.value = { ...baseLocation }
  form3.value = { ...baseLocation }

  form4.value = {
    id: '', uid: '', client: '', clientId: '',
    organization: organization.value?.Name || '',
    organizationId: organizationId.value || '',
    docTypeTarget: config.public.doctypevalue ?? 'Standard Order',
    docTypeTargetId: config.public.doctypeid ?? '132',
    warehouse: '', warehouseId: '',
    priceList: orgDefaults.value.priceList || config.public.pricelistvalue || 'Standard',
    priceListId: orgDefaults.value.priceListId || config.public.pricelistid || '101',
    currency: '', currencyId: '',
    user: user.value?.Name ?? '',
    userId: user.value?.id ?? userId.value ?? '',
    orderSource: orgDefaults.value.orderSource || '',
    orderSourceId: orgDefaults.value.orderSourceId || '',
    deliveryViaRule: orgDefaults.value.deliveryViaRule || '',
    deliveryViaRuleId: orgDefaults.value.deliveryViaRuleId || '',
    shipper: orgDefaults.value.shipper || '',
    shipperId: orgDefaults.value.shipperId || ''
  }

  lines.value = []
}

const lines = ref([])

const save = async (record) => {
  form.value = record.partner
  form2.value = record.ship
  form3.value = record.bill
  form4.value = record.order
  activeSave.value = form.value?.name !== ''
}

const saveLines = async (orderLines) => {
  lines.value = orderLines
}

const tab = ref('partner')

const submit = async () => {
  if (!canSubmit.value) return

  // FBA relabel: every product line needs its printLabelCode before submit —
  // the server would otherwise leave the auto-completed order in Draft.
  if (form4.value?.isRelabelByFulfillmentProvider === true) {
    const missingCodes = (lines.value || []).filter(l => l?.productId && !String(l?.printLabelCode || '').trim())
    if (missingCodes.length) {
      toast({
        message: 'FBA-Relabel: Etiketten-Code fehlt auf Position(en): ' + missingCodes.map(l => `#${l?.line || '?'}`).join(', '),
        type: 'is-danger',
        duration: 5000
      })
      return
    }
  }

  form.value.alert.processing = true
  activeSave.value = true

  try {
    const res = await $fetch('/api/partners/partners/quick-add', {
      method: 'POST',
      headers: useRequestHeaders(['cookie']),
      body: {
        partner: form.value,
        ship: form2.value,
        bill: form3.value,
        order: form4.value,
        lines: lines.value
      }
    })

    if (Number(res.status) === 200) {
      if (res?.orderWarning) {
        toast({ message: res.orderWarning, type: 'is-warning', duration: 6000 })
      }
      toast({ message: 'Saved!', type: 'is-success', duration: 2000 })
      emit('created', res)
      emit('update:modelValue', false)
      activeSave.value = false
      if (res?.partner?.id) {
        router.push('/partners/partners/' + res.partner.id + '/edit')
      }
    } else {
      toast({ message: res?.message || 'Save error', type: 'is-danger', duration: 2500 })
    }
  } catch (err) {
    toast({ message: err?.message || 'Save error', type: 'is-danger', duration: 2500 })
  } finally {
    if (form.value) form.value.alert.processing = false
  }
}

// Lifecycle: load defaults only when the modal opens; block body scroll; ESC to close
watch(open, (isOpen) => {
  if (typeof document !== 'undefined') {
    document.body.style.overflow = isOpen ? 'hidden' : ''
  }
  if (isOpen) {
    ready.value = false
    loadDefaults()
  }
})

const onKeydown = (e) => {
  if (!open.value) return
  if (e.key === 'Escape') close()
  // Ctrl/Cmd + Enter submits
  else if ((e.ctrlKey || e.metaKey) && e.key === 'Enter') {
    e.preventDefault()
    submit()
  }
}

onMounted(() => { if (typeof document !== 'undefined') document.addEventListener('keydown', onKeydown) })
onUnmounted(() => {
  if (typeof document !== 'undefined') {
    document.removeEventListener('keydown', onKeydown)
    document.body.style.overflow = ''
  }
})

const canSubmit = computed(() =>
  !!form.value &&
  String(form.value.name || '').trim() !== '' &&
  String(form.value.EMail || '').trim() !== '' &&
  String(form4.value?.deliveryViaRuleId ?? '') !== '' &&
  !form.value.alert.processing
)

// Track which required field is still missing so the user gets a targeted hint
const missingField = computed(() => {
  if (!form.value) return null
  if (!String(form.value.name || '').trim()) return 'Name'
  if (!String(form.value.EMail || '').trim()) return 'E-Mail'
  if (!String(form4.value?.deliveryViaRuleId ?? '')) return 'Versandart'
  return null
})
</script>

<template>
  <Teleport to="body">
    <Transition name="oqa-fade">
      <div v-if="open" class="oqa-overlay" @click.self="close">
        <Transition name="oqa-slide" appear>
          <div v-if="open" class="oqa-card" role="dialog" aria-modal="true" aria-labelledby="oqa-title">
            <!-- Header -->
            <header class="oqa-head">
              <div class="oqa-head-body">
                <span class="oqa-head-badge"><i class="ti ti-shopping-cart-plus"></i></span>
                <div class="oqa-head-text">
                  <h3 id="oqa-title" class="oqa-title">Auftrag erstellen</h3>
                  <p class="oqa-subtitle">
                    <span class="oqa-subtitle-part">Partner &amp; Auftrag in einem Schritt anlegen</span>
                    <span class="oqa-chip oqa-chip--org" v-if="organization?.Name"><i class="ti ti-building"></i>{{ organization.Name }}</span>
                  </p>
                </div>
              </div>
              <button class="oqa-close" @click="close" title="Schließen" :disabled="form?.alert?.processing" aria-label="Close">
                <i class="ti ti-x"></i>
              </button>
            </header>

            <!-- Body (scrollable) -->
            <section class="oqa-body">
              <div v-if="!ready" class="oqa-loading">
                <i class="ti ti-loader-2 spin"></i>
                <span>Lade…</span>
              </div>
              <template v-else>
                <PartnersPartnerQuickForm
                  v-model="form"
                  v-model:tab="tab"
                  :order-defaults="orgDefaults"
                  @save="save"
                />
                <PartnersPartnerOrderLineTable
                  v-model="lines"
                  action="create"
                  :info="form4"
                  @save="saveLines"
                />
              </template>
            </section>

            <!-- Sticky action bar -->
            <footer class="oqa-foot">
              <div class="oqa-foot-left">
                <span v-if="missingField" class="oqa-hint oqa-hint--warn">
                  <i class="ti ti-alert-circle"></i>
                  Fehlt: <strong>{{ missingField }}</strong>
                </span>
                <span v-else-if="ready" class="oqa-hint oqa-hint--ok">
                  <i class="ti ti-circle-check"></i>
                  Bereit zum Speichern
                </span>
              </div>
              <div class="oqa-foot-right">
                <span class="oqa-kbd" title="Tastenkürzel">
                  <span class="oqa-kbd-key">Ctrl</span>
                  <span class="oqa-kbd-sep">+</span>
                  <span class="oqa-kbd-key">Enter</span>
                </span>
                <button type="button" class="oqa-btn oqa-btn--ghost" @click="close" :disabled="form?.alert?.processing">
                  Abbrechen
                </button>
                <button
                  type="button"
                  class="oqa-btn oqa-btn--primary"
                  :disabled="!canSubmit"
                  @click="submit"
                >
                  <i v-if="form?.alert?.processing" class="ti ti-loader-2 spin"></i>
                  <i v-else class="ti ti-device-floppy"></i>
                  <span>{{ form?.alert?.processing ? 'Speichern…' : 'Speichern' }}</span>
                </button>
              </div>
            </footer>
          </div>
        </Transition>
      </div>
    </Transition>
  </Teleport>
</template>

<style scoped>
.oqa-overlay {
  position: fixed; inset: 0;
  background: rgba(15, 23, 42, 0.58);
  backdrop-filter: blur(4px);
  display: flex; align-items: stretch; justify-content: center;
  z-index: 9998;
  padding: 24px;
}

.oqa-card {
  width: 100%;
  max-width: 1280px;
  display: flex; flex-direction: column;
  background: var(--theme-bg-primary, #fff);
  border-radius: 16px;
  overflow: hidden;
  box-shadow: 0 24px 72px rgba(15, 23, 42, 0.4);
  border: 1px solid var(--theme-border, rgba(255, 255, 255, 0.06));
}

/* Header */
.oqa-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; padding: 16px 24px;
  background:
    radial-gradient(1200px 120px at 0% 0%, rgba(16, 185, 129, 0.18), transparent 60%),
    linear-gradient(to right, #ecfdf5, transparent 70%);
  border-bottom: 1px solid var(--theme-border, #e5e7eb);
  flex-shrink: 0;
}
.oqa-head-body { display: flex; align-items: center; gap: 14px; min-width: 0; }
.oqa-head-badge {
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; flex-shrink: 0;
  border-radius: 12px;
  background: linear-gradient(135deg, #10b981, #059669);
  color: #fff; font-size: 22px;
  box-shadow: 0 6px 14px rgba(16, 185, 129, 0.35);
}
.oqa-head-text { min-width: 0; }
.oqa-title { margin: 0; font-size: 19px; font-weight: 700; color: var(--theme-text-primary, #0f172a); letter-spacing: -0.01em; }
.oqa-subtitle {
  margin: 3px 0 0 0;
  display: flex; align-items: center; gap: 10px;
  font-size: 13px; color: var(--theme-text-secondary, #64748b);
}
.oqa-subtitle-part { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.oqa-chip {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 2px 10px; border-radius: 999px;
  font-size: 11.5px; font-weight: 600;
  border: 1px solid transparent;
  white-space: nowrap;
}
.oqa-chip i { font-size: 13px; }
.oqa-chip--org { background: #eff6ff; color: #1d4ed8; border-color: #bfdbfe; }

.oqa-close {
  display: inline-flex; align-items: center; justify-content: center;
  width: 36px; height: 36px;
  background: var(--theme-bg-primary, rgba(255, 255, 255, 0.7));
  border: 1.5px solid var(--theme-border, #e2e8f0);
  border-radius: 10px;
  color: var(--theme-text-secondary, #64748b);
  cursor: pointer; flex-shrink: 0;
  font-size: 16px;
  transition: all 0.15s;
}
.oqa-close:hover:not(:disabled) {
  border-color: #ef4444; color: #ef4444;
  background: #fef2f2;
}
.oqa-close:disabled { opacity: 0.5; cursor: not-allowed; }

/* Body */
.oqa-body {
  flex: 1; min-height: 0;
  overflow-y: auto;
  padding: 20px 24px;
  background: var(--theme-bg-secondary, #f8fafc);
  scroll-behavior: smooth;
}
.oqa-body::-webkit-scrollbar { width: 10px; }
.oqa-body::-webkit-scrollbar-thumb { background: #cbd5e1; border-radius: 6px; border: 2px solid var(--theme-bg-secondary, #f8fafc); }
.oqa-body::-webkit-scrollbar-thumb:hover { background: #94a3b8; }

.oqa-loading {
  display: flex; align-items: center; justify-content: center; gap: 10px;
  padding: 80px 20px;
  color: var(--theme-text-secondary, #64748b);
  font-size: 14px;
}
.oqa-loading i { font-size: 26px; color: #10b981; }

/* Sticky footer */
.oqa-foot {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; padding: 12px 24px;
  border-top: 1px solid var(--theme-border, #e2e8f0);
  background: var(--theme-bg-primary, #fff);
  flex-shrink: 0;
}
.oqa-foot-left, .oqa-foot-right { display: flex; align-items: center; gap: 10px; }

.oqa-hint {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 13px; font-weight: 500;
}
.oqa-hint i { font-size: 16px; }
.oqa-hint--warn { color: #b45309; }
.oqa-hint--ok { color: #059669; }

.oqa-kbd {
  display: inline-flex; align-items: center; gap: 3px;
  font-size: 11px; color: var(--theme-text-secondary, #94a3b8);
  margin-right: 6px;
}
.oqa-kbd-key {
  padding: 2px 6px; border-radius: 4px;
  background: #f1f5f9; border: 1px solid #e2e8f0;
  font-family: 'SFMono-Regular', Menlo, Consolas, monospace;
  font-size: 10px; color: #475569;
}
.oqa-kbd-sep { color: #94a3b8; font-weight: 600; }

.oqa-btn {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 9px 18px;
  border: 1.5px solid transparent;
  border-radius: 10px;
  font-size: 14px; font-weight: 600;
  cursor: pointer;
  transition: all 0.15s;
}
.oqa-btn i { font-size: 16px; }
.oqa-btn:disabled { opacity: 0.5; cursor: not-allowed; }

.oqa-btn--ghost {
  background: transparent;
  color: var(--theme-text-secondary, #475569);
  border-color: var(--theme-border, #e2e8f0);
}
.oqa-btn--ghost:hover:not(:disabled) { background: #f1f5f9; color: #1e293b; }

.oqa-btn--primary {
  background: linear-gradient(135deg, #10b981, #059669);
  color: #fff;
  border-color: transparent;
  box-shadow: 0 4px 12px rgba(16, 185, 129, 0.35);
}
.oqa-btn--primary:hover:not(:disabled) {
  background: linear-gradient(135deg, #059669, #047857);
  transform: translateY(-1px);
  box-shadow: 0 6px 16px rgba(16, 185, 129, 0.45);
}
.oqa-btn--primary:active:not(:disabled) { transform: translateY(0); }

.spin { animation: oqa-spin 1s linear infinite; }
@keyframes oqa-spin { to { transform: rotate(360deg); } }

/* Transitions */
.oqa-fade-enter-active, .oqa-fade-leave-active { transition: opacity 0.18s ease; }
.oqa-fade-enter-from, .oqa-fade-leave-to { opacity: 0; }
.oqa-slide-enter-active { transition: transform 0.22s cubic-bezier(0.2, 0.8, 0.2, 1), opacity 0.18s ease; }
.oqa-slide-leave-active { transition: transform 0.18s ease, opacity 0.15s ease; }
.oqa-slide-enter-from { transform: translateY(18px) scale(0.985); opacity: 0; }
.oqa-slide-leave-to { transform: translateY(8px); opacity: 0; }

/* Dark mode */
[data-mode="dark"] .oqa-overlay { background: rgba(2, 6, 23, 0.72); }
[data-mode="dark"] .oqa-card { background: #0f172a; border-color: #1e293b; box-shadow: 0 24px 72px rgba(0, 0, 0, 0.7); }
[data-mode="dark"] .oqa-head {
  background:
    radial-gradient(1200px 120px at 0% 0%, rgba(16, 185, 129, 0.18), transparent 60%),
    linear-gradient(to right, #064e3b, transparent 70%);
  border-bottom-color: #1e293b;
}
[data-mode="dark"] .oqa-title { color: #f1f5f9; }
[data-mode="dark"] .oqa-subtitle { color: #94a3b8; }
[data-mode="dark"] .oqa-chip--org { background: #0c1e3e; color: #93c5fd; border-color: #1e3a8a; }
[data-mode="dark"] .oqa-body { background: #0b1220; }
[data-mode="dark"] .oqa-body::-webkit-scrollbar-thumb { background: #334155; border-color: #0b1220; }
[data-mode="dark"] .oqa-foot { background: #0f172a; border-top-color: #1e293b; }
[data-mode="dark"] .oqa-close { background: #1e293b; border-color: #334155; color: #e2e8f0; }
[data-mode="dark"] .oqa-btn--ghost { color: #cbd5e1; border-color: #334155; }
[data-mode="dark"] .oqa-btn--ghost:hover:not(:disabled) { background: #1e293b; color: #f1f5f9; }
[data-mode="dark"] .oqa-kbd-key { background: #1e293b; border-color: #334155; color: #cbd5e1; }

/* Mobile: full-screen */
@media (max-width: 768px) {
  .oqa-overlay { padding: 0; }
  .oqa-card { border-radius: 0; max-width: 100%; height: 100vh; border: none; }
  .oqa-head { padding: 12px 16px; }
  .oqa-head-badge { width: 38px; height: 38px; font-size: 18px; }
  .oqa-title { font-size: 16px; }
  .oqa-subtitle { flex-direction: column; align-items: flex-start; gap: 4px; }
  .oqa-body { padding: 14px 16px; }
  .oqa-foot { padding: 10px 16px; flex-wrap: wrap; gap: 10px; }
  .oqa-foot-left { width: 100%; order: -1; }
  .oqa-kbd { display: none; }
  .oqa-btn { flex: 1; justify-content: center; }
}
</style>
