<script setup>
import { date, string } from 'alga-js'
import { DatePicker } from 'tedir-calendar'
import { SelectBox } from 'tedir-select'
import { toast } from 'bulma-toast'
import DOMPurify from 'dompurify'

const router = useRouter()
const route = useRoute()
const generateShipments = useGenerateShipments()
const generateShipmentActive = useGenerateShipmentActive()
const user = useCookie('logship_user')

const warehouses = useCookie('logship_warehouses')
const warehouse = useCookie('logship_warehouse')
const warehouseId = useCookie('logship_warehouse_id')

const summaryLog = ref({})
const form = ref({
  id: '',
  uid: '',
  warehouse: generateShipments.value?.warehouse || warehouse.value?.Name || '',
  warehouseId: generateShipments.value?.warehouseId || warehouseId.value || '',
  dateAcct: date.now('date'),
  partner: generateShipments.value?.partner || '',
  partnerId: generateShipments.value?.partnerId || '',
  datePromised: date.now('date'),
  docStatus: 'Complete',
  docStatusId: 'CO',
  isUnconfirmed: false,
  isOneDocument: false,
  inProgress: false,
  isRunJob: false,
  alert: {
    status: '',
    message: '',
    processing: false,
  }
})
watch(() => generateShipments, () => {
  if(generateShipments.value?.warehouse && generateShipments.value?.warehouseId && generateShipments.value?.partner && generateShipments.value?.partnerId) {
    form.value.warehouse = generateShipments.value?.warehouse || warehouse.value?.Name || ''
    form.value.warehouseId = generateShipments.value?.warehouseId || warehouseId.value || ''
    form.value.partner = generateShipments.value?.partner || ''
    form.value.partnerId = generateShipments.value?.partnerId || ''
  }
}, {deep: true})
watch(generateShipmentActive, () => {
  summaryLog.value = {}
  if(generateShipments.value?.warehouse && generateShipments.value?.warehouseId && generateShipments.value?.partner && generateShipments.value?.partnerId) {
    form.value.warehouse = generateShipments.value?.warehouse || warehouse.value?.Name || ''
    form.value.warehouseId = generateShipments.value?.warehouseId || warehouseId.value || ''
    form.value.partner = generateShipments.value?.partner || ''
    form.value.partnerId = generateShipments.value?.partnerId || ''
  }
})

const loading = ref({})
const filtering = ref({})
const getOptions = ref({})
const setOptions = async (url, key) => {
  loading.value[key] = true
  const res = await $fetch('/api/'+url, {
    headers: useRequestHeaders(['cookie'])
  })
  if(res) {
    getOptions.value[key] = res
  }
  loading.value[key] = false
}

const filterOptions = async (model, key, filter = '') => {
  if(filter) {
    await setOptions('filters/'+model+'/'+filter, key)
    filtering.value[key] = filter
  } else {
    if(!filtering.value?.[key] || filtering.value?.[key] === '') {
      await setOptions('models/'+model, key)
    }
  }
}

const extractDocumentNo = (str) => {
  let newStr = ''
  const newArr = String(str ?? '').split('Processed:')
  if(isNaN(newArr?.[1]?.trim()) === false) {
    newStr = newArr[1].trim()
  }
  return newStr
}

const serverSidePrinting = async (content) => {
  const res = await $fetch('/api/print/', {
    method: 'POST',
    body: content
  })
  if(res) {
    //console.log(res)
    if(res?.stdout) {
      toast({
        message: `The ${content?.pathName === 'picklist' ? 'Picklist' : 'Shipment'} has been printed via server side printing!`,
        type: 'is-success',
        duration: 2000
      })
    }
  }
}

const printPDF = async (docContent, type =  'direct') => {
  const { jsPDF } = await import('jspdf')
  
  const doc = new jsPDF({
    orientation: 'p',
    unit: 'pt',
    format: 'a4',
    putOnlyUsedFonts: true,
    compress: true
  })
  
  doc.html(DOMPurify.sanitize(docContent), {
    callback: (doc) => {
      if(type === 'server') {
        serverSidePrinting({
          pathName: `picklist/${new Date().getFullYear()}`,
          fileName: `${date.now().replace(/\-|\:/g, '_').replace(' ', '-PICKLIST-')}-${user.value?.Name || 'SUPERUSER'}.pdf`,
          fileContent: doc.output('dataurlstring')?.replace('data:application/pdf;filename=generated.pdf;base64,', '')
        })
      } else {
        doc.save(`${date.now().replace(/\-|\:/g, '_').replace(' ', '-PICKLIST-')}-${user.value?.Name || 'SUPERUSER'}.pdf`)
      }
    },
    width: 580,
    windowWidth: 580,
    margin: 15,
    x: 0,
    y: 0,
    autoPaging: 'text',
  })
}

const generateReport = async (type) => {
  if(Number(summaryLog.value?.logs?.length ?? 0) >= 1) {
    const newInOutLine = []
    for(let log of summaryLog.value.logs) {
      const docNo = extractDocumentNo(log?.msg ?? log)
      if(!docNo) continue
      const res = await $fetch('/api/processes/inouts/'+docNo)
      if(res?.records?.[0]) {
        const docRes = res.records[0]
        const productLines = (docRes.m_inoutline || []).filter(l => l.M_Product_ID && l.M_Locator_ID && !l.C_Charge_ID)
        for(let drl of productLines) {
          if(newInOutLine.filter(i => i.AD_Org_ID.id == drl.AD_Org_ID.id && i.M_Product_ID.Value == drl.M_Product_ID.Value && i.M_Locator_ID.X == drl.M_Locator_ID.X && i.M_Locator_ID.Y == drl.M_Locator_ID.Y && i.M_Locator_ID.Z == drl.M_Locator_ID.Z).length >= 1) {
            const prodInd = newInOutLine.findIndex(i => i.AD_Org_ID.id == drl.AD_Org_ID.id && i.M_Product_ID.Value == drl.M_Product_ID.Value && i.M_Locator_ID.X == drl.M_Locator_ID.X && i.M_Locator_ID.Y == drl.M_Locator_ID.Y && i.M_Locator_ID.Z == drl.M_Locator_ID.Z)
            const prodItem = newInOutLine[prodInd]
            prodItem.QtyEntered = Number(prodItem.QtyEntered) + Number(drl.QtyEntered)
            newInOutLine.splice(prodInd, 1, prodItem)
          } else {
            newInOutLine.push(drl)
          }
        }
        /*console.log(docRes.m_inoutline.map(i => {
          return [i.M_Product_ID.Value, i.M_Locator_ID.X, i.M_Locator_ID.Y, i.M_Locator_ID.Z]
        }))
        console.log(newInOutLine.map(i => {
          return [i.M_Product_ID.Value, i.M_Locator_ID.X, i.M_Locator_ID.Y, i.M_Locator_ID.Z]
        }))*/
      }
    }
    const truncateName = (name, maxLen = 30) => {
      if (!name) return ''
      return name.length > maxLen ? name.substring(0, maxLen) + '...' : name
    }

    const docRows = newInOutLine.map(item => {
      return `
        <tr>
          <td style="border-bottom: 1px solid #9f9f9f; padding: 0.3rem;">${item.AD_Org_ID.identifier}</td>
          <td style="border-bottom: 1px solid #9f9f9f; padding: 0.3rem;">${item.M_Locator_ID.X}, ${item.M_Locator_ID.Y}, ${item.M_Locator_ID.Z}</td>
          <td style="border-bottom: 1px solid #9f9f9f; padding: 0.3rem; max-width: 140px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;">${truncateName(item.M_Product_ID.Name, 35)}</td>
          <td style="border-bottom: 1px solid #9f9f9f; padding: 0.3rem;">${item.M_Product_ID.Value}<br>${item.M_Product_ID.SKU || '-'}<br>${item.M_Product_ID.mpn || '-'}<br>${item.M_Product_ID.UPC || '-'}</td>
          <td style="border-bottom: 1px solid #9f9f9f; padding: 0.3rem; text-align: center;">${item.QtyEntered}</td>
        </tr>
      `
    }).join('')

    const docContent = `
      <div style="font-size: 7pt; width: 565px;">
        <div style="text-align: center;">
          <p style="font-size: 14pt; font-weight: bold;">Picklist</p>
          <p>${date.now('date')}</p>
        </div>
        <table style="border-collapse: collapse; border: none; width: 100%; margin-top: 1rem;">
          <thead>
            <tr>
              <th style="background-color: #f2f2f2; padding: 0.3rem; font-size: 7pt;">Org</th>
              <th style="background-color: #f2f2f2; padding: 0.3rem; font-size: 7pt;">Locator</th>
              <th style="background-color: #f2f2f2; padding: 0.3rem; font-size: 7pt;">Product Name</th>
              <th style="background-color: #f2f2f2; padding: 0.3rem; font-size: 7pt;">Value/SKU/MPN/UPC</th>
              <th style="background-color: #f2f2f2; padding: 0.3rem; font-size: 7pt;">Qty</th>
            </tr>
          </thead>
          <tbody>
            ${docRows}
          </tbody>
        </table>
      </div>
    `

    printPDF(docContent, type)
  }
}

const generateShipment = async (val) => {
  if(val) {
    const docNo = extractDocumentNo(val)
    if(!docNo) return

    const response = await $fetch('/api/print/'+docNo+'/shipment', {
      headers: useRequestHeaders(['cookie'])
    })
    if(response) {
      serverSidePrinting({
        pathName: `shipments/${new Date().getFullYear()}`,
        fileName: `${date.now().replace(/\-|\:/g, '_').replace(' ', '-'+docNo+'-')}-SHIPMENTS-${user.value?.Name || 'SUPERUSER'}.pdf`,
        fileContent: response.reportFile
      })
    }
  }
}

const generateAll = async (logs) => {
  for(let log of logs) {
    const docNo = extractDocumentNo(log?.msg ?? log)
    if(!docNo) continue

    const response = await $fetch('/api/print/'+docNo+'/shipment', {
      headers: useRequestHeaders(['cookie'])
    })
    if(response) {
      await $fetch('/api/print/', {
        method: 'POST',
        body: {
          pathName: `shipments/${new Date().getFullYear()}`,
          fileName: `${date.now().replace(/\-|\:/g, '_').replace(' ', '-'+docNo+'-')}-SHIPMENTS-${user.value?.Name || 'SUPERUSER'}.pdf`,
          fileContent: response.reportFile
        }
      })
    }
  }

  setTimeout(() => {
    toast({
      message: 'The mutliple printing of Shipment via server has been processed!',
      type: 'is-success',
      duration: 2000
    })
  }, 1000)
}

const submit = async () => {
  form.value.alert.processing = true

  const res = await $fetch('/api/processes/inouts/generate', {
    method: 'POST',
    headers: useRequestHeaders(['cookie']),
    body: {
      warehouseId: form.value.warehouseId,
      dateAcct: form.value.dateAcct,
      partnerId: form.value.partnerId,
      datePromised: form.value.datePromised,
      docStatusId: form.value.docStatusId,
      isUnconfirmed: form.value.isUnconfirmed,
      isOneDocument: form.value.isOneDocument,
      inProgress: form.value.inProgress,
      isRunJob: form.value.isRunJob,
    }
  })

  if(Number(res.status) === 200) {
    summaryLog.value = res
    /*toast({
      message: 'Shipment has been generated!',
      type: 'is-success',
      duration: 2000
    })*/
    if(Number(res?.logs?.length || 0) >= 1) {
      //generateShipment(res.logs[0]?.msg ?? res.logs[0])
      toast({
        message: 'The Shipment and Picklist has been generated!',
        type: 'is-success',
        duration: 2000
      })
    } else {
      toast({
        message: 'No Shipment or Picklist generated!',
        type: 'is-warning',
        duration: 2000
      })
    }
  } else {
    //form.value.alert.status = res.status
    //form.value.alert.message = res.message
    toast({
      message: res.message || 'Generate error',
      type: 'is-danger',
      duration: 2000
    })
    //window.scrollTo(0, 0)
  }

  form.value.alert.processing = false
}

const closeShipmentGeneration = () => {
  generateShipmentActive.value = false
}
</script>

<template>
  <div class="modal" :class="{'active': generateShipmentActive}" :style="{display: generateShipmentActive ? 'block' : 'none'}">
    <div class="modalDialog modalCenter modalPrintPreview" @click.self="closeShipmentGeneration">
      <div class="modalContent">
        <div class="modalHeader">
          <h3 class="modalTitle">Shipment Generation</h3>
          <div class="cursor-pointer" @click="closeShipmentGeneration">
            <span class="tf-icon ti ti-x ti-sm me-1"></span>
          </div>
        </div>
        <div class="modalBody">
          <div class="d-flex justify-between mb-3">
            <h4></h4>
            <div class="d-flex gap-0.75rem">
              <template v-if="summaryLog?.summary">
                <div>
                  <button type="button" class="button" @click="summaryLog = {}">
                    Parameter
                  </button>
                </div>
                <div v-if="summaryLog?.logs?.[0]">
                  <button type="button" class="button" @click="generateReport('direct')">
                    Print Picklist Direct
                  </button>
                </div>
                <div v-if="summaryLog?.logs?.[0]">
                  <button type="button" class="button" @click="generateReport('server')">
                    Print Picklist Server
                  </button>
                </div>
              </template>
              <div v-else>
                <button type="button" class="button" @click="submit" :class="(form.warehouseId === '' || form.alert.processing) ? 'pointerEvents-none opacity-0.6' : ''">
                  Start
                </button>
              </div>
            </div>
          </div>
          <div>
            <div class="my-3 mx-3">

              <div>
                <div class="p-1.5rem">
                  <p><strong>Generate and print Shipments from open Orders</strong></p>
                  <p>Shipments for open Orders are created based on the delivery rule of the Order and the relative order priority. If a Promise Date is selected only orders up to (including) the date are selected.</p>
                  <p>If several Orders of a business partner have the same location, the orders can be consolidated into one Shipment.</p>
                  <p>You can also include orders who have outstanding confirmations (e.g. ordered=10 - not confirmed shipments=4 - would create a new shipment of 6 if available).</p>
                </div>
                <div v-if="summaryLog?.summary" class="p-1.5rem">
                  <p><strong>{{ summaryLog.summary }}</strong> - <a v-if="Number(summaryLog?.logs?.length || 0) >= 1" href="javascript:void(0);" @click.prevent="generateAll(summaryLog?.logs || [])">Print All</a></p>
                  <template v-for="(log, ind) in summaryLog?.logs || []" :key="ind">
                    <p>{{ log?.date ?? log }} {{ log?.msg ?? '' }} - <a href="javascript:void(0);" @click.prevent="generateShipment(log?.msg ?? log)">Print Shipment</a></p>
                  </template>
                </div>
                <div v-else class="p-1.5rem">
                  <div class="columns is-desktop">
                    <div class="column is-one-third">
                      Warehouse *
                    </div>
                    <div class="column is-two-thirds">
                      <!--<SelectBox v-model="form.warehouseId" :options="warehouses" @change="(val, opt) => form.warehouse = opt.name" prop="name" dataprop="id" datatype="string" :size="5" />-->
                      <ClientOnly>
                        <SelectBox v-model="form.warehouseId" :options="getOptions?.['warehouses']?.records || [{id: form.warehouseId, Name: form.warehouse}]" prop="Name" dataprop="id" datatype="string" :size="5" @click="filterOptions('m_warehouse', 'warehouses')" @search="(val) => filterOptions('m_warehouse', 'warehouses', string.urlEncode(`isActive eq true AND contains(Name,'${val}')`))" :loading="loading?.['warehouses'] ?? true" />
                      </ClientOnly>
                    </div>
                  </div>
                  
                  <div class="columns is-desktop mt-2">
                    <div class="column is-one-third">
                      Shipment Date
                    </div>
                    <div class="column is-two-thirds">
                      <DatePicker class="pickerEnd" v-model="form.dateAcct" />
                    </div>
                  </div>
                  
                  <div class="columns is-desktop mt-2">
                    <div class="column is-one-third">
                      Business Partner
                    </div>
                    <div class="column is-two-thirds">
                      <ClientOnly>
                        <SelectBox v-model="form.partnerId" :options="getOptions?.['partners']?.records || [{id: form.partnerId, Name: form.partner}]" prop="Name" dataprop="id" datatype="string" :size="5" @click="filterOptions('c_bpartner', 'partners')" @search="(val) => filterOptions('c_bpartner', 'partners', string.urlEncode(`isActive eq true AND contains(Name,'${val}')`))" :loading="loading?.['partners'] ?? true" />
                      </ClientOnly>
                    </div>
                  </div>
                  
                  <div class="columns is-desktop mt-2">
                    <div class="column is-one-third">
                      Date Promised
                    </div>
                    <div class="column is-two-thirds">
                      <DatePicker class="pickerEnd" v-model="form.datePromised" />
                    </div>
                  </div>
                  
                  <div class="columns is-desktop mt-2">
                    <div class="column is-one-third">
                      
                    </div>
                    <div class="column is-two-thirds">
                      <div class="check">
                        <input type="checkbox" v-model="form.isUnconfirmed" class="checkInput" id="isUnconfirmed" :checked="form.isUnconfirmed">
                        <label class="checkLabel" for="isUnconfirmed">Orders with unconfirmed Shipments</label>
                      </div>
                    </div>
                  </div>
                  
                  <div class="columns is-desktop mt-2">
                    <div class="column is-one-third">
                      Document Action
                    </div>
                    <div class="column is-two-thirds">
                      <select v-model="form.docStatusId" class="select">
                        <option value="CO">Complete</option>
                        <option value="PR">Prepare</option>
                      </select>
                    </div>
                  </div>
                  
                  <div class="columns is-desktop mt-2">
                    <div class="column is-one-third">
                      
                    </div>
                    <div class="column is-two-thirds">
                      <div class="d-flex flexDirection-column px-3 gap-5px">
                        <div class="check">
                          <input type="checkbox" v-model="form.isOneDocument" class="checkInput" id="isOneDocument" :checked="form.isOneDocument">
                          <label class="checkLabel" for="isOneDocument">Consolidate to one Document</label>
                        </div>
                        <div class="check">
                          <input type="checkbox" v-model="form.inProgress" class="checkInput" id="inProgress" :checked="form.inProgress">
                          <label class="checkLabel" for="inProgress">Subtract In Progress Shipment From On Hand</label>
                        </div>
                        <div class="check">
                          <input type="checkbox" v-model="form.isRunJob" class="checkInput" id="isRunJob" :checked="form.isRunJob">
                          <label class="checkLabel" for="isRunJob">Run as Job</label>
                        </div>
                      </div>
                    </div>
                  </div>
                </div>
              </div>

            </div>
          </div>
        </div>
        <div class="modalFooter">
          <div></div>
          <div class="d-flex gap-10px">
            <button type="button" class="button" @click="closeShipmentGeneration">Close</button>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<style scoped>
.modal.active .modalDialog {
  padding: 0;
}
.modalContent {
  background: white;
}

/*@media (max-width: 900px) {
  margin-right: 8px;
}*/
</style>