<template>
  <el-card class="step-card">
    <div
      slot="header"
      class="flex between">
      <div class="step-card-title">Step1 Choose model</div>
      <div>&gt;&gt;</div>
    </div>
    <div v-loading="loading">
      <div class="card-sub-title">{{ detail.product_name }}</div>
      <image-viewer
        v-if="isBigImageShow"
        :on-close="closeBigImage"
        :initial-index="0"
        :url-list="detail.main?.images" />
      <div
        class="img-wrap flex center"
        @click="openBigImage">
        <img :src="detail.main?.image" />
      </div>
      <div class="divider"></div>
      <el-form
        :model="form"
        :rules="rules"
        label-width="90px"
        ref="form">
        <el-form-item
          label="Time frame"
          prop="cycle">
          <el-radio-group v-model="form.cycle">
            <el-radio
              v-for="item in priceData.priceList"
              :key="item.cycle_id"
              :label="item.cycle_id"
              >{{ item.name }}
            </el-radio>
          </el-radio-group>
        </el-form-item>

        <div class="flex">
          <el-form-item
            label-width="120px"
            label="Decorated in"
            prop="decorated">
            <el-select
              v-model="form.decorated"
              size="small">
              <el-option
                :label="'Local'"
                :value="'Local'"></el-option>
              <el-option
                :label="'China'"
                :value="'China'"></el-option>
            </el-select>
          </el-form-item>
          <el-form-item
            label-width="120px"
            prop="supplyChain"
            label="Supply chain"
            size="small">
            <el-select v-model="form.supplyChain">
              <el-option
                :label="'AU Stock'"
                :value="'AU Stock'"></el-option>
              <el-option
                :label="'Air Freight'"
                :value="'Air Freight'"></el-option>
              <el-option
                :label="'Sea Freight'"
                :value="'Sea Freight'"></el-option>
            </el-select>
          </el-form-item>
        </div>
        <el-form-item
          label="Model"
          prop="model">
          <div class="custom-checkbox-wrap">
            <div
              class="custom-checkbox"
              :class="{
                active: form.model === item.id,
                disable: form.model && form.model !== item.id,
              }"
              v-for="item in computedBasePriceData"
              @click="modelClick(item)"
              :key="item.id">
              {{ item.point }}
            </div>
          </div>
          <el-radio-group
            v-model="form.model"
            style="display: none"
            size="small">
            <el-radio-button
              v-for="item in computedBasePriceData"
              :key="item.id"
              :label="item.id"
              >{{ item.point }}</el-radio-button
            >
          </el-radio-group>
        </el-form-item>
        <el-form-item
          label="Colour"
          prop="color">
          <div class="custom-checkbox-wrap">
            <div
              class="custom-checkbox"
              :class="{
                active: form.color.includes(0),
              }"
              @click="colorClick({ id: 0 })">
              Unspecified
            </div>

            <div
              class="custom-checkbox flex"
              :class="{
                active: form.color.includes(item.id),
              }"
              v-for="item in detail.color"
              @click="colorClick(item)"
              :key="item.id">
              <div class="color-selector-label flex center">
                <img :src="item.img" />
              </div>
              <div>
                {{ item.name }}
              </div>
            </div>
            <div
              class="custom-checkbox"
              :class="{
                active: form.color.includes(999),
              }"
              @click="colorClick({ id: 999 })">
              + PMS
            </div>
          </div>
          <el-checkbox-group
            v-model="form.color"
            style="display: none"
            size="small">
            <el-checkbox-button :label="0">Unspecified</el-checkbox-button>
            <el-checkbox-button
              v-for="item in detail.color"
              :label="item.id"
              :key="item.id">
              {{ item.name }}
            </el-checkbox-button>
            <el-checkbox-button :label="999">+ PMS</el-checkbox-button>
          </el-checkbox-group>
        </el-form-item>
        <el-form-item prop="colorPmsText">
          <el-input
            v-show="form.color.includes(999)"
            type="textarea"
            :rows="5"
            placeholder="Product color comments. Multi color instructions, specific color matchong (CMYK, RGB, PMS) etc.."
            v-model="form.colorPmsText">
          </el-input>
        </el-form-item>

        <div class="qty-title">
          QTY&nbsp;(&nbsp;MOQ:{{ computedMinBuyNumber }}&nbsp;)
        </div>
        <div
          class="divider"
          v-show="form.color.length > 0"></div>
        <div class="flex wrap">
          <el-form-item
            class="flex-auto color-form-item"
            label-width="140"
            v-for="(formItem, index) in form.autoForm"
            :prop="`autoForm.${index}.value`"
            :rules="{
              required: true,
              trigger: 'change',
              type: 'number',
              message: 'the number should not less then MOQ',
              min: computedMinBuyNumber,
            }"
            :key="index">
            <div class="flex end">
              <div class="flex-auto flex end">
                <img
                  class="auto-form-color-image"
                  v-if="formItem.img"
                  :src="formItem.img"
                  alt="" />
                <div class="auto-form-label form-item-label">
                  {{ formItem.label }}
                </div>
              </div>
              <el-input
                @change="
                  value => {
                    if (value >= computedMinBuyNumber)
                      $refs.form.clearValidate(`autoForm.${index}.value`)
                  }
                "
                style="width: 80px"
                :min="computedMinBuyNumber"
                type="number"
                v-model.number="formItem.value"></el-input>
            </div>
          </el-form-item>
        </div>
      </el-form>
    </div>
  </el-card>
</template>

<script>
import imageViewer from 'element-ui/packages/image/src/image-viewer'
import stepMixin from './stepMixin'

export default {
  name: 'Step1',
  components: {
    'image-viewer': imageViewer,
  },
  mixins: [stepMixin],
  props: {
    // 步骤2的表单. 因其打印价格表单会反向影响本组件的最小起购数量, 故需从父组件获取. 只用来计算, 本组件不更改这个数据.
    form2: {
      type: Object,
      default: function () {
        return {}
      },
    },
  },
  data() {
    // this.detail 记录在mixin里;
    return {
      // 查看大图
      isBigImageShow: false,
      rules: {
        decorated: [{ required: true, message: '请选择', trigger: 'change' }],
        supplyChain: [{ required: true, message: '请选择', trigger: 'change' }],
        model: [
          {
            required: true,
            trigger: 'change',
            type: 'number',
            min: 1,
            message: 'Please select model',
          },
        ],
        color: [
          {
            required: true,
            validator: (rules, value, cb) => {
              value.length > 0
                ? cb()
                : cb(new Error('Please select at least one color'))
            },
            trigger: 'change',
          },
        ],
        colorPmsText: [{ trigger: 'blur', validator: this.checkColorPmsText }],
        cycle: [
          {
            required: true,
            message: 'Please select time frame',
            trigger: 'change',
          },
        ],
      },
      form: {
        // 必须要有的初始值, 否则必定会报错Cannot read properties of undefined
        color: [],
        model: 0,
        colorPmsText: '',
      },
      // 标志符,用于控制监听是否启用
      loaded: false,
    }
  },
  computed: {
    // 商品 当前选中周期的 基础价格和打印价格数据
    computedPriceData() {
      return this.priceData.priceList.filter(
        item => item.cycle_id === this.form.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.form.model
      )
    },
    // 该商品周期的最小起订量. attributeList的属性名(website_qty1, website_qty2)排序, 然后取属性值
    computedMinBuyNumber() {
      // 算基础价格的第一个有效值
      const target = this.computedBasePriceData.length
        ? this.computedBasePriceData[
            this.computedBasePriceIndex > 0 ? this.computedBasePriceIndex : 0
          ]
        : {}
      const candidate = [
        target.website_qty1,
        target.website_qty2,
        target.website_qty3,
        target.website_qty4,
        target.website_qty5,
        target.website_qty6,
        target.website_qty7,
        target.website_qty8,
      ]

      if (!candidate.some(item => item !== undefined)) return 1
      // 算出商品基础价格的第一个有效值
      let index = this.findEffectIndex(candidate)
      // 算出打印服务和附加服务的第一个有效价格所处位置.
      Object.entries(this.form2).forEach(current => {
        if (/\d+/.test(current[0])) {
          const decoration = current[1].decorationList.filter(
            i => i.id === current[1].printService
          )
          if (decoration.length && current[1].enable) {
            // 打印价格的基础阶梯价格
            const index2 = this.findEffectIndex([
              decoration[0].website_qty1,
              decoration[0].website_qty2,
              decoration[0].website_qty3,
              decoration[0].website_qty4,
              decoration[0].website_qty5,
              decoration[0].website_qty6,
              decoration[0].website_qty7,
              decoration[0].website_qty8,
            ])
            // 附加价格
            const index3 = this.findEffectIndex([
              decoration[0].supplier_qty1,
              decoration[0].supplier_qty2,
              decoration[0].supplier_qty3,
              decoration[0].supplier_qty4,
              decoration[0].supplier_qty5,
              decoration[0].supplier_qty6,
              decoration[0].supplier_qty7,
              decoration[0].supplier_qty8,
            ])
            // 让index记录最大值
            if (index2 > index) index = index2
            if (index3 > index) index = index3
          }
        } else {
          // 附加服务的价格
          const additions = this.priceData.additionList[current[0]].filter(
            item => current[1].includes(item.id)
          )

          if (additions.length) {
            additions.forEach(target => {
              const index4 = this.findEffectIndex([
                target.website_qty1,
                target.website_qty2,
                target.website_qty3,
                target.website_qty4,
                target.website_qty5,
                target.website_qty6,
                target.website_qty7,
                target.website_qty8,
              ])
              // 让index记录最大值
              if (index4 > index) index = index4
            })
          }
        }
      })

      const temp = Object.entries(this.priceData.attributeList)
        .sort((a, b) => a[0].localeCompare(b[0]))
        .filter((item, i) => index === i)

      if (temp.length) {
        return temp[0][1]
      } else {
        return 1
      }
    },
  },
  watch: {
    computedBasePriceData() {
      if (!this.loaded || !this.computedBasePriceData.length) return
      // fixme 如果有从商品详情页带过来的型号选择数据, 要选中该值, 而不是默认的第一个值
      if (
        this.computedBasePriceData.filter(i => i.id === this.preData.model)
          .length
      ) {
        this.form.model = this.preData.model
      } else {
        this.form.model = this.computedBasePriceData[0].id
      }
    },
    'form.model': {
      immediate: true,
      handler: function () {
        if (!this.loaded) return

        this.generateColorForm()
      },
    },
    'form.color': {
      immediate: true,
      handler: function () {
        if (!this.loaded) return

        this.generateColorForm()
        this.$refs.form.clearValidate('colorPmsText')
      },
    },
    form2: {
      immediate: true,
      handler: function () {
        if (!this.loaded) return

        this.generateColorForm()
      },
    },
  },
  mounted() {
    this.form = {
      supplyChain: 'AU Stock',
      decorated: 'Local',
      model: 0, // 型号的赋值在computedBasePriceData的监听里面, 因为其涉及到基础价格变更后的重新赋值.
      cycle: this.preData.cycle
        ? this.preData.cycle
        : this.priceData.priceList[0].cycle_id,
      color: [],
      colorPmsText: '',
      // 根据所选规格和颜色组合成的自动表单.需要在computedBasePriceData的watch里面生成
      autoForm: [],
    }

    this.loaded = true
  },
  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 step1 form error'))
          }
        })
      })
    },
    checkColorPmsText(rule, value, cb) {
      // fixme. 颜色的两个固定值的id还未确定
      if (!this.form.color.includes(999)) cb()

      if (this.form.colorPmsText.trim().length < 1) {
        cb(new Error('You must type color comment here if "+ PMS" is checked'))
      } else {
        cb()
      }
    },
    // 找出第一个有效价格的index. 非变异方法, 勿对参数进行赋值操作.
    // 价格留空和111不算到起购量, 为正常数值或者0或者999(POA)就可以算到起购量, 所以在此处将空手动重置为NaN
    findEffectIndex(array) {
      return array
        .map(item => (item === '' ? Number.NaN : Number(item)))
        .findIndex(item => !Number.isNaN(item) && item !== 111)
    },
    openBigImage() {
      this.isBigImageShow = true
    },
    closeBigImage() {
      this.isBigImageShow = false
    },
    generateColorForm() {
      if (!this.loaded || this.form.color.length < 1) {
        this.form.autoForm = []
        return
      }
      // 生成所选规格和颜色组合成的自动表单
      const targetModel = this.computedBasePriceData.filter(
        item => item.id === this.form.model
      )
      const oldForm = JSON.parse(JSON.stringify(this.form.autoForm))

      let color1 = []
      if (targetModel.length) {
        color1 = this.detail.color.reduce((total, item) => {
          if (this.form.color.includes(item.id)) {
            const temp = {
              img: item.img || '',
              label: `${item.name}, ${targetModel[0].point}`,
              color: item.name,
              colorId: item.id,
              value: this.computedMinBuyNumber,
            }
            const temp2 = oldForm.filter(item => item.label === temp.label)
            if (temp2.length && temp2[0].value >= this.computedMinBuyNumber) {
              // 如果原来有值且原值大于等于最小起购, 则沿用原值
              temp.value = temp2[0].value
            }
            total.push(temp)
          }
          return total
        }, [])
        if (this.form.color.includes(0)) {
          const temp = {
            img: '',
            label: `Unspecified, ${targetModel[0].point}`,
            color: 'Unspecified',
            colorId: -1,
            value: this.computedMinBuyNumber,
          }
          const temp2 = oldForm.filter(item => {
            return item.label === temp.label
          })
          if (temp2.length && temp2[0].value >= this.computedMinBuyNumber) {
            // 如果原来有值且原值大于等于最小起购, 则沿用原值
            temp.value = temp2[0].value
          }
          color1.unshift(temp)
        }
        if (this.form.color.includes(999)) {
          const temp = {
            img: '',
            label: `+ PMS, ${targetModel[0].point}`,
            color: 'PMS',
            colorId: -1,
            value: this.computedMinBuyNumber,
          }
          const temp2 = oldForm.filter(item => item.label === temp.label)
          if (temp2.length && temp2[0].value >= this.computedMinBuyNumber) {
            // 如果原来有值且原值大于等于最小起购, 则沿用原值
            temp.value = temp2[0].value
          }
          color1.push(temp)
        }
      }
      this.$set(this.form, 'autoForm', color1)
    },
    modelClick(item) {
      if (this.form.model === item.id) {
        this.form.model = 0
      } else {
        this.form.model = item.id
      }
    },
    colorClick(item) {
      const index = this.form.color.indexOf(item.id)
      if (index !== -1) {
        this.form.color.splice(index, 1)
      } else {
        this.form.color.push(item.id)
      }
    },
  },
}
</script>

<style lang="scss" scoped>
@import './step.scss';
div {
  box-sizing: border-box;
}
.img-wrap {
  $width: 140px;
  width: $width;
  height: $width;
  position: relative;
  padding: 4px;
  border: 1px solid #eee;
  cursor: pointer;
  margin-bottom: 16px;
  img {
    width: 100%;
  }
}
.el-checkbox-button {
  min-width: 76px;
}
.qty-title {
  margin-bottom: 16px;
  font-size: 14px;
  font-family: Proxima Nova, sans-serif;
  color: #000;
}
// 选择颜色
.color-selector-label {
  width: 16px;
  height: 16px;
  position: relative;
  margin-right: 4px;
  img {
    width: 100%;
  }
}
// 颜色型号对应购买数量输入项
.color-form-item {
  box-sizing: border-box;
  max-width: 50%;
  padding-left: 4px;
  .auto-form-label {
    text-align: right;
    padding: 0 12px;
    min-width: 140px;
  }
  :deep(.el-form-item__error) {
    text-align: right;
    width: 100%;
  }
  .auto-form-color-image {
    width: 20px;
    height: 20px;
    margin-right: -4px;
  }
}
</style>