import { i18next, localize } from '@things-factory/i18n-base'
import { openPopup } from '@things-factory/layout-base'
import { client, CustomAlert, navigate, PageView } from '@things-factory/shell'
import { ScrollbarStyles, CommonButtonStyles } from '@things-factory/styles'
import { getPathInfo } from '@things-factory/utils'
import gql from 'graphql-tag'
import { css, html } from 'lit-element'
import '../../components/popup-note'
import { ORDER_STATUS } from '../../constants'
import './delivery-note-popup'

class PrintDeliveryOrder extends localize(i18next)(PageView) {
  static get styles() {
    return [
      ScrollbarStyles,
      css`
        :host {
          display: flex;
          flex-direction: column;
          padding: 0;
        }

        #container {
          flex: 1;
          padding: 0;
          margin: 0;
          border: 0;
        }
      `
    ]
  }

  static get properties() {
    return {
      _doNo: String,
      _driverName: String,
      _ownCollection: Boolean,
      _truckNo: String,
      _status: String,
      _date: Date,
      _recipient: String,
      _proceedFlag: Boolean,
      // _customerContactPoints: Array,
      _bizplace: Object,
      _orderInfo: Object,
      _isManualDo: Boolean,
      _data: Object,
      _roNo: String,
      _refNo: String,
      _deliveryContactPoint: Object
    }
  }

  constructor() {
    super()
    this._date = ''
    this._status = ''
  }

  get context() {
    var actions = [
      {
        title: i18next.t('button.back'),
        action: () => navigate(`delivery_orders`),
        ...CommonButtonStyles.back
      },
      {
        title: i18next.t('button.print'),
        action: () => {
          if (this._validateBusinessRestDay()) {
            this.renderRoot.querySelector('iframe').contentWindow.print()
          }
        },
        ...CommonButtonStyles.print
      }
    ]
    if (this._status === ORDER_STATUS.READY_TO_DISPATCH.value || this._status === ORDER_STATUS.DELIVERING.value) {
      actions.push({
        title: i18next.t('button.edit'),
        action: this._editDeliveryNote.bind(this),
        ...CommonButtonStyles.edit
      })
    }

    if (this._status === ORDER_STATUS.DELIVERING.value) {
      actions.push({
        title: i18next.t('button.complete'),
        action: this._checkDeliveredOrder.bind(this),
        ...CommonButtonStyles.save
      })
    }

    return {
      title: i18next.t('title.goods_delivery_note_details'),
      help: 'operato-wms/transport-order/print-delivery-note',
      actions,
      exportable: {
        name: i18next.t('title.goods_delivery_note_details'),
        data: this._exportableData.bind(this)
      }
    }
  }

  render() {
    return html` <iframe id="container"></iframe> `
  }

  get _doDocument() {
    return this.shadowRoot.querySelector('#container')
  }

  async pageUpdated(changes) {
    if (this.active) {
      if (changes.resourceId) {
        this._doNo = changes.resourceId
      }

      if (this._doNo) {
        await this._fetchDeliveryOrder(this._doNo)

        this._fetchDOTemplate()
      }

      this.updateContext()
    }
  }

  async _fetchDeliveryOrder(name) {
    const response = await client.query({
      query: gql`
        query deliveryOrderByWorksheet($name: String!) {
          deliveryOrderByWorksheet(name: $name) {
            deliveryOrderInfo {
              name
              contactName
              createdDate
              deliverTo
              deliveryDate
              doStatus
              driverName
              driverCode
              otherDestination
              otherDriver
              otherDriverCode
              ownCollection
              isManualDo
              remark
              reusablePallet
              truckNo
              bizplace {
                id
                name
              }
              releaseGood {
                name
                refNo
                refNo2
                refNo3
                attentionTo
                rtm
              }
              productList {
                batchNo
                sku
                name
                type
                uom
                loadedQty
                uomValue
              }
            }
            releaseOrderDeliverTo {
              id
              contactName
              address
              phone
              fax
              email
              businessRestDay
              customerCode
            }
          }
        }
      `,
      variables: {
        name
      }
    })

    if (!response.errors) {
      const deliveryOrderData = response.data.deliveryOrderByWorksheet

      let orderInfo = deliveryOrderData.deliveryOrderInfo
      this._roNo = orderInfo.releaseGood.name
      this._status = orderInfo.doStatus
      this._ownCollection = orderInfo.ownCollection
      this._truckNo = orderInfo.truckNo
      this._bizplace = orderInfo.bizplace
      this._isManualDo = orderInfo.isManualDo

      // Use release order's deliverTo contact point for business rest day validation
      this._deliveryContactPoint = deliveryOrderData.releaseOrderDeliverTo || null

      this._orderInfo = orderInfo
    }
  }

  /**
   * Validates if current date falls on a business rest day
   * @returns {boolean} - Returns true if printing is allowed, false otherwise
   */
  _validateBusinessRestDay() {
    // Check if there's a contact point reference
    if (!this._deliveryContactPoint || !this._deliveryContactPoint.businessRestDay) {
      return true // No business rest day restriction, allow printing
    }

    const businessRestDay = this._deliveryContactPoint.businessRestDay
    if (!businessRestDay || businessRestDay.trim() === '') {
      return true // Empty business rest day, allow printing
    }

    // Get current day of week
    const today = new Date()
    const dayOfWeek = today.getDay() // 0 = Sunday, 1 = Monday, ..., 6 = Saturday
    const dayNames = ['SUNDAY', 'MONDAY', 'TUESDAY', 'WEDNESDAY', 'THURSDAY', 'FRIDAY', 'SATURDAY']
    const currentDayName = dayNames[dayOfWeek]

    // Parse business rest days (comma-separated)
    const restDays = businessRestDay
      .split(',')
      .map(day => day.trim().toUpperCase())
      .filter(day => day.length > 0)

    // Check if current day is in the rest days list
    if (restDays.includes(currentDayName)) {
      CustomAlert({
        type: 'warning',
        title: i18next.t('title.printing_not_allowed'),
        text:
          i18next.t('text.printing_not_allowed_business_rest_day', {
            day: currentDayName,
            restDays: restDays.join(', ')
          }) ||
          `Printing is not allowed as today (${currentDayName}) falls on the business rest day(s) of this contact point: ${restDays.join(
            ', '
          )}`,
        confirmButton: { text: i18next.t('button.okay') }
      })
      return false
    }

    return true // Current day is not a rest day, allow printing
  }

  /**
   * @oscarchuaweiwen-fsd
   * Kindly clean up anything regarding this function.
   * Check and confirm to be remove and remove.
   * This function causes the whole page to render 2 times. Thus causing the document template to run 2 time and consuming alot of resources.
   */
  async _fetchDeliveryOrderRO(name) {
    const response = await client.query({
      query: gql`
        query fetchDeliveryOrderRO($name: String!) {
          fetchDeliveryOrderRO(name: $name) {
            roNo
            doNo
            roRef
            roRef2
            roRef3
            companyDomain
            recipientBiz
            doDate
            productList {
              batchNo
              sku
              name
              type
              uom
              loadedQty
              uomValue
            }
          }
        }
      `,
      variables: {
        name
      }
    })

    if (!response.error) {
      this._data = response.data.fetchDeliveryOrderRO
      this._roNo = this._data.roNo
      this._refNo = this._data.roRef
    }
  }

  async _checkDeliveredOrder() {
    const popup = openPopup(
      html`
        <popup-note
          .title="${i18next.t('title.remark')}"
          @submit="${async e => {
            try {
              const result = await CustomAlert({
                title: i18next.t('title.are_you_sure'),
                text: i18next.t('text.completed_delivery_order'),
                confirmButton: { text: i18next.t('button.confirm') },
                cancelButton: { text: i18next.t('button.cancel') }
              })

              if (!result.value) {
                return
              }

              const response = await client.mutate({
                mutation: gql`
                  mutation checkDeliveredOrder($name: String!, $patch: DeliveryOrderPatch) {
                    checkDeliveredOrder(name: $name, patch: $patch) {
                      name
                    }
                  }
                `,
                variables: {
                  name: this._doNo,
                  patch: { remark: e.detail.value }
                }
              })

              if (!response.errors) {
                navigate('delivery_orders')
                this._showToast({ message: i18next.t('text.delivery_order_completed') })
              }
            } catch (e) {
              this._showToast(e)
            }
          }}"
        ></popup-note>
      `,
      {
        backdrop: true,
        size: 'medium',
        title: i18next.t('title.completed_delivery_order')
      }
    )
  }

  _editDeliveryNote() {
    openPopup(
      html`
        <delivery-note-popup
          .doNo="${this._doNo}"
          .roNo="${this._roNo}"
          .refNo="${this._refNo}"
          .bizplace="${this._bizplace}"
          .orderInfo="${this._orderInfo}"
          .status="${this._status}"
          .manualDo="${this._isManualDo}"
          @delivery-dispatched="${() => {
            this.pageReset()
          }}"
        ></delivery-note-popup>
      `,
      {
        backdrop: true,
        size: 'large',
        title: i18next.t('title.edit_delivery_note')
      }
    )
  }

  _fetchDOTemplate() {
    var { domain } = getPathInfo(location.pathname) // find out better way later.

    if (domain === 'orientage-warehouse' || domain === 'shah-alam-warehouse') {
      this._doDocument.src = `/view_document_orientage_do/${this._doNo}`
    } else {
      this._doDocument.src = `/view_document_ro_do/${this._doNo}`
    }
  }

  _exportableData() {
    const { name, doNo, refNo, refNo2, refNo3, companyDomain, attentionTo, doDate, rtm } = {
      ...this._orderInfo.releaseGood,
      bizplaceName: this._orderInfo.bizplace.name,
      doNo: this._orderInfo.name,
      doDate: this._orderInfo.createdDate
    }

    const customerCode = this._deliveryContactPoint?.customerCode || ''

    const exportData = this._orderInfo.productList.map(res => {
      return {
        roNo: name,
        doNo,
        roRef: refNo,
        roRef2: refNo2,
        roRef3: refNo3,
        companyDomain,
        recipientBiz: attentionTo,
        doDate,
        rtm,
        customerCode,
        ...res
      }
    })

    const headerSetting = [
      {
        header: i18next.t('field.ro'),
        key: 'roNo',
        width: 25,
        type: 'string'
      },
      {
        header: i18next.t('field.do'),
        key: 'doNo',
        width: 25,
        type: 'string'
      },
      {
        header: i18next.t('field.ref_no'),
        key: 'roRef',
        width: 25,
        type: 'string'
      },
      {
        header: i18next.t('field.ref_no_2'),
        key: 'roRef2',
        width: 25,
        type: 'string'
      },
      {
        header: i18next.t('field.ref_no_3'),
        key: 'roRef3',
        width: 25,
        type: 'string'
      },
      {
        header: i18next.t('field.rtm'),
        key: 'rtm',
        width: 25,
        type: 'string'
      },
      {
        header: i18next.t('field.customer_code'),
        key: 'customerCode',
        width: 25,
        type: 'string'
      },
      {
        header: i18next.t('field.company'),
        key: 'companyDomain',
        width: 25,
        type: 'string'
      },
      {
        header: i18next.t('field.recipient_bizplace'),
        key: 'recipientBiz',
        width: 25,
        type: 'string'
      },
      {
        header: i18next.t('field.do_generated_date'),
        key: 'doDate',
        width: 25,
        type: 'string'
      },
      {
        header: i18next.t('field.batch_no'),
        key: 'batchNo',
        width: 25,
        type: 'string'
      },
      {
        header: i18next.t('field.sku'),
        key: 'sku',
        width: 25,
        type: 'string'
      },
      {
        header: i18next.t('field.product_name'),
        key: 'name',
        width: 25,
        type: 'string'
      },
      {
        header: i18next.t('field.packing_type'),
        key: 'type',
        width: 25,
        type: 'string'
      },
      {
        header: i18next.t('field.loaded_qty'),
        key: 'loadedQty',
        width: 25,
        type: 'string'
      },
      {
        header: i18next.t('field.load_uom_value'),
        key: 'uomValue',
        width: 25,
        type: 'string'
      },
      {
        header: i18next.t('field.uom'),
        key: 'uom',
        width: 25,
        type: 'string'
      }
    ]

    return { header: headerSetting, data: exportData }
  }

  _showToast({ type, message }) {
    document.dispatchEvent(
      new CustomEvent('notify', {
        detail: {
          type,
          message
        }
      })
    )
  }
}

window.customElements.define('print-delivery-note', PrintDeliveryOrder)
