<script lang="ts" setup>
/**
 * @Name: target-rule-setting
 * @Description: 自动化-规则定向-规则设置
 * @Author: Cheney
 */

import { ref, computed } from 'vue';
import { Plus } from '@element-plus/icons-vue';
import conditionBuilder from '/@/components/conditionBuilder/index.vue';
import InputFloat from '/@/components/input-float/index.vue';
import { useSymbolOptions } from '/@/components/conditionBuilder/utils';
import { ActionList, RuleNameMap } from './enum';
import XEUtils from 'xe-utils';

interface Props {
  rule: AutoRule;
  disabled?: boolean;
}

const props = defineProps<Props>();
const candidateFields = [
  { label: '曝光量', value: 'impressions' },
  { label: '点击量', value: 'clicks' },
  { label: '花费', value: 'spend', prefix: '$' },
  { label: '点击率', value: 'ctr', suffix: '%' },
  { label: '单次点击费用', value: 'cpc', prefix: '$' },
  { label: '转化率', value: 'cr', suffix: '%' },
  { label: '广告订单数', value: 'order' },
  { label: '广告销售额', value: 'sale', prefix: '$' },
  { label: 'ACOS', value: 'acos', suffix: '%' },
  {
    label: '定向匹配方式',
    value: 'matchType',
    type: 'array',
    options: [
      { label: '关键词-精确', value: 'exect' },
      { label: '关键词-广泛', value: 'broad' },
      { label: '关键词-词组', value: 'phrase' },
      { label: '商品-品类', value: 'category' },
      { label: '商品-单个商品', value: 'asin' },
    ],
  },
  { label: '关键词名称', value: 'keywords', type: 'array' },
];

const { getSymbolOptions } = useSymbolOptions(candidateFields);
const ruleFormRef = ref();
const condiBuilderRef = ref();
const actionModel = ref('bid-ratio');

const maxRuleNumber = computed(() => {
  const ret = {
    increase: 0,
    decrease: 0,
    set: 0,
    pause: 0,
  };
  for (const info of props.rule.conditions) {
    ret[info.actionType] = Math.max(ret[info.actionType] || 0, info.ordering);
  }
  return ret;
});

function checkFloat(rule: any, value: any, callback: any) {
  if (XEUtils.toNumber(value) <= 0) {
    callback(new Error('请输入大于0的数值！'));
  } else {
    callback();
  }
}

function checkMinMax(rule: any, value: any, callback: any) {
  if (XEUtils.toNumber(value) <= 0) {
    callback(new Error('请输入大于0的数值！'));
  } else {
    callback();
  }
}

function addRule(actionType: string, index: number = -1) {
  const field = candidateFields[0].value;
  const symbol = getSymbolOptions(field)[0].value;
  const rule = {
    action: { set: '', baseType: '', max: '', min: '', numType: 'ratio' },
    actionType: actionType,
    conditions: [
      {
        key: Math.random().toString(36).substring(2),
        day: 1,
        exceptDay: 0,
        items: [
          {
            dataType: field,
            dayType: symbol === 'in' || symbol === 'not_in' ? '' : 'sum',
            symbol: symbol,
            num: '',
            ranges: [],
            values: [],
          },
        ],
      },
    ],
    day: '1',
    exceptDay: '',
    ordering: maxRuleNumber.value[actionType] + 1,
    show: true,
  };
  if (index === -1) {
    props.rule.conditions.push(rule);
  } else {
    props.rule.conditions.splice(index + 1, 0, rule);
  }
}

if (props.rule.conditions.length === 0) {
  props.rule.campaignType = 'sp';
  props.rule.activeModel = 'campaign';
  addRule('increase', -1);
}

function delRule(index: number) {
  props.rule.conditions.splice(index, 1);
}

function changeAction(action: any) {
  const [a, b] = actionModel.value.split('-');
  action.baseType = a;
  action.numType = b;
  action.set = '';
}

async function validateConditionsForm() {
  const ret = [];
  for (const f of condiBuilderRef.value) {
    ret.push(await f.validate());
  }
  for (const validList of ret) {
    if (validList.includes(false)) {
      return false;
    }
  }
  return true;
}

async function validateRuleForm() {
  const ret = [];
  for (const f of ruleFormRef.value) {
    await f.validate((valid: boolean) => {
      ret.push(valid);
    });
  }
  return !ret.includes(false);
}

async function validateForm() {
  const valid1 = await validateRuleForm();
  const valid2 = await validateConditionsForm();
  return valid1 && valid2;
}

defineExpose({ validateForm });
</script>

<template>
  <div>
    <div class="asj-h3">
      <span class="custom-title-icon"></span>
      规则设置
    </div>
    <div class="rule-setting-container">
      <div v-for="(info, index) in rule.conditions" class="rule-setting-item" :key="info.actionType + info.ordering">
        <div class="rule-setting-title">
          <div class="asj-h3">{{ RuleNameMap[info.actionType] }} - 规则{{ info.ordering }}</div>
          <div class="rule-setting-opration">
            <el-tooltip content="添加规则" placement="top" effect="dark" v-if="!disabled">
              <el-icon @click="addRule(info.actionType, index)" :disabled="disabled">
                <Plus />
              </el-icon>
            </el-tooltip>
            <el-tooltip content="删除规则" placement="top" effect="dark" v-if="rule.conditions.length !== 1 && !disabled">
              <el-icon @click="delRule(index)">
                <DeleteFilled />
              </el-icon>
            </el-tooltip>
            <el-tooltip content="收起/展开规则" placement="top" effect="dark">
              <el-icon @click="info.show = !info.show">
                <ArrowDown />
              </el-icon>
            </el-tooltip>
          </div>
        </div>
        <div v-show="info.show">
          <el-form :inline="true" :model="info.action" ref="ruleFormRef" :disabled="disabled">
            <!-- 竞价规则下面的下拉框和两个输入框 -->
            <div v-if="info.actionType === 'increase' || info.actionType === 'decrease'">
              <el-form-item>
                <el-select v-model="actionModel" @change="changeAction(info.action)" style="width: 250px">
                  <el-option
                    v-for="item in ActionList"
                    :key="item.value"
                    :value="item.value"
                    :label="item.label.replace('_', info.actionType === 'increase' ? '升高' : '降低')">
                  </el-option>
                </el-select>
              </el-form-item>
              <el-form-item prop="set" :rules="{ validator: checkFloat }">
                <InputFloat
                  v-model="info.action.set"
                  :prefix="info.action.numType === 'num' ? '$' : ''"
                  :suffix="info.action.numType === 'ratio' ? '%' : ''"
                  style="width: 120px">
                </InputFloat>
              </el-form-item>
              <el-form-item label="最大值" v-if="info.actionType === 'increase'" prop="max" :rules="{ validator: checkMinMax }">
                <InputFloat v-model="info.action.max" style="width: 120px" prefix="$"></InputFloat>
              </el-form-item>
              <el-form-item label="最小值" v-else prop="min" :rules="{ validator: checkMinMax }">
                <InputFloat v-model="info.action.min" style="width: 120px" prefix="$"></InputFloat>
              </el-form-item>
            </div>
            <el-form-item v-if="info.actionType === 'set'" prop="set">
              <el-input v-model="info.action.set"></el-input>
            </el-form-item>
          </el-form>
          <conditionBuilder
            :data="info.conditions"
            :candidate-fields="candidateFields"
            ref="condiBuilderRef"
            :disabled="disabled" />
        </div>
      </div>
      <el-popover placement="bottom-start" trigger="hover" :disabled="disabled">
        <template #reference>
          <el-button :icon="Plus" type="warning" :disabled="disabled">添加规则</el-button>
        </template>
        <div class="popver-content">
          <span class="popver-content-item" v-for="[name, title] of Object.entries(RuleNameMap)" @click="addRule(name)">{{
            title
          }}</span>
        </div>
      </el-popover>
    </div>
  </div>
</template>

<style lang="scss" scoped>
.popver-content {
  display: flex;
  flex-direction: column;

  .popver-content-item {
    padding: 5px 0;

    &:hover {
      background-color: #f4f7fd;
      color: blue;
      cursor: pointer;
    }
  }
}

.rule-setting-container {
  .rule-setting-item {
    border: 1px solid #e0e0e0;
    margin: 10px auto;
    padding: 0 12px;
  }

  .rule-setting-title {
    display: flex;
    justify-content: space-between;
    align-items: center;

    .rule-setting-opration {
      display: flex;
      align-items: center;
      gap: 20px;

      .el-icon {
        cursor: pointer;
      }
    }
  }
}

.custom-title-icon {
  padding-right: 10px;
}

.custom-title-icon:before {
  content: '';
  width: 4px;
  height: 15px;
  background: #3569d6;
  position: absolute;
  transform: translateY(25%);
}
</style>
