<template>
  <div>
    <div class="search-bar">
      <el-select class="contrast" placeholder="选择对比项" clearable v-model="comparative.type" @change="getComparativeData">
        <el-option v-for="el in comparative.options" :key="el.value" :value="el.value" :label="el.label"></el-option>
      </el-select>
      <div class="contrast-box" v-if="comparative.type">
        <el-select class="contrast-selector" clearable v-model="comparative.subTypeLeft" @change="onSubComparativeChange">
          <el-option v-for="el in subOptions" :disabled="comparative.subTypeRight == el.key" :key="el.key" :value="el.key" :label="el.value"></el-option>
        </el-select>
        <span class="contrast-box-text">vs</span>
        <el-select class="contrast-selector" clearable v-model="comparative.subTypeRight" @change="onSubComparativeChange">
          <el-option v-for="el in subOptions" :disabled="comparative.subTypeLeft == el.key" :key="el.key" :value="el.key" :label="el.value"></el-option>
        </el-select>
      </div>
      <el-button v-if="comparative.type" type="text" @click="onClearComparative">清空对比项</el-button>
    </div>
    <el-table class="comparative-table" v-if="comparative.type && comparative.subTypeLeft && comparative.subTypeRight" :data="comparative.data" v-loading="comparative.loading">
      <el-table-column label="对比项" prop="comparativeType" min-width="160"></el-table-column>
      <el-table-column label="营销人数" prop="marketingNumber" min-width="100" :formatter="(row, col, val) => numFormat(val)"></el-table-column>
      <el-table-column label="触达人数" prop="reachNumber" min-width="100" :formatter="(row, col, val) => numFormat(val)"></el-table-column>
      <el-table-column label="触达率" prop="reachRate" min-width="90" :formatter="(row, col, val) => val || '--'"></el-table-column>
      <el-table-column label="转化人数" prop="conversionNumber" min-width="100" :formatter="(row, col, val) => numFormat(val)"></el-table-column>
      <el-table-column label="转化率" prop="conversionRate" min-width="90" :formatter="(row, col, val) => val || '--'"></el-table-column>
      <el-table-column label="转化销售额(元)" prop="conversionSale" min-width="120" :formatter="(row, col, val) => numFormat(val)"></el-table-column>
      <el-table-column label="客单价(元)" prop="perCustomerTransaction" min-width="100" :formatter="(row, col, val) => numFormat(val)"></el-table-column>
      <el-table-column label="连带率" prop="associatedPurchaseRate" min-width="70" :formatter="(row, col, val) => val || '--'"></el-table-column>
      <el-table-column label="活动费用(元)" prop="activityCost" min-width="110" :formatter="(row, col, val) => numFormat(val)"></el-table-column>
      <el-table-column label="ROI" prop="ROI" min-width="70" :formatter="(row, col, val) => val || '--'"></el-table-column>
    </el-table>
    <div class="chart-box">
      <div class="chart-member-count" id="chart-member-count">
        <svg aria-hidden="true" class="no-data-icon">
          <use xlink:href="#icon-cp-no-data"></use>
        </svg>
      </div>
      <el-row :gutter="20" class="target-list">
        <el-col :span="index == 0 ? 24 : 12" v-for="(el, index) in targetList" :key="index">
          <target-group :data-list="el"></target-group>
        </el-col>
      </el-row>
    </div>
  </div>
</template>

<script>
import G2 from '@antv/g2';
import DataSet from '@antv/data-set';
import { getPlanStatistics, getMemberCrowd, getComparativeData } from '@/service/api/aiApi.js';
import { numFormat } from '@/utils/index.js';
import TargetGroup from './target-group.vue';

export default {
  name: 'Conversion',
  props: {
    memberType: {
      type: Number,
      default: 0
    },
    filterJson: {
      type: String,
      default: ''
    }
  },
  components: { TargetGroup },
  data() {
    return {
      numFormat,
      activityId: '',
      planId: '',
      targetList: [
        [
          {
            label: '活动目标(销售额)',
            unit: '元',
            value: '',
            key: 'activityTargetSale',
            type: 'amount'
          },
          {
            label: '实际达成(销售额)',
            unit: '元',
            value: '',
            key: 'actualSale',
            type: 'amount'
          },
          {
            label: '实际达成率',
            value: '',
            key: 'actualReachRate',
            type: 'rate'
          }
        ],
        [
          {
            label: '活动费用',
            tips: '不包含短信发送失败退回金额',
            unit: '元',
            value: '',
            key: 'activityCost',
            type: 'amount'
          },
          {
            label: 'ROI',
            value: '',
            key: 'ROI',
            type: 'rate'
          }
        ],
        [
          {
            label: '客单价',
            unit: '元',
            value: '',
            key: 'perCustomerTransaction',
            type: 'amount'
          },
          {
            label: '连带率',
            value: '',
            key: 'associatedPurchaseRate',
            type: 'number'
          }
        ]
      ],
      comparative: {
        loading: false,
        originData: [],
        data: [],
        options: [],
        type: '',
        subTypeLeft: '',
        subTypeRight: ''
      }
    };
  },
  computed: {
    subOptions() {
      return this.comparative.options.find(el => el.value == this.comparative.type).children;
    }
  },
  created() {
    this.activityId = this.$route.params.id;
    this.planId = this.$route.query.planId;
    this.getPlanStatistics();
    this.getMemberCrowd();
  },
  methods: {
    getPlanStatistics() {
      getPlanStatistics({ activityId: this.activityId, planId: this.planId }).then(res => {
        if (!Array.isArray(res.result) || res.result.length == 0) {
          return;
        }
        const targetData = res.result[0];
        this.targetList = this.targetList.map(el => {
          return el.map(item => {
            const value = targetData[item.key];
            switch (item.type) {
              case 'number':
                item.value = numFormat(value);
                break;
              case 'amount':
                item.value = numFormat(value);
                break;
              case 'rate':
                item.value = value == null ? '--' : value;
                break;
            }
            return item;
          });
        });

        let data = [
          { action: '营销人数', label: '营销率', count: targetData.marketingNumber, rate: '' },
          { action: '触达人数', label: '触达率', count: targetData.reachNumber, rate: targetData.reachRate },
          { action: '转化人数', label: '转化率', count: targetData.conversionNumber, rate: targetData.conversionRate }
        ];
        const totalCount = data.reduce((total, el) => (total += el.count), 0);
        const dv = new DataSet.DataView().source(data);
        dv.transform({
          type: 'map',
          callback(row) {
            row.percent = row.count / totalCount;
            return row;
          }
        });
        data = dv.rows;
        document.getElementById('chart-member-count').innerHTML = '';
        const chart = new G2.Chart({
          container: 'chart-member-count',
          forceFit: true,
          height: 224,
          padding: [17, '30%', 0, '20%']
        });
        chart.source(data, {
          percent: { nice: false }
        });
        chart.axis(false);
        chart.legend(false);
        chart.tooltip({ showTitle: false });
        chart
          .coord('rect')
          .transpose()
          .scale(1, -1);
        chart
          .intervalSymmetric()
          .position('action*percent')
          .shape('funnel')
          .color('action', ['#2F54EB', '#597EF7', '#85A5FF'])
          .label(
            'label*rate',
            (label, rate) => {
              return rate ? label + ' ' + rate : '';
            },
            {
              offset: 35,
              labelLine: {
                lineWidth: 1,
                stroke: 'rgba(0, 0, 0, 0.15)'
              }
            }
          )
          .tooltip('action*count', (action, count) => {
            return { name: action + ' ' + numFormat(count) };
          });
        data.forEach(obj => {
          // 中间标签文本
          chart.guide().text({
            top: true,
            position: {
              action: obj.action,
              percent: 'median'
            },
            content: obj.action + ' ' + numFormat(obj.count), // 显示的文本内容
            style: {
              fill: '#fff',
              fontSize: '12',
              textAlign: 'center',
              shadowBlur: 2,
              shadowColor: 'rgba(0, 0, 0, .45)'
            }
          });
        });
        chart.render();
      });
    },
    getMemberCrowd() {
      getMemberCrowd({ memberCrowdWidgetId: this.filterJson }).then(res => {
        const filterFrontShow = JSON.parse(res.result.filterFrontShow || '[]');
        this.comparative.options = filterFrontShow
          .filter(el => el.columnKey != 'mainStoreId')
          .map(el => {
            // 对比项 1会员类型、2会员等级、3金字塔、4会员分组
            const valueMap = { wxMember: 1, gradeId: 2, tagGroup: 3 };
            return {
              label: el.chainNodeName,
              value: valueMap[el.columnKey],
              children: el.columnKey == 'wxMember' ? el.selectList : el.selectList.reduce((result, el) => result.concat(el.data), [])
            };
          });
      });
    },
    getComparativeData() {
      this.comparative.loading = true;
      // 对比项 1会员类型、2会员等级、3金字塔、4会员分组
      getComparativeData({ activityId: this.activityId, planId: this.planId, comparativeItem: this.comparative.type })
        .then(res => {
          this.comparative.originData = res.result || [];
        })
        .finally(() => (this.comparative.loading = false));
    },
    onComparativeChange() {
      if (!this.comparative.type) {
        this.comparative.subTypeLeft = '';
        this.comparative.subTypeRight = '';
        this.comparative.data = [];
        return;
      }
      this.getComparativeData();
    },
    onSubComparativeChange() {
      if (this.comparative.subTypeLeft && this.comparative.subTypeRight) {
        this.comparative.loading = true;
        setTimeout(() => {
          this.comparative.loading = false;
        }, 500);
        const subTypeLeft = this.subOptions.find(el => el.key == this.comparative.subTypeLeft).value;
        const subTypeRight = this.subOptions.find(el => el.key == this.comparative.subTypeRight).value;
        // 取出对比数据
        this.comparative.data = [];
        this.comparative.data.push(this.comparative.originData.find(el => el.comparativeType == subTypeLeft) || { comparativeType: subTypeLeft });
        this.comparative.data.push(this.comparative.originData.find(el => el.comparativeType == subTypeRight) || { comparativeType: subTypeRight });
      }
    },
    onClearComparative() {
      this.comparative.type = '';
      this.comparative.subTypeLeft = '';
      this.comparative.subTypeRight = '';
      this.comparative.data = '';
    }
  }
};
</script>

<style lang="scss" scoped>
.search-bar {
  display: flex;
  justify-content: flex-start;
  align-items: center;
  margin-top: 16px;
  .contrast {
    margin-right: 10px;
    width: 160px;
  }
  .contrast-box {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-right: 10px;
    width: 300px;
    border-radius: 2px;
    border: 1px solid #dcdfe4;
    .contrast-selector {
      margin-right: 0;
      /deep/ .el-input__inner {
        height: 30px;
        line-height: 30px;
        border: none;
      }
    }
    .contrast-box-text {
      font-size: 14px;
      font-weight: 500;
      color: #2f54eb;
      line-height: 20px;
    }
  }
}
.comparative-table {
  margin-top: 20px;
  /deep/ .el-table__empty-block {
    min-height: 120px;
    .el-table__empty-text {
      margin-bottom: 0;
      &::before {
        margin: 30px auto 0;
      }
    }
  }
}
.chart-box {
  display: flex;
  justify-content: flex-start;
  align-items: center;
  margin-top: 24px;
  .chart-member-count,
  .target-list {
    flex-shrink: 0;
    width: 50%;
    min-height: 272px;
  }
  .chart-member-count {
    text-align: center;
    .no-data-icon {
      width: 80px;
      height: auto;
      margin-top: 20px;
    }
  }
}
</style>
