<script setup lang="ts">
import type { UserActionRule, UserActionRuleItem, RuleEvent, RuleAttr } from '@/types'
import { Paperclip, Plus, CloseBold } from '@element-plus/icons-vue'
import { useMetaEvent } from '@/composables/useAllData'
import { stringOperatorList, numberOperatorList, dateOperatorList } from '@/utils/dictionary'
import { searchEventAttrs } from '@/api/base'

// const userActionRule = ref(inject('userActionRule') as UserActionRule)
const userActionRule = defineModel<UserActionRule>({ default: { current_logic_operate: 'and', items: [] } })

const { metaEventList } = useMetaEvent()

const currentMetaEventList = computed(() => {
  return [{ id: '-1', name: '所有事件', event_attrs: [] }, ...metaEventList.value]
})

// 获取逻辑运算符名称
function getLogicalName(value: 'and' | 'or') {
  return value === 'or' ? '或' : '且'
}

// 获取运算符列表
function getOperatorList(type: string) {
  if (type === '1') return stringOperatorList
  if (type === '2' || type === '3') return numberOperatorList
  if (type === '4' || type === '5') return dateOperatorList
  return stringOperatorList
}

// 获取事件属性列表
function getEventAttrList(eventId: string) {
  return currentMetaEventList.value.find(item => item.id === eventId)?.event_attrs || []
}

// 切换逻辑运算符
function toggleOperate(rule: UserActionRule) {
  rule.current_logic_operate = rule.current_logic_operate === 'or' ? 'and' : 'or'
}

// 添加条件
function handleAdd(items: UserActionRuleItem[]) {
  items.push({ operate: '', operate_name: '', value: '', event_list: [] })
}

// 删除条件
function handleRemove(items: UserActionRuleItem[], index: number) {
  items.splice(index, 1)
}

// 添加事件
function handleEventAdd(events: RuleEvent[]) {
  events.push({ event_id: '', event_name: '', attr_list: [] })
}

// 删除事件条件
function handleEventRemove(events: RuleEvent[], index: number) {
  events.splice(index, 1)
}

// 添加属性条件
function handleAttrAdd(attrs: RuleAttr[]) {
  attrs.push({ attr_id: '', attr: '', attr_name: '', attr_type: '', operate: '', operate_name: '', value: '' })
}

// 删除属性条件
function handleAttrRemove(attrs: RuleAttr[], index: number) {
  attrs.splice(index, 1)
}

// 发生条件改变
function handleHappenOperateChange(value: string, item: UserActionRuleItem) {
  const found = dateOperatorList.find(item => item.value === value)
  item.operate_name = found?.label || ''
  item.value = ''
}

// 事件改变
function handleEventChange(value: string, event: RuleEvent) {
  const currentEvent = metaEventList.value.find(item => item.id === value)
  event.event_name = currentEvent?.name || ''
  event.attr_list = []
}

// 属性改变
function handleAttrChange(value: string, attr: RuleAttr, event: RuleEvent) {
  const found = getEventAttrList(event.event_id).find(item => item.id === value)
  attr.attr = found?.english_name || ''
  attr.attr_name = found?.name || ''
  attr.attr_type = found?.type || ''
  // 清空条件数据
  attr.operate = ''
  attr.operate_name = ''
  attr.value = ''
}

// 条件改变
function handleOperateChange(value: string, item: RuleAttr) {
  const found = getOperatorList(item.attr_type).find(item => item.value === value)
  item.operate_name = found?.label || ''
  item.value = ''
  // 区间
  if (value === 'range') {
    item.value = { start: undefined, end: undefined }
  }
}

function querySearch(event: RuleEvent, attr: RuleAttr, search: string, cb: (arg: any) => void) {
  const found = getEventAttrList(event.event_id).find(item => item.id === attr.attr_id)
  const experiment_meta_event_id = found?.experiment_meta_event_id || ''
  searchEventAttrs({ search, experiment_meta_event_id: experiment_meta_event_id, experiment_meta_event_attr_id: attr.attr_id, per_page: 1000 }).then(res => {
    const list: string[] = []
    res.data.list.forEach((item: any) => {
      try {
        const fields = JSON.parse(item.fields)
        const value = fields[attr.attr_id]
        if (!list.includes(value)) list.push(value)
      } catch (error) {
        console.log(error)
      }
    })
    cb(list.map((item: string) => ({ value: item })))
  })
}

const options = ref<{ label: string; value: string }[]>([])
const loading = ref(false)
function remoteMethod(event: RuleEvent, attr: RuleAttr, search: string) {
  const found = getEventAttrList(event.event_id).find(item => item.id === attr.attr_id)
  const experiment_meta_event_id = found?.experiment_meta_event_id || ''
  loading.value = true
  searchEventAttrs({ search, experiment_meta_event_id: experiment_meta_event_id, experiment_meta_event_attr_id: attr.attr_id, per_page: 1000 }).then(res => {
    const list: string[] = []
    res.data.list.forEach((item: any) => {
      try {
        const fields = JSON.parse(item.fields)
        const value = fields[attr.attr_id]
        if (!list.includes(value)) list.push(value)
      } catch (error) {
        console.log(error)
      }
    })
    options.value = list.map((item: string) => ({ value: item, label: item }))
    loading.value = false
  })
}
</script>

<template>
  <el-card shadow="never" class="user-action-rule">
    <template #header>
      <el-button circle color="#67c23a" :icon="Paperclip"></el-button>
      用户行为序列满足以下条件
    </template>
    <div class="rule" v-if="userActionRule.items.length">
      <div class="rule-operator">
        <span @click="toggleOperate(userActionRule)">{{ getLogicalName(userActionRule.current_logic_operate) }}</span>
      </div>
      <div class="rule-list">
        <section class="rule-item" v-for="(rule, index) in userActionRule.items" :key="index">
          <el-row align="middle">
            <!-- 发生 -->
            <el-form-item>
              <el-select v-model="rule.operate" @change="value => handleHappenOperateChange(value, rule)">
                <el-option v-for="option in dateOperatorList" :key="option.label" v-bind="option"></el-option>
              </el-select>
            </el-form-item>
            <el-form-item>
              <template v-if="rule.operate === 'after' || rule.operate === 'before'">
                <el-date-picker v-model="rule.value" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" style="width: 180px" />
              </template>
              <template v-else-if="rule.operate === 'range'">
                <el-date-picker v-model="rule.value" type="datetimerange" value-format="YYYY-MM-DD HH:mm:ss" style="width: 254px" />
              </template>
              <el-input v-model="rule.value" v-else />
            </el-form-item>
            <p style="margin-right: 10px">依次发生过</p>
            <el-button text :icon="Plus" @click="handleEventAdd(rule.event_list)">添加条件</el-button>
            <el-button text :icon="CloseBold" @click="handleRemove(userActionRule.items, index)"></el-button>
          </el-row>
          <div class="rule-item" v-for="(event, index) in rule.event_list" :key="index" style="margin: 15px 0">
            <el-form-item>
              <el-select v-model="event.event_id" @change="value => handleEventChange(value, event)">
                <el-option v-for="option in currentMetaEventList" :key="option.id" :label="option.name" :value="option.id"></el-option>
              </el-select>
            </el-form-item>
            <el-button text :icon="Plus" @click="handleAttrAdd(event.attr_list)">添加条件</el-button>
            <el-button text :icon="CloseBold" @click="handleEventRemove(rule.event_list, index)"></el-button>

            <!-- 属性条件 -->
            <el-row justify="space-between" class="rule-item" v-for="(attr, index) in event.attr_list" :key="index">
              <div>
                <el-form-item>
                  <el-select v-model="attr.attr_id" @change="value => handleAttrChange(value, attr, event)">
                    <el-option v-for="option in getEventAttrList(event.event_id)" :key="option.id" :label="option.name" :value="option.id"></el-option>
                  </el-select>
                </el-form-item>
                <el-form-item>
                  <el-select v-model="attr.operate" @change="value => handleOperateChange(value, attr)">
                    <el-option
                      v-for="option in getOperatorList(attr.attr_type)"
                      :key="option.value"
                      :label="option.alias || option.label"
                      :value="option.value"></el-option>
                  </el-select>
                </el-form-item>
                <el-form-item v-if="!['null', 'not null'].includes(attr.operate)">
                  <!-- 数字区间 -->
                  <template v-if="['2', '3'].includes(attr.attr_type) && attr.operate === 'range'">
                    <el-input-number step-strictly :controls="false" :min="0" v-model="attr.value.start" />
                    <el-input-number step-strictly :controls="false" :min="0" v-model="attr.value.end" />
                  </template>
                  <!-- 日期区间 -->
                  <template v-else-if="attr.attr_type === '4' && attr.operate === 'range'">
                    <el-date-picker v-model="attr.value.start" type="date" value-format="YYYY-MM-DD" />
                    <el-date-picker v-model="attr.value.end" type="date" value-format="YYYY-MM-DD" />
                  </template>
                  <!-- 时间区间 -->
                  <template v-else-if="attr.attr_type === '5' && attr.operate === 'range'">
                    <el-date-picker v-model="attr.value.start" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" style="width: 180px" />
                    <el-date-picker v-model="attr.value.end" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" style="width: 180px" />
                  </template>
                  <template v-else-if="attr.attr_type === '4' && (attr.operate === 'after' || attr.operate === 'before')">
                    <el-date-picker v-model="attr.value" type="date" value-format="YYYY-MM-DD" />
                  </template>
                  <template v-else-if="attr.attr_type === '5' && (attr.operate === 'after' || attr.operate === 'before')">
                    <el-date-picker v-model="attr.value" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" style="width: 180px" />
                  </template>
                  <template v-else>
                    <el-select
                      v-model="attr.value"
                      filterable
                      remote
                      allow-create
                      multiple
                      :remote-method="(query:string) => remoteMethod(event, attr, query)"
                      :loading="loading"
                      style="width: 320px"
                      v-if="['in', 'not in'].includes(attr.operate)">
                      <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
                    </el-select>
                    <el-autocomplete v-model="attr.value" :fetch-suggestions="(query, cb) => querySearch(event, attr, query, cb)" style="width: 320px" v-else />
                  </template>
                </el-form-item>
              </div>
              <el-button text :icon="CloseBold" @click="handleAttrRemove(event.attr_list, index)"></el-button>
            </el-row>
          </div>
        </section>
      </div>
    </div>
    <el-button text :icon="Plus" @click="handleAdd(userActionRule.items)">添加用户行为</el-button>
  </el-card>
</template>

<style src="@/assets/styles/rule.scss"></style>
