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

import { computed, ref } from 'vue';
import { Bottom, InfoFilled, Plus, Top } 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 isVisible = ref(true);
const setting = ref('edit');

const { getSymbolOptions } = useSymbolOptions(candidateFields);
const maxIsDisabled = ref([]);
const minIsDisabled = ref([]);
const ruleFormRef = ref();
const condiBuilderRef = ref();
const actionModel = ref([]);
let ruleInfo = {};

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;
});

onBeforeMount(() => {
  watch(() => props.rule, (newRule) => {
    ruleInfo = newRule.conditions[0].action;
    actionModel.value = newRule.conditions.map(condition => condition.action.baseType + '-' + condition.action.numType);
    if (!actionModel.value) {
      props.rule.campaignType = 'sp';
      props.rule.activeModel = 'campaign';
      addRule('increase', -1);
    }
  });
  // 已有数据
  if (props.rule.id) {
    actionModel.value = props.rule.conditions.map(condition => condition.action.baseType + '-' + condition.action.numType);
  } else {
    props.rule.campaignType = 'sp';
    props.rule.activeModel = 'campaign';
    addRule('increase', -1);
  }
});

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();
//   }
// }

async function addRule(actionType: string, index: number = -1) {
  const field = candidateFields[0].value;
  const symbol = getSymbolOptions(field)[0].value;
  const rule = {
    action: { set: '', baseType: 'bid', 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);
    if (actionType === 'increase') {
      actionModel.value.push('bid-ratio');
      maxIsDisabled.value.push(ruleInfo.max !== '' && ruleInfo.max !== undefined);
    } else if (actionType === 'decrease') {
      actionModel.value.push('bid-ratio');
      minIsDisabled.value.push(ruleInfo.min);
    }
  } else {
    props.rule.conditions.splice(index + 1, 0, rule);
    maxIsDisabled.value.splice(index + 1, 0, false); // 添加一个初始值
    actionModel.value.splice(index + 1, 0, 'bid-ratio'); // 添加一个初始值
    minIsDisabled.value.splice(index + 1, 0, false); // 添加一个初始值
  }
}

function delRule(actionType: string, index: number) {
  props.rule.conditions.splice(index, 1);
  if (actionType === 'increase') {
    maxIsDisabled.value.splice(index, 1);
    actionModel.value.splice(index, 1);
  } else if (actionType === 'decrease') {
    minIsDisabled.value.splice(index, 1);
    actionModel.value.splice(index, 1);
  }
}

function changeAction(actionModel: any, action: any) {
  const [a, b] = actionModel.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() {
  // 当没有勾选最大值、最小值时，清空action的max和min值
  props.rule.conditions.forEach((condition, index) => {
    if (!maxIsDisabled.value[index]) {
      condition.action.max = '';
    }
    if (!minIsDisabled.value[index]) {
      condition.action.min = '';
    }
  });
  const valid1 = await validateRuleForm();
  const valid2 = await validateConditionsForm();
  return valid1 && valid2;
}

function handleClose() {
  isVisible.value = false;
}

function moveUp(index) {
  if (index > 0) {
    const temp = props.rule.conditions[index];
    props.rule.conditions[index] = props.rule.conditions[index - 1];
    props.rule.conditions[index - 1] = temp;
    // 更新ordering
    updateOrdering();
  }
}

function moveDown(index) {
  if (index < props.rule.conditions.length - 1) {
    const temp = props.rule.conditions[index];
    props.rule.conditions[index] = props.rule.conditions[index + 1];
    props.rule.conditions[index + 1] = temp;
    // 更新ordering
    updateOrdering();
  }
}

function updateOrdering() {
  props.rule.conditions.forEach((condition, index) => {
    condition.ordering = index + 1; // 重新计算ordering，从1开始
  });
}

function getActionModelLabel(value) {
  const option = ActionList.find(option => option.value === value);
  return option ? option.label : '';
}

// 获取对应 set 值的后缀
function getSetSuffix(numType) {
  return numType === 'num' ? '$' : numType === 'ratio' ? '%' : '';
}

defineExpose({ validateForm });
</script>

<template>
  <div>
    <div class="asj-h3">
      <span class="custom-title-icon"></span>
      规则设置
    </div>
    <!--提示信息-->
    <div>
      <el-tag v-if="isVisible" class="custom-tag" closable color="#e7edf4" @close="handleClose">
        <template #default>
          <div class="tag-content">
            <el-icon style="color: #0b52a7">
              <InfoFilled />
            </el-icon>
            可设置多个规则，如果一个对象命中多个规则，系统只是执行优先级最高的规则
          </div>
        </template>
      </el-tag>
    </div>
    <div class="mt-5">
      <el-radio-group v-model="setting" size="small">
        <el-radio-button label="编辑" value="edit" />
        <el-radio-button label="排序" value="order" />
      </el-radio-group>
    </div>
    <div v-if="setting === 'edit'" class="rule-setting-container">
      <div v-for="(info, index) in rule.conditions" :key="info.actionType + info.ordering" class="rule-setting-item">
        <div class="rule-setting-title">
          <div class="asj-h3">{{ RuleNameMap[info.actionType] }} - 规则{{ info.ordering }}</div>
          <div class="rule-setting-opration">
            <el-tooltip v-if="!disabled" content="添加规则" effect="dark" placement="top">
              <el-icon :disabled="disabled" @click="addRule(info.actionType, index)">
                <Plus />
              </el-icon>
            </el-tooltip>
            <el-tooltip v-if="rule.conditions.length !== 1 && !disabled" content="删除规则" effect="dark"
                        placement="top">
              <el-icon @click="delRule(info.actionType,index)">
                <DeleteFilled />
              </el-icon>
            </el-tooltip>
            <el-tooltip content="收起/展开规则" effect="dark" placement="top">
              <el-icon @click="info.show = !info.show">
                <ArrowDown />
              </el-icon>
            </el-tooltip>
          </div>
        </div>
        <div v-show="info.show">
          <el-form ref="ruleFormRef" :disabled="disabled" :inline="true" :model="info.action">
            <!-- 竞价规则下面的下拉框和两个输入框 -->
            <div v-if="info.actionType === 'increase' || info.actionType === 'decrease'">
              <el-form-item>
                <el-select v-model="actionModel[index]" style="width: 250px"
                           @change="changeAction(actionModel[index], info.action)">
                  <el-option
                      v-for="item in ActionList"
                      :key="item.value"
                      :label="item.label.replace('_', info.actionType === 'increase' ? '升高' : '降低')"
                      :value="item.value">
                  </el-option>
                </el-select>
              </el-form-item>
              <el-form-item :rules="{ validator: checkFloat }" prop="set">
                <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 v-if="info.actionType === 'increase'" label="最大值" prop="max">
                <template v-slot:label>
                  <el-checkbox v-model="maxIsDisabled[index]">最大值</el-checkbox>
                </template>
                <InputFloat v-model="info.action.max" :disabled="!maxIsDisabled[index]" prefix="$"
                            style="width: 120px"></InputFloat>
              </el-form-item>
              <el-form-item v-else label="最小值" prop="min">
                <template v-slot:label>
                  <el-checkbox v-model="minIsDisabled[index]">最小值</el-checkbox>
                </template>
                <InputFloat v-model="info.action.min" :disabled="!minIsDisabled[index]" prefix="$"
                            style="width: 120px"></InputFloat>
              </el-form-item>
            </div>
            <el-form-item v-if="info.actionType === 'set'" prop="set">
              <InputFloat v-model="info.action.set" prefix="$" style="width: 120px"></InputFloat>
            </el-form-item>
          </el-form>
          <conditionBuilder
              ref="condiBuilderRef"
              :candidate-fields="candidateFields"
              :data="info.conditions"
              :disabled="disabled" />
        </div>
      </div>
      <el-popover :disabled="disabled" placement="bottom-start" trigger="hover">
        <template #reference>
          <el-button :disabled="disabled" :icon="Plus" type="warning">添加规则</el-button>
        </template>
        <div class="popver-content">
          <span v-for="[name, title] of Object.entries(RuleNameMap)" class="popver-content-item" @click="addRule(name)">{{
              title
            }}</span>
        </div>
      </el-popover>
    </div>
    <div v-if="setting === 'order'" class="mt-2">
      <div v-for="(info, index) in rule.conditions" :key="info.actionType + info.ordering">
        <el-row>
          <el-col :span="20">
            <el-card body-style="padding: 12px 10px;" class="rule-setting-item" shadow="hover">
              {{ RuleNameMap[info.actionType] }} - 规则{{ info.ordering }}
              <span v-if="info.actionType === 'increase' || info.actionType === 'decrease'">
                 {{
                  getActionModelLabel(actionModel[index]).replace('_', info.actionType === 'increase' ? '升高' : '降低')
                }}
                {{ info.action.set }}
              <span v-if="info.action.set && info.action.numType">
                {{ getSetSuffix(info.action.numType) }}
              </span>
              </span>
            </el-card>
          </el-col>
          <el-col :span="4">
            <div class="mt-3 pl-2">
              <el-button :disabled="index === 0" :icon="Top" link type="primary" @click="moveUp(index)"></el-button>
              <el-button :disabled="index === rule.conditions.length - 1" :icon="Bottom" link type="primary"
                         @click="moveDown(index)"></el-button>
            </div>
          </el-col>
        </el-row>
      </div>
    </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%);
}

.tag-content {
  display: block;
  max-width: 100%;
}

.rule-setting-item {
  width: 100%;
  margin: 5px 0;
  padding: 0;
  border-radius: 0 !important;
  font-size: 13px;
  font-weight: 500;
}

</style>
