<script lang="ts" setup>
import type { FormInst, FormItemRule, FormRules } from 'naive-ui'
import { computed, defineOptions, reactive, ref, unref, watch } from 'vue'
import { asideMap } from '@/config/aside'
import { useDictionary } from '@/store/modules/dictonary'
import { useConfig } from '@/store/modules/asideConfig'
import type { FilterCondition } from '/#/api'
import { addCondition, updateCondition } from '@/api/home/filter'

defineOptions({ name: 'NewFilterModal' })

type Status = 'edit' | 'new'

const show = ref(false)
const configStore = useConfig()
const dicStore = useDictionary()
const currentStatus = ref<Status>('new')
let currentEditId: string | null = null

const modalTitle = computed(() => {
  return currentStatus.value === 'new' ? '新建过滤条件' : '编辑过滤条件'
})

const cardStyle = {
  'width': '800px',
  '--n-padding-bottom': '10px',
  '--n-padding-left': '10px',
}

const noBorderInput = {
  '--n-border': '0px',
  '--n-border-hover': '0px',
  '--n-border-pressed': '0px',
}

const formItemStyle = {
  '--n-label-height': '0px',
  '--n-feedback-height': '8px',
}

interface FormType {
  name: string | null
  logic: string | null
  conditions: Condition[]
}

interface Condition {
  type: string | null
  operator: string | null
  result: any
}

interface Option {
  label: string
  value: string
}

const rules: FormRules = {
  name: {
    required: true,
    message: '请输入过滤条件名称',
    trigger: 'blur',
  },
  logic: {
    required: true,
    message: '请选择逻辑关系',
    trigger: 'blur',
  },
  conditions: {
    required: true,
    validator(rule: FormItemRule, value: Condition[]) {
      for (const item of value) {
        const { type, operator, result } = item

        if (type === null || operator === null || result === null)
          return new Error('请选择过滤条件')
      }
      return true
    },
    trigger: ['input', 'blur'],
  },
}

const formRef = ref<FormInst | null>(null)

const formValue = reactive<FormType>({
  name: null,
  logic: null,
  conditions: [{
    type: null,
    operator: null,
    result: null,
  }],
})

function handleSumbit(e: MouseEvent) {
  e.preventDefault()
  formRef.value?.validate((errors) => {
    if (errors)
      return

    const list = formValue.conditions.map((item) => {
      const { type, operator, result } = item

      return {
        searchfield: type!,
        searchtype: operator!,
        searchvalue: result!,
      }
    })

    const param: FilterCondition = {
      searchname: formValue.name!,
      ocrUsersearchchildList: list,
      logic: formValue.logic!,
    }

    if (currentStatus.value === 'new')
      addCondition(param)
    else
      updateCondition({ id: currentEditId!, ...param })
    closeModal()
  })
}

function createCondition() {
  formValue.conditions.push({
    type: null,
    operator: null,
    result: null,
  })
}

function removeCondition(index: number) {
  formValue.conditions.splice(index, 1)
}

function formLabel(index: number) {
  return index === 0 ? '筛选条件' : ''
}

const typeOptions = ref<Option[]>([])

const operatorOptions = [
  {
    label: '等于',
    value: 'eq',
  },
  {
    label: '不等于',
    value: 'notEq',
  },
]

const logicOptions = [
  {
    label: '与',
    value: 'and',
  },
  {
    label: '或',
    value: 'or',
  },
]

const similarityOptions = [
  {
    label: '80%-90%',
    value: [80, 90],
  },
  {
    label: '95%-100%',
    value: [95, 100],
  },
  {
    label: '100%-100%',
    value: [100, 100],
  },
]

const resultOptions = ref<Option[]>([])

function showModal() {
  show.value = true
}

function closeModal() {
  show.value = false
}

function generateAllData(config): Option[] {
  const initVal: Option[] = []
  const list = Object.keys(config).reduce((acc, value) => {
    if (value.startsWith('iz') && asideMap[value]?.inFilterList !== false) {
      const name = asideMap[value]?.label

      name && acc.push({
        value,
        label: name || '未配置',
      })
    }
    return acc
  }, initVal)

  return list
}

watch(() => configStore.systemConfig, (newVal) => {
  const list = generateAllData(newVal)
  typeOptions.value = list
})

function handleTypeUpate(value: string) {
  if (value === 'izsimilarity') {
    resultOptions.value = similarityOptions as any
    return
  }

  const key = `get${value}`
  const options = unref(dicStore[key])
  resultOptions.value = options || []
}

function leaveHandler() {
  currentStatus.value = 'new'
  currentEditId = null

  formValue.name = null
  formValue.conditions = [
    {
      type: null,
      operator: null,
      result: null,
    },
  ]
}

function edit(editFilter: any) {
  currentStatus.value = 'edit'

  const { searchname, ocrUsersearchchildList, id } = editFilter
  currentEditId = id
  formValue.name = searchname
  formValue.conditions = ocrUsersearchchildList.map((item) => {
    return {
      type: item.searchfield,
      operator: item.searchtype,
      result: item.searchvalue,
    }
  })
}

defineExpose({
  showModal,
  edit,
})
</script>

<template>
  <n-modal v-model:show="show" transform-origin="center" @after-leave="leaveHandler">
    <n-card :style="cardStyle" :bordered="false" size="huge" role="dialog" aria-modal="true">
      <div class="wrapper">
        <span class="wrapper-title">{{ modalTitle }}</span>
        <div class="wrapper-bar">
          <div class="wrapper-info">
            <span :style="{ 'margin-left': '18px' }">基本信息</span>
          </div>
        </div>
        <div class="wrapper-form">
          <n-form ref="formRef" :model="formValue" :rules="rules">
            <n-form-item path="name" label="标题">
              <n-input v-model:value="formValue.name" :style="{ width: '780px' }" @keydown.enter.prevent />
            </n-form-item>
            <n-form-item path="logic" label="逻辑关系">
              <n-select v-model:value="formValue.logic" placeholder="请选择逻辑关系" :options="logicOptions" />
            </n-form-item>
            <n-form-item
              v-for="(item, index) in formValue.conditions" :key="index" :style="formItemStyle"
              path="conditions" :label="formLabel(index)"
            >
              <n-select
                v-model:value="item.type" placeholder="请选择筛选项名称" :options="typeOptions"
                @update:value="handleTypeUpate"
              />
              <n-select
                v-model:value="item.operator" style="margin-left: 8px;" placeholder="请选择"
                :options="operatorOptions"
              />
              <n-space v-if="item.type === 'izyear'">
                <n-date-picker
                  v-model:value="item.result" style="margin-left: 8px;width: 240px;" type="daterange"
                  clearable
                />
              </n-space>
              <n-select
                v-else v-model:value="item.result" style="margin-left: 8px;" placeholder="请选择"
                :options="resultOptions"
              />
              <n-button :style="noBorderInput" icon-placement="right" @click="removeCondition(index)">
                <template #icon>
                  <SvgIcon size="24" name="close" />
                </template>
              </n-button>
            </n-form-item>
          </n-form>
        </div>
        <div class="wrapper-new" @click="createCondition">
          <span>+</span>
          <span style="margin-left:8px">添加筛选条件</span>
        </div>
      </div>
      <template #footer>
        <div class="wrapper-footer">
          <n-button type="info" @click="handleSumbit">
            确认
          </n-button>
          <n-button secondary style="margin-left:15px" @click="closeModal">
            取消
          </n-button>
        </div>
      </template>
    </n-card>
  </n-modal>
</template>

<style lang="less" scoped>
.wrapper {
  display: flex;
  flex-direction: column;

  &-title {
    font-weight: bold;
    font-size: 16px;
  }

  &-bar {
    background-color: #e8e8e8;
    width: 100%;
    margin-top: 20px;
  }

  &-form {
    display: flex;
    justify-content: space-between;
    margin-top: 20px;
  }

  &-new {
    display: flex;
    width: 110px;
    color: #507afd;
    line-height: 22px;
    cursor: pointer;

    &:hover {
      color: #507aac;
    }
  }

  &-table {
    margin-top: 20px;
  }

  &-footer {
    display: flex;
    justify-content: flex-end;
  }

  &-info {
    font-weight: bold;
    position: relative;

    &:before {
      background-color: #1980FF;
      content: "";
      width: 5px;
      border-radius: 2px;
      top: 0;
      bottom: 0;
      position: absolute;
    }
  }
}
</style>
