<template>
  <div>
    <el-card>
      <template slot="header">
        <div
          class="card-title"
          v-if="currentTicket">
          <span>当前票种：<b>{{ currentTicket.name || '无' }}</b></span>

          <div>{{ form.payDateBegin | formatDate }} 票价：<span class="price"><b>{{ currentPrice }}</b> 元</span></div>
        </div>
        <span
          v-else
          style="color:red">请选择门票</span>
      </template>

      <el-form
        v-loading="loading"
        class="sale-form-wrap"
        ref="form"
        :model="form"
        :inline="true"
        label-width="100px">
        <el-form-item
          verify
          can-be-empty
          label="顾客姓名"
          prop="buyer_name">
          <el-input
            v-model="form.buyer_name"></el-input>
        </el-form-item>
        <el-form-item
          can-be-empty
          :verify="verifyPhone"
          label="顾客电话"
          prop="buyer_phone">
          <el-input
            v-model="form.buyer_phone"></el-input>
        </el-form-item>
        <el-form-item
          label="证件类型"
          prop="buyer_papers_type">
          <el-select
            :disabled="identify_lockCheckStyle"
            v-model="form.buyer_papers_type"
            placeholder="请选择">
            <el-option
              v-for="(item,key) in papersType"
              :key="key"
              :label="item"
              :value="key">
            </el-option>
          </el-select>
          <el-checkbox
            style="margin-left:10px"
            v-model="identify_lockCheckStyle">
            锁定
          </el-checkbox>
        </el-form-item>
        <el-form-item
          key="id1"
          :verify="verifyId"
          can-be-empty
          v-if="form.buyer_papers_type==='ID_CARD'"
          label="证件号码"
          prop="buyer_identify">
          <ReaderInput
            type="ID"
            @change="form.buyer_name=$event.Name"
            v-model="form.buyer_identify"></ReaderInput>
        </el-form-item>
        <el-form-item
          v-else
          key="id2"
          label="证件号码"
          prop="buyer_identify">
          <el-input v-model="form.buyer_identify"></el-input>
        </el-form-item>
        <el-form-item
          v-if="currentTicket && currentTicket.is_need_playtime"
          verify
          prop="payDateBegin"
          label="游玩日期">
          <el-date-picker
            :clearable="false"
            :editable="false"
            :picker-options="dateOption"
            v-model="form.payDateBegin"
            type="date"
          >
          </el-date-picker>
        </el-form-item>
        <el-form-item
          v-if="currentTicket && currentTicket.is_need_playtime"
          label="结束日期">
          <el-input
            disabled
            v-model="playEndDate"
          ></el-input>
        </el-form-item>
        <el-form-item
          verify
          number
          label="购买数量"
          prop="count"
        >
          <el-input-number
            ref="ticketCount"
            name="ticket-count"
            v-model.number="form.count"
            :min="1"
            :max="10000"
            :precision="0"
          ></el-input-number>
        </el-form-item>
        <el-form-item
          label="检票方式"
          prop="checkWay">
          <el-select
            v-model="form.checkWay"
            :disabled="retail_lockCheckStyle">
            <el-option
              v-for="item in checkWayList"
              :key="item.val"
              :value="item.val"
              :label="item.name"
            ></el-option>
          </el-select>
          <el-checkbox
            style="margin-left:10px"
            v-model="retail_lockCheckStyle">
            锁定
          </el-checkbox>
        </el-form-item>
        <el-form-item
          label="价格方案">
          <el-select
            v-model="currentPlan"
            v-if="pricePlan.length">
            <el-option
              v-for="item in pricePlan"
              :key="item.id"
              :label="item.name"
              :value="item.id">
            </el-option>
          </el-select>
        </el-form-item>

        <el-form-item
          v-if="currentTicket && currentTicket.discount"
          label="折扣">
          <el-input-number
            controls-position="right"
            v-model="currentTicket.discount">
          </el-input-number>折
        </el-form-item>
        <el-form-item
          v-if="currentTicket && currentTicket.discount_rule"
          label="优惠策略">
          <el-input
            disabled
            :value="'满 '+man+' 减 '+jian"></el-input>
          <!-- <el-input
            v-model="currentTicket.discount_rule"
            :disabled="true"></el-input> -->
          <!-- <span> &nbsp;满{{ man }}减{{ jian }}</span> -->
        </el-form-item>
        <el-form-item
          verify
          number
          label="优惠价">
          <el-input-number
            :min="0"
            :precision="2"
            controls-position="right"
            v-model.number="manualPrice"></el-input-number>
          元
        </el-form-item>
        <el-form-item label="订单标签">
          <el-select
            v-model="form.order_tag"
            clearable>
            <el-option
              v-for="item in order_tag_list"
              :key="item"
              :label="item"
              :value="item">
            </el-option>
          </el-select>
        </el-form-item>
        <!-- v-if="form.checkWay === 3 || form.checkWay === 4" -->
        <el-form-item
          label="游客信息"
        >
          <div
            v-if="currentTicket"
            class="input-space"
          >
            <el-button
              type="primary"
              size="small"
              icon="el-icon-edit"
              @click="showTouristList"
            >
              编辑查看
            </el-button>
          </div>
        </el-form-item>
      </el-form>

      <div class="btn-wrap">
        <el-button
          @click="resetForm"
          style="margin-right:20px">
          重置表单
        </el-button>
        <el-button
          type="primary"
          @click="addToOrder">
          加入订单
        </el-button>
      </div>
    </el-card>

    <!-- 游客列表 -->
    <TouristList
      :check-ticket-no="form.checkWay === 5"
      :check-face="form.checkWay === 4"
      :check-id="form.checkWay === 3"
      :tourist-list="touristList"
      :update-tourist="updateTourist"
      ref="touristList"></TouristList>
  </div>
</template>

<script>
import { randomString } from '@/utils'
import { verifyId, verifyPhone } from '@/utils/validate'
import { papersType, checkWayList } from '@/assets/staticData'
import { getTicketTypeInfo } from '@/api/ticketType'
import { getTicketPricePlanList } from '@/api/ticketPricePlan'
import { getSystemConfigList } from '@/api/systemConfig'
import { setTourist } from '@/pages/common'

import TouristList from '../common/TouristList'
import ReaderInput from '@/components/ReaderInput'
import moment from 'moment'

export default {
  props: {
    currentTicket: {
      type: Object,
      default: () => null
    },
    orderItems: {
      type: Array,
      default: () => []
    }
  },
  components: {
    TouristList,
    ReaderInput
  },
  computed: {
    totalPrice () {
      if (!this.currentTicket) {
        return 0
      }
      return this.$NP.times(this.currentPrice, this.form.count)
    },
    // 计算总共多少张票
    totalCount () {
      return this.orderItems.reduce((init, item) => {
        return init + item.count
      }, 0)
    },
    // 计算当前票种总共多少张票（totalCount包含各票种的总数）
    totalCountOfCurrentType () {
      return this.orderItems.filter(item => item.id === this.currentTicket.id).reduce((init, item) => {
        return init + item.count
      }, 0)
    },
    scenicName () {
      return this.$store.state.user.scenicName
    }
  },
  data () {
    return {
      loading: false,
      keyControl: 2, // 键盘控制：1,2,3标识选中顺序
      isFocus: false, // 当前组件是否选中
      papersType,
      checkWayList,
      pricePlan: [],
      playEndDate: '',
      currentPrice: 0,
      currentPlan: null,
      retail_lockCheckStyle: this.$localStore.get('retail_lockCheckStyle') || false,
      identify_lockCheckStyle: this.$localStore.get('identify_lockCheckStyle') || false,
      required_field: [],

      touristList: [{
        idKey: randomString(),
        guestName: '',
        guestPhone: '',
        guestIdentify: '',
        guest_papers_type: 'ID_CARD',
        lock: false // 是否可编辑
      }],
      form: {
        order_tag: '',
        buyer_identify: '',
        buyer_name: '',
        buyer_papers_type: this.defaultPapersType(),
        buyer_phone: '',
        group_individual: 1,
        count: this.$localStore.get('initNum') === '空' ? undefined : 1,
        payChannel: '现金',
        payDateBegin: new Date(moment().startOf('day').valueOf()),
        play_date_end: '',
        price: 0,
        checkWay: this.$localStore.get('retail_checkWay') || 1,
        actualMoney: 0 // 实付金额，不需要传给后台
      },
      man: 0, // 满x
      jian: 0, // 减y
      manualPrice: 0, // 优惠价
      order_tag_list: [],
      dateOption: {
        // 日历禁用日期
        disabledDate () {
          return false
        }
      }
    }
  },
  async created () {
    this.getTicketPricePlanList()
    const res = await getSystemConfigList()
    /*
    const order_tag_list = res.list.find(v => v.config_key === 'order_tag_list')?.config_value || []
    this.order_tag_list = order_tag_list.replace(/\s+/g, '').split(',')
    */
    this.order_tag_list = res.list.find(v => v.config_key === 'order_tag_list')?.config_value?.replace(/\s+/g, '')?.split(',') || []
  },
  methods: {
    verifyId,
    verifyPhone,
    randomString,
    // 从满10减1这种字符串里提取出10和1
    parseDiscountRule (discountRule) {
      let pattern = /满(\d+)减(\d+)/ // 定义正则表达式
      let match = discountRule.match(pattern) // 使用 match() 方法匹配字符串
      if (match) {
        let man = parseInt(match[1]) // 第一个括号中的数字为满减条件
        let jian = parseInt(match[2]) // 第二个括号中的数字为满减金额
        return { man, jian }
      }
      return null // 如果匹配失败，则返回 null
    },
    getCheckWayValByName (name) {
      // const checkWayList = [
      //   { name: '一码一人', val: 1 },
      //   { name: '一码多人', val: 2 },
      //   { name: '身份证入园', val: 3 },
      //   { name: '人脸入园', val: 4 },
      //   { name: '预印票', val: 5 }
      // ];
      // 由'一码多人'得到2
      const item = checkWayList.find(item => item.name === name)
      return item ? item.val : undefined
    },
    getTicketPricePlanList () {
      getTicketPricePlanList({ keyWords1: 1, pageNum: 0, pageSize: 0 }).then(res => {
        this.pricePlan = res.list

        this.pricePlan.unshift({
          id: null,
          name: '无'
        })
      })
    },
    setFocus () {
      this.$refs.ticketCount.focus()
      this.$refs.ticketCount.select()
    },
    FormResetFields_fix () { // resetForm里的this.$refs.form.resetFields()会执行失败，导致左侧切换时日期不正常，这里临时代替
      let iform = {
        buyer_identify: '',
        buyer_name: '',
        buyer_papers_type: this.defaultPapersType(),
        buyer_phone: '',
        group_individual: 1,
        count: this.$localStore.get('initNum') === '空' ? undefined : 1,
        payChannel: '现金',
        payDateBegin: new Date(moment().startOf('day').valueOf()),
        play_date_end: '',
        price: 0,
        checkWay: this.$localStore.get('retail_checkWay') || 1,
        actualMoney: 0 // 实付金额，不需要传给后台
      }
      this.form = iform // 手动设为初始值，因为resetFields()会导致之后的语句不执行
    },
    resetForm () {
      this.touristList = [{
        idKey: randomString(),
        guestName: '',
        guestPhone: '',
        guestIdentify: '',
        guest_papers_type: 'ID_CARD',
        lock: false // 是否可编辑
      }]
      console.log('resetFields执行前')
      /* this.$refs.form.resetFields() */
      // 实测this.$refs.form.resetFields()会导致后面的语句不执行，从而watch里currentTicket函数中改日期的语句也不执行，故换成手动重置表单
      this.FormResetFields_fix()
      console.log('resetFields执行后')
      this.form.checkWay = this.$localStore.get('retail_checkWay') || 1
    },
    setEndDate () {
      let endDate = moment(this.form.payDateBegin).add(this.currentTicket.use_valid_days - 1, 'days').endOf('day').valueOf()
      this.form.play_date_end = new Date(endDate)
      this.playEndDate = moment(endDate).format('YYYY-MM-DD')
    },
    // 更新游客列表
    updateTourist (data) {
      this.form.count = data.length
      this.touristList = data
    },
    // 同步游客数据与游客数
    syncTouristList () {
      let num = this.form.count - this.touristList.length
      setTourist(this.touristList, num)
    },
    // 显示游客弹窗
    showTouristList () {
      this.syncTouristList()
      this.$refs.touristList.show()
    },
    isPlayToday () {
      let isbefore = moment(this.form.payDateBegin).isBefore(moment().format('YYYY-MM-DD'))
      let isafter = moment(this.form.payDateBegin).isAfter(moment().format('YYYY-MM-DD'))
      return (!isbefore) && (!isafter)
    },
    addToOrder (callback) {
      if (!this.isPlayToday()) {
      // 客户端下单的时候游玩日期不是当天，提示一下
        this.$message.warning('友情提示：您下单的游玩日期不是今天！')
      }

      if (!this.currentTicket) {
        return this.$message.error('请选择门票')
      }

      if (this.loading) return

      // 校验当前票种与价格是否一致
      if (this.priceObj.id !== this.currentTicket.id) {
        this.setPrice()
        return
      }

      this.$refs.form.validate((valid) => {
        if (valid) {
          this.$localStore.set('checkWay', this.form.checkWay)

          this.syncTouristList()

          let { payDateBegin, play_date_end } = this.form

          let { id, name, check_count } = this.currentTicket

          let price = this.currentPrice

          if (this.form.checkWay === 3) {
            // 是否存在未填写的内容
            let blankData = this.touristList.find(item => {
              return !item.guestName || !item.guestIdentify
            })
            if (blankData) {
              this.$message.error('游客信息不完整，请编辑查看')
              return
            }
          }

          if (this.form.checkWay === 4) {
            // 是否存在未填写的内容
            let blankData = this.touristList.find(item => {
              return !item.face
            })
            if (blankData) {
              this.$message.error('游客人脸信息不完整，请编辑查看')
              return
            }
          }

          if (this.required_field && this.required_field.length && this.required_field.includes('name')) {
            let blankData = this.touristList.find(item => {
              return !item.guestName
            })
            if (blankData) {
              this.$message.error('游客姓名不完整，请编辑查看')
              return
            }
          }

          if (this.required_field && this.required_field.length && this.required_field.includes('papers_id')) {
            let blankData = this.touristList.find(item => {
              return !item.guestIdentify
            })
            if (blankData) {
              this.$message.error('游客证件号不完整，请编辑查看')
              return
            }
          }

          let tickets = this.touristList.map(item => {
            return {
              ticket_type_id: id,
              check_num: check_count,
              price: this.currentPrice,
              guestName: item.guestName,
              guestPhone: item.guestPhone,
              guestIdentify: item.guestIdentify,
              guest_papers_type: item.guest_papers_type,
              ticket_no: item.ticket_no,
              face: item.face,
              price_plan_id: this.currentPlan || 0,
              payDateBegin: this.currentTicket.is_need_playtime ? payDateBegin : null,
              play_date_end: this.currentTicket.is_need_playtime ? play_date_end : null,
              is_discount: this.currentTicket.is_discount
            }
          })

          // 合并游玩日期相同的票种数据
          const existItem = this.orderItems.find(i => {
            let dateIsEque
            if (this.currentTicket.is_need_playtime) {
              dateIsEque = JSON.stringify(i.payDateBegin) === JSON.stringify(payDateBegin)
            } else {
              dateIsEque = true
            }
            // 日期对象不全等
            return i.id === this.currentTicket.id && dateIsEque && i.price === this.currentPrice
          })

          if (existItem) {
            existItem.tickets = existItem.tickets.concat(tickets)
            existItem.count = existItem.tickets.length
            existItem.total = this.$NP.plus(existItem.total, this.totalPrice)
          } else {
            this.orderItems.push({
              keyId: randomString(), // 唯一标识
              id, // 票种Id
              ticketName: name,
              count: tickets.length,
              price,
              total: this.totalPrice,
              payDateBegin: this.currentTicket.is_need_playtime ? payDateBegin : null,
              currentTicket: { ...this.currentTicket, price_plan_id: this.currentPlan, price, payDateBegin, play_date_end },
              tickets
            })
          }

          // 重置游客数量
          this.touristList = [{
            idKey: randomString(),
            guestName: '',
            guestPhone: '',
            guestIdentify: '',
            guest_papers_type: 'ID_CARD',
            lock: false // 是否可编辑
          }]

          this.form.count = this.$localStore.get('initNum') === '空' ? undefined : 1

          if (callback && typeof callback === 'function') {
            callback()
          }

          this.$nextTick(() => {
            this.$refs.form.clearValidate()
          })
        }
      })
    },
    setPrice () {
      if (!this.currentTicket) {
        this.currentPrice = 0
        return
      }
      this.loading = true
      getTicketTypeInfo({
        planId: this.currentPlan,
        id: this.currentTicket.id,
        start: moment(this.form.payDateBegin).format('YYYY-MM-DD'),
        end: moment(this.form.payDateBegin).format('YYYY-MM-DD')
      }).then(res => {
        this.priceObj = res?.data

        let original_currentPrice = res?.data.prices[0]
          ? (res?.data.prices[0].price === null ? this.currentTicket.price : res?.data.prices[0].price)
          : this.currentTicket.price
        /* 昭苏打折，注意discount默认是10即打十折，需要乘以0.1 */
        let isValidDiscount = this.currentTicket && this.currentTicket.discount && this.currentTicket.discount > 0 && this.currentTicket.discount <= 10
        this.currentPrice = isValidDiscount ? (original_currentPrice * (this.currentTicket.discount * 0.1)) : original_currentPrice
        this.manualPrice = this.currentPrice // 设置优惠价初始价格为折扣价，允许后期修改
      }).finally(() => {
        this.loading = false
      })
    },
    defaultPapersType () {
      if (process.env.VUE_APP_PROJECT === 'zql') {
        return 'ID_CARD'
      } else if (this.$localStore.get('retail_identify')) {
        return this.$localStore.get('retail_identify')
      } else {
        return ''
      }
    }

  },
  watch: {
    'currentTicket.discount' (val) {
      // 现在需要能手动修改折扣,除了在初始获取时设置,也要在折扣手动变动时设置 (打x折)
      let original_currentPrice = this.currentTicket.price
      let isValidDiscount = this.currentTicket && this.currentTicket.discount && this.currentTicket.discount > 0 && this.currentTicket.discount <= 10
      this.currentPrice = isValidDiscount ? (original_currentPrice * (this.currentTicket.discount * 0.1)) : original_currentPrice
      this.manualPrice = this.currentPrice // 设置优惠价初始价格为折扣价，允许后期修改
    },
    currentTicket (val) {
      if (!val) return

      this.resetForm()

      // 设置初始日期
      if (moment(val.use_startdate).isAfter(new Date())) {
        this.form.payDateBegin = val.use_startdate
      } else {
        this.form.payDateBegin = new Date(moment().startOf('day').valueOf())
      }
      // 设置不可选日期
      this.dateOption.disabledDate = (date) => {
        let beforeToday = moment().subtract(1, 'days').isAfter(date)
        let beforeStart = moment(val.use_startdate).isAfter(date)
        let afterEnd = moment(val.use_enddate).isBefore(date)
        return beforeToday || beforeStart || afterEnd
      }

      this.timer && clearTimeout(this.timer)
      this.timer = setTimeout(() => {
        this.setPrice()
      }, 300)

      if (val.required_field) {
        this.required_field = JSON.parse(val.required_field)
      } else {
        this.required_field = []
      }
    },
    retail_lockCheckStyle (val) {
      if (val) {
        this.$localStore.set('retail_checkWay', this.form.checkWay)
      }
      this.$localStore.set('retail_lockCheckStyle', val)
    },
    identify_lockCheckStyle (val) {
      if (val) {
        this.$localStore.set('retail_identify', this.form.buyer_papers_type)
      }
      this.$localStore.set('identify_lockCheckStyle', val)
    },
    'form.payDateBegin' (val) {
      if (val) {
        this.setEndDate()
        this.currentPlan = null
        this.timer && clearTimeout(this.timer)
        this.timer = setTimeout(() => {
          this.setPrice()
        }, 300)
      }
    },
    'currentTicket.discount_rule' (e) {
      let result = this.parseDiscountRule(e)
      this.man = result ? result.man : this.man
      this.jian = result ? result.jian : this.jian
    },
    'currentTicket.id' (e) {
      this.man = 0
      this.jian = 0
      if (this.currentTicket.discount_rule) {
        let result = this.parseDiscountRule(this.currentTicket.discount_rule)
        this.man = result ? result.man : this.man
        this.jian = result ? result.jian : this.jian
      }
    },
    'man' (e) {
      console.log('满', e)
    },
    'jian' (e) {
      console.log('减', e)
    },
    // 当前票种的张数变化（不要watch所有票）
    'totalCountOfCurrentType' (e) {
      console.log('当前票种目前共有', e, '张票')
      let ticketNum_currentType = e // 当前票种的票数，根据它去满减当前票种
      // 限制为‘在当前票种’的票里，令 totalFreeTicketNum_currentType 张票的价为0
      let setItemFreeTickets = (item, totalFreeTicketNum_currentType) => {
        // 计算当前票种能免费的票数，这个item代表orderItems数组里当前票种的元素
        const freeTicketNum_currentType = Math.min(totalFreeTicketNum_currentType, item.tickets.length)
        // 更新总共能免费的票数
        totalFreeTicketNum_currentType -= freeTicketNum_currentType
        // 将前 freeTicketNum_currentType 张票的价格设为0
        for (let i = 0; i < freeTicketNum_currentType; i++) {
          const ticket = item.tickets[i]
          ticket.price = 0
        }
        item.total = this.$NP.times(item.tickets.length - freeTicketNum_currentType, item.price)
        return item
      }
      // 添加满减逻辑
      if (ticketNum_currentType >= this.man && this.man !== 0) {
        // 计算总共能免多少张票
        const totalFreeTicketNum_currentType = Math.floor(ticketNum_currentType / this.man) * this.jian
        console.log(`当前票种总共能免${totalFreeTicketNum_currentType}张票`)
        // 之前错误地将 orderItems 里totalFreeTicketNum_currentType 张票的价格设置为 0（并且此时的this.jian并非之前票种的jian）(所以错误地更新了其他票种的total)
        // 实际应该只更新 orderItems 里当前票种的，也就是不要动之前加入订单的票种。只更新和目前票种id一致的
        console.log('当前票种id', this.currentTicket.id)
        // 在orderItems找到当前票种，只更新orderItems里的当前票种的票们；不修改orderItems里之前的其他票种的票
        const index = this.$parent.$parent.orderItems.findIndex(item => item.id === this.currentTicket.id) // 找到元素索引
        if (index !== -1) { // 在orderItems找到了当前票种的元素
          let currentItemOforderItems = this.$parent.$parent.orderItems[index]
          this.$parent.$parent.orderItems[index] = setItemFreeTickets(currentItemOforderItems, totalFreeTicketNum_currentType) // 直接修改元素
        }
        console.log('减免后的this.$parent.$parent.orderItems:', this.$parent.$parent.orderItems)
      }
      // 先判断订单总价是否超过了满减门槛 this.man，如果超过了，就计算可减免的票数?
      // 然后将其中当前票种?张票的价格设为零，并重新计算订单项的总价。
      // 注意，最后一个订单项的票不一定都够 reduceCount 张，所以需要使用 Math.min() 方法来取两者的最小值。
    },
    'manualPrice' (e) {
      // this.manualPrice = e
      this.currentPrice = this.manualPrice // 优惠价
      /* 原有的不兼容满减的逻辑
          this.$parent.$parent.orderItems.forEach(item => {
            if (item.id === this.currentTicket.id) {
              item.price = e
              item.total = this.$NP.times(item.tickets.length, e)
              item.tickets.forEach(t => {
                t.price = e
                t.discount = Math.round(e / t.original_price * 100)
              })
            }
          })
      */
      // 优惠价考虑与满减兼容,满减会把一些票的票价置为0,优惠价不能改这部分为0的票的价钱
      // item.tickets里面有price属性，你用js的函数式计算出tickets里面的price加起来，不要使用乘法
      this.$parent.$parent.orderItems.forEach(item => {
        if (item.id === this.currentTicket.id) {
          item.price = e
          // item.total = this.$NP.times(item.tickets.length, e)
          item.tickets.forEach(t => {
            t.price = (t.price === 0) ? 0 : e // 不改动满减设的0
            t.discount = Math.round(e / t.original_price * 100)
          })
          let item_manjian_total = item.tickets.reduce((prev, curr) => prev + curr.price, 0)
          item.total = item_manjian_total /* 注意,这里的总价依赖之前设的优惠之后的票价,故需要放在item.price设完之后 */
        }
      })
    },
    currentPlan () {
      this.setPrice()
    }
  }
}
</script>

<style lang="scss" scoped>
.el-input,.el-select,.el-date-editor,.el-date-editor.el-input,.el-input-number {
  width: 200px;
}

</style>
