<template>
    <el-dialog v-model="visible" title="多条件筛选" width="450px" append-to-body draggable
        class="transient-filter-dialog">
        <el-form label-width="auto" class="filter-form">
            <el-form-item label="暂态幅值(%)">
                <div class="range-inputs">
                    <el-input-number v-model="filterForm.featureAmplitudeMin" class="range-input-item" :min="0"
                        :max="200" :precision="3" :step="0.01" :controls="false" placeholder="0"
                        @change="onRangeMinChange($event, 'featureAmplitudeMax')" />
                    <span class="range-sep">&lt; 　幅值　 &lt;</span>
                    <el-input-number v-model="filterForm.featureAmplitudeMax" class="range-input-item" :min="0"
                        :max="200" :precision="3" :step="0.01" :controls="false" placeholder="200"
                        @change="onRangeMaxChange($event, filterForm.featureAmplitudeMin, 'featureAmplitudeMax', '暂态幅值')" />
                </div>
            </el-form-item>
            <el-form-item label="暂态持续时间">
                <div class="range-inputs">
                    <el-input-number v-model="filterForm.evtParamTmMin" class="range-input-item" :min="0"
                        :precision="3" :step="0.01" :controls="false" placeholder="X毫秒"
                        @change="onRangeMinChange($event, 'evtParamTmMax')" />
                    <span class="range-sep">&lt; 持续时间 &lt;</span>
                    <el-input-number v-model="filterForm.evtParamTmMax" class="range-input-item" :min="0"
                        :precision="3" :step="0.01" :controls="false" placeholder="X毫秒"
                        @change="onRangeMaxChange($event, filterForm.evtParamTmMin, 'evtParamTmMax', '暂态持续时间')" />
                </div>
            </el-form-item>
            <el-form-item label="触发类型">
                <el-select v-model="params.showName" clearable placeholder="请选择触发类型" style="width: 100%">
                    <el-option v-for="item in eventTypeList" :key="item.value" :label="item.label"
                        :value="item.value" />
                </el-select>
            </el-form-item>
            <el-form-item label="是否存在波形">
                <el-select v-model="params.fileFlag" clearable placeholder="请选择是否存在波形" style="width: 100%">
                    <el-option v-for="item in fileFlagOptions" :key="item.value" :label="item.label"
                        :value="item.value" />
                </el-select>
            </el-form-item>
        </el-form>
        <template #footer>
            <div>
                <el-button type="primary" @click="onConfirm">确认</el-button>
            </div>
        </template>
    </el-dialog>
</template>

<script setup lang="ts">
import { ref, watch } from 'vue'
import { ElMessage } from 'element-plus'

const getDefaultFilterParams = () => ({
    featureAmplitude: '',
    evtParamTm: '',
    showName: '',
    fileFlag: '' as string | number
})

const visible = defineModel<boolean>('visible', { default: false })

const props = defineProps<{
    params: Record<string, any>
}>()

const emit = defineEmits<{
    confirm: []
}>()

const eventTypeList = [
    { label: '电压暂降', value: '电压暂降' },
    { label: '电压暂升', value: '电压暂升' },
    { label: '电压中断', value: '电压中断' }
]

const fileFlagOptions = [
    { label: '存在', value: 1 },
    { label: '不存在', value: 0 }
]

type RangeMaxField = 'featureAmplitudeMax' | 'evtParamTmMax'

const filterForm = ref<{
    featureAmplitudeMin?: number
    featureAmplitudeMax?: number
    evtParamTmMin?: number
    evtParamTmMax?: number
}>({})

const parseRangeParam = (val: string): [number | undefined, number | undefined] => {
    if (!val) return [undefined, undefined]
    const [min = '', max = ''] = String(val).split(',')
    const minNum = min !== '' ? Number(min) : undefined
    const maxNum = max !== '' ? Number(max) : undefined
    return [
        minNum != null && !Number.isNaN(minNum) ? minNum : undefined,
        maxNum != null && !Number.isNaN(maxNum) ? maxNum : undefined
    ]
}

const joinRangeParam = (min?: number, max?: number) => {
    if (min == null && max == null) return ''
    return `${min ?? ''},${max ?? ''}`
}

const onRangeMinChange = (min: number | undefined, maxField: RangeMaxField) => {
    const max = filterForm.value[maxField]
    if (min != null && max != null && max <= min) {
        filterForm.value[maxField] = undefined
    }
}

const onRangeMaxChange = (
    max: number | undefined,
    min: number | undefined,
    maxField: RangeMaxField,
    label: string
) => {
    if (min != null && max != null && max <= min) {
        ElMessage.warning(`${label}最大值必须大于最小值`)
        filterForm.value[maxField] = undefined
    }
}

const validateRange = (
    min: number | undefined,
    max: number | undefined,
    label: string,
    options?: { maxLimit?: number }
) => {
    const hasMin = min != null && !Number.isNaN(min)
    const hasMax = max != null && !Number.isNaN(max)

    if (!hasMin && !hasMax) return true

    if (hasMin !== hasMax) {
        ElMessage.warning(`${label}请同时填写最小值和最大值`)
        return false
    }

    if (min! <= 0 || max! <= 0) {
        ElMessage.warning(`${label}必须大于0`)
        return false
    }

    if (max! <= min!) {
        ElMessage.warning(`${label}最大值必须大于最小值`)
        return false
    }

    if (options?.maxLimit !== undefined && max! > options.maxLimit) {
        ElMessage.warning(`${label}最大值不能大于${options.maxLimit}`)
        return false
    }

    return true
}

const syncFromParams = () => {
    const [faMin, faMax] = parseRangeParam(props.params.featureAmplitude)
    const [tmMin, tmMax] = parseRangeParam(props.params.evtParamTm)
    filterForm.value.featureAmplitudeMin = faMin
    filterForm.value.featureAmplitudeMax = faMax
    filterForm.value.evtParamTmMin = tmMin
    filterForm.value.evtParamTmMax = tmMax
}

const reset = () => {
    filterForm.value = {}
    Object.assign(props.params, getDefaultFilterParams())
}

const onConfirm = () => {
    const { featureAmplitudeMin, featureAmplitudeMax, evtParamTmMin, evtParamTmMax } = filterForm.value

    if (!validateRange(featureAmplitudeMin, featureAmplitudeMax, '暂态幅值', { maxLimit: 200 })) {
        return
    }
    if (!validateRange(evtParamTmMin, evtParamTmMax, '暂态持续时间')) {
        return
    }

    props.params.featureAmplitude = joinRangeParam(featureAmplitudeMin, featureAmplitudeMax)
    props.params.evtParamTm = joinRangeParam(evtParamTmMin, evtParamTmMax)
    visible.value = false
    emit('confirm')
}

watch(visible, val => {
    if (val) syncFromParams()
})

defineExpose({ reset, syncFromParams })
</script>

<style scoped lang="scss">
.range-inputs {
    display: flex;
    align-items: center;
    width: 100%;
    gap: 8px;

    .range-input-item {
        width: 120px;

        :deep(.el-input__wrapper) {
            width: 100%;
        }
    }

    .range-sep {
        flex-shrink: 0;
        color: var(--el-text-color-regular);
        font-size: 14px;
        white-space: nowrap;
    }
}
</style>
