<template>
  <el-card class="step-card">
    <div
      slot="header"
      class="flex between">
      <div class="step-card-title">Step3 Confirm</div>
    </div>
    <div v-loading="loading">
      <div>
        <div v-if="addressList.length">
          <div class="card-sub-title">Ship to</div>
          <div class="form-item-label">Shipping address</div>
          <div class="flex between">
            <div>
              <div>
                <div class="flex">
                  <div class="address-text name">{{ defaultAddr.name }}</div>
                  <div class="address-text">&nbsp;{{ defaultAddr.phone }}</div>
                </div>
                <div class="address-text">{{ defaultAddr.address }}</div>
                <div class="flex">
                  <div class="address-text">{{ defaultAddr.city }}</div>
                  <div class="address-text">
                    &nbsp;{{ defaultAddr.post_code }}
                  </div>
                </div>
              </div>
            </div>
            <el-button
              type="text"
              @click="visibleOfSelectAddressDialog = true"
              >edit address</el-button
            >
          </div>
        </div>
        <el-button
          @click="addAddress"
          v-else
          size="mini"
          plain
          >+&nbsp;Add delivery address</el-button
        >
      </div>
      <el-form
        :model="form"
        :rules="rules"
        label-width="0"
        label-position="left"
        ref="form">
        <el-form-item
          label-width="120px"
          label="Freight type">
          <el-radio-group
            v-loading="freightLoading"
            v-model="form.freight_type">
            <el-radio :label="2">AAE</el-radio>
            <el-radio :label="1">Road express</el-radio>
          </el-radio-group>
        </el-form-item>

        <div class="price-title flex">
          <div>Pricing Optiopns</div>
        </div>
        <div class="divide-solid"></div>
        <div class="price-table">
          <el-table
            class=""
            v-loading="freightLoading"
            :data="computedPriceTableData">
            <el-table-column
              v-for="(column, index) in computedPriceTableColumns"
              :fixed="column.fixed || false"
              :width="column.width || '100px'"
              :key="`${column.prop}-${index}`"
              :label="column.label || column.prop"
              :prop="column.prop"></el-table-column>
          </el-table>
        </div>

        <el-form-item
          label-width="0"
          prop="job">
          <div class="form-item-label">
            <span style="color: red">*</span>&nbsp;Reference or Job name
          </div>
          <el-select
            v-model="form.job"
            filterable
            allow-create
            default-first-option
            style="width: 100%"
            placeholder="Ref, Choose or create new one">
            <el-option
              v-for="item in jobOptions"
              :key="item.label_type"
              :label="item.label_type"
              :value="item.label_type">
            </el-option>
          </el-select>
        </el-form-item>
        <div class="form-item-label">Note</div>
        <el-form-item
          prop="note"
          label-width="0">
          <el-input
            v-model="form.note"
            placeholder="Any note"></el-input>
        </el-form-item>
      </el-form>
      <div class="flex center">
        <el-button
          type="primary"
          @click="addToProject">
          <div class="flex center">
            <span class="btn-icon el-icon-shopping-cart-2"></span>&nbsp; Add to
            project
          </div>
        </el-button>
        <el-button
          type="info"
          @click="sendEnquiry">
          <div class="flex">
            <span class="btn-icon el-icon-shopping-bag-1"></span>&nbsp; Send
            enquiry
          </div>
        </el-button>
      </div>
      <add-address-dialog
        :dialogVisible.sync="visibleOfEditAddressDialog"
        :data="addressDetail"
        :componentVisible="patternOfEditAddressDialog"
        @close="closeAddressDialog"
        @update="getAddressData" />
      <select-address-dialog
        :addressDetail="form.defaultAddr"
        :addressList="addressList"
        :visible.sync="visibleOfSelectAddressDialog"
        @add-new-addr="addAddress"
        @select-addr="selectAddress"
        @close="closeSelectAddressDialog"></select-address-dialog>
    </div>
  </el-card>
</template>

<script>
import { plus } from 'number-precision'
import _ from 'lodash'
import { mapState } from 'vuex'
import stepMixin from './stepMixin'
import selectAddressDialog from './DialogSelectAddr.vue'
import addAddressDialog from '@/components/addAddressDialog.vue'
import {
  formatPrice,
  getUnit,
  getSetup,
  getPrint,
  getAddon,
  getPackaging,
  getFright,
} from '@/utils/price'

export default {
  name: 'Step3',
  components: {
    addAddressDialog,
    selectAddressDialog,
  },
  mixins: [stepMixin],
  props: {
    // 步骤1中选中的周期. 不能直接拿form1来取form1.cycle, 否则步骤1变更时, 涉及到form1的computed会全部重新计算, 可能会导致其他异常
    cycle: {
      type: Number,
      default: function () {
        return 0
      },
    },
    // 同cycle
    model: {
      type: Number,
      default: function () {
        return 0
      },
    },
    // 同cycle. form1的autoForm, 记录对应颜色的 商品购买数量表单.
    buyForm: {
      type: Array,
      default: function () {
        return []
      },
    },
    // 步骤2的表单. 因其设计选中规格, 为当前步骤的前置数据, 故需从父组件获取. 只用来计算, 本组件不更改这个数据.
    form2: {
      type: Object,
      default: function () {
        return {}
      },
    },
    weightInfo: {
      type: Object,
      default: function () {
        return {}
      },
    },
  },
  data() {
    return {
      rules: {
        job: [
          {
            required: true,
            message: 'Please select or create a job name',
            trigger: 'change',
          },
        ],
      },
      form: {
        // 默认的配送地址
        defaultAddr: {},
        freight_type: 1,
        job: '',
        note: '',
      },
      freightLoading: false,
      // 运费信息
      freightInfo: {},
      // 运费浮动比. 从product页面来的数据, 记录在local storage里面
      sellFreight: 0,
      addressList: [],
      addressDetail: {},
      visibleOfSelectAddressDialog: false,
      visibleOfEditAddressDialog: false,
      patternOfEditAddressDialog: 1,
      jobOptions: [],
      priceTableColumns: [
        {
          prop: 'qty',
          label: 'Qty',
          fixed: 'left',
        },
      ],
      dynamicPriceTableColumns: [],
      dynamicPriceTableData: [],
      priceTableData: [
        {
          qty: 'Unit',
        },
        {
          qty: 'Set up',
        },
        {
          qty: 'Print Option',
        },
        {
          qty: 'Addon',
        },
        {
          qty: 'Packing',
        },
        {
          qty: 'Fright',
        },
        {
          qty: 'SubTotal',
        },
      ],
    }
  },
  computed: {
    ...mapState('config', { configInfo: state => state.configInfo }),
    // 商品 当前选中周期的 基础价格和打印价格数据
    computedPriceData() {
      return this.priceData.priceList.filter(
        item => item.cycle_id === this.cycle
      )
    },
    /**
     * 当前选中周期下, 商品对应的各型号基础价格数据. 可以推断当前周期有几个型号
     */
    computedBasePriceData() {
      const model = this.computedPriceData.length
        ? this.computedPriceData[0]
        : {}
      // 属性‘1’里面是基础价格数据, 属性 ’2‘是打印价格数据
      if (model['1']) {
        return model['1'].slice()
      } else {
        return []
      }
    },
    // 当前型号位于基础价格数据的index, 用于取出型号对应的基础数据
    computedBasePriceIndex() {
      return this.computedBasePriceData.findIndex(
        item => item.id === this.model
      )
    },
    /**
     * 当前选中周期下, 商品对应的各型号打印价格.
     */
    computedPrintPriceData() {
      const model = this.computedPriceData.length
        ? this.computedPriceData[0]
        : {}
      // 属性‘1’里面是基础价格数据, 属性 ’2‘是打印价格数据
      if (model['2']) {
        return model['2'].slice()
      } else {
        return []
      }
    },

    // 其实没必要的, 只是方便html上不用读多一层属性 from.defaultAddr.****这样
    defaultAddr() {
      return this.form.defaultAddr
    },
    computedPriceTableColumns() {
      return this.priceTableColumns.concat(this.dynamicPriceTableColumns)
    },
    computedPriceTableData() {
      return this.priceTableData.map((item, index) =>
        Object.assign({}, item, this.dynamicPriceTableData[index] || {})
      )
    },
  },
  watch: {
    addressList() {
      const temp = this.addressList.filter(item => item.is_default === 1)
      if (temp.length) {
        this.form.defaultAddr = temp[0]
      } else if (this.addressList.length) {
        this.form.defaultAddr = this.addressList[0]
      } else {
        this.form.defaultAddr = {}
      }
      if (this.form.defaultAddr.post_code) {
        this.getFreight()
      }
    },
    'form.freight_type'() {
      this.getFreight()
    },
    'form.defaultAddr'() {
      this.getFreight()
    },
    buyForm: {
      deep: true,
      immediate: true,
      handler: function () {
        const temp = []
        if (!this.loaded) return temp
        this.dynamicPriceTableColumns = this.buyForm.map(item => {
          return {
            prop: `${item.value}`,
            buyNum: item.value,
          }
        })

        this.getDynamicPriceTableData()
      },
    },
    form2: {
      deep: true,
      immediate: true,
      handler: function () {
        this.getDynamicPriceTableData()
      },
    },
  },
  mounted() {
    if (localStorage.getItem('sellFreight')) {
      this.sellFreight = localStorage.getItem('sellFreight')
    }
    this.getAddressData().then(() => {
      this.loaded = true
    })
    this.getJobList()
  },
  methods: {
    checkForm() {
      return new Promise((resolve, reject) => {
        this.$refs.form.validate(valid => {
          if (valid) {
            resolve(JSON.parse(JSON.stringify(this.form)))
          } else {
            reject(new Error('validate step3 form error'))
          }
        })
      })
    },
    addToProject() {
      this.$emit('check', 1)
    },
    sendEnquiry() {
      this.$emit('check', 2)
    },
    // Job 下拉/输入框候选数据
    getJobList() {
      this.$axios
        .post('/goods_cart/cartLabelLists', { keyword: [] })
        .then(res => {
          this.jobOptions = res.result
        })
    },
    // 获取配送地址数据
    async getAddressData() {
      return await this.$axios
        .get('address/list', {
          params: {
            keyword: '',
            page: 1,
            limit: 100,
          },
        })
        .then(res => {
          if (res.code === 1) {
            this.addressList = res.result.data
            this.addressTotal = res.result.total
          }
        })
    },
    addAddress() {
      this.addressDetail = {}
      this.patternOfEditAddressDialog = 2
      this.visibleOfEditAddressDialog = true
    },
    closeAddressDialog() {
      this.visibleOfEditAddressDialog = false
    },
    selectAddress(data) {
      const temp = this.addressList.filter(item => item.id === data)
      if (temp.length) this.form.defaultAddr = temp[0]
      this.closeSelectAddressDialog()
    },
    closeSelectAddressDialog() {
      this.visibleOfSelectAddressDialog = false
    },
    getDynamicPriceTableData() {
      const temp = [
        {}, // unit
        {}, // setup 打印和附加价格之和
        {}, // print option
        {}, // addon 附加服务除了packing之外的总价
        {}, // packing / packaging
        {}, // fright 运费
        {}, // 汇总
      ]
      const ratio = plus(this.sellFreight / 100, 1)
      // { buyNum数量, prop标签label }
      this.dynamicPriceTableColumns.forEach(v => {
        const unitPrice = getUnit(
          v.buyNum,
          this.computedBasePriceIndex,
          this.priceData.attributeList,
          this.computedBasePriceData
        )
        temp[0][`${v.prop}`] = formatPrice(unitPrice)
        temp[0][`${v.prop}_value`] = unitPrice

        const setupPrice = getSetup(
          v.buyNum,
          this.form2,
          this.priceData.additionList
        )
        temp[1][`${v.prop}`] = formatPrice(setupPrice)
        temp[1][`${v.prop}_value`] = setupPrice

        const printPrice = getPrint(
          v.buyNum,
          this.form2,
          this.priceData.attributeList
        )
        temp[2][`${v.prop}`] = formatPrice(printPrice)
        temp[2][`${v.prop}_value`] = printPrice

        const addonPrice = getAddon(
          v.buyNum,
          this.form2,
          this.priceData.attributeList,
          this.priceData.additionList
        )
        temp[3][`${v.prop}`] = formatPrice(addonPrice)
        temp[3][`${v.prop}_value`] = addonPrice

        const packagingPrice = getPackaging(
          v.buyNum,
          this.form2,
          this.priceData.attributeList,
          this.priceData.additionList
        )
        temp[4][`${v.prop}`] = formatPrice(packagingPrice)
        temp[4][`${v.prop}_value`] = packagingPrice

        const frightPrice = getFright(
          v.buyNum,
          this.configInfo,
          this.freightInfo,
          this.weightInfo,
          ratio
        )
        temp[5][`${v.prop}`] = formatPrice(frightPrice)
        temp[5][`${v.prop}_value`] = frightPrice

        // 最后一行汇总行的数据
        const total = [
          temp[0][`${v.prop}_value`],
          temp[1][`${v.prop}_value`],
          temp[2][`${v.prop}_value`],
          temp[3][`${v.prop}_value`],
          temp[4][`${v.prop}_value`],
          temp[5][`${v.prop}_value`],
        ].reduce((total, curr) => {
          const value = Number(curr)
          if (total === 'POA' || curr === 'POA') {
            return 'POA'
          } else if (typeof value === 'number') {
            return plus(total, value)
          } else {
            return total
          }
        }, 0)

        temp[6][`${v.prop}`] =
          typeof total === 'number' ? formatPrice(total) : total
        temp[6][`${v.prop}_value`] = total
      })
      // console.log(temp, '计算动态表格数据')
      this.dynamicPriceTableData = temp
    },
    getFreight: _.debounce(function () {
      if (!this.form.defaultAddr.post_code) return
      this.freightLoading = true
      this.$axios
        .post('/quote/freight', {
          postcode: this.form.defaultAddr.post_code,
          type: this.form.freight_type,
        })
        .then(res => {
          this.freightInfo = res.result
          this.getDynamicPriceTableData()
        })
        .finally(() => {
          setTimeout(() => {
            this.freightLoading = false
          }, 300)
        })
    }, 200),
  },
}
</script>

<style lang="scss" scoped>
@import './step.scss';
div {
  box-sizing: border-box;
}
.btn-icon {
  font-size: 20px;
}
.address-text {
  font-size: 14px;
  line-height: 18px;
  color: #000;
  font-family: Proxima Nova, sans-serif;
  &.name {
    font-weight: bold;
  }
}
.price-title {
  height: 32px;
  padding: 0 8px;
  background: #f8f9fd;
  width: 100%;
  & > div {
    font-size: 16px;
    color: #000;
    font-family: Proxima Nova, sans-serif;
  }
}
.divide-solid {
  height: 4px;
  width: 100%;
  background-color: #a9aeba;
  margin: 10px auto 12px;
}
.price-table {
  :deep(.el-table) {
    font-family: Proxima Nova;
    &::before {
      background-color: transparent;
    }
    td.el-table__cell {
      font-size: 15px;
      border-bottom: 2px solid #dddcdc;
    }
    th.el-table__cell {
      font-weight: 600;
      font-size: 20px;
      color: #fff;
      background-color: #626469;
      border-bottom: none;
    }
  }
}
</style>
