<template>
    <div>
        <el-switch
            v-if="field.prop"
            @change="onChange"
            :model-value="displayValue"
            :loading="loading"
            active-value="1"
            inactive-value="0"
            v-bind="invokeTableContextDataFun(field.customRenderAttr?.switch, { row, field, cellValue: displayValue, column, index })"
        />
    </div>
</template>

<script setup lang="ts">
import { TableColumnCtx } from 'element-plus'
import { inject, ref, onMounted } from 'vue'
import { getCellValue, invokeTableContextDataFun } from '/@/components/table/index'
import type baTableClass from '/@/utils/baTable'

interface Props {
    row: TableRow
    field: TableColumn
    column: TableColumnCtx<TableRow>
    index: number
}

const loading = ref(false)
const props = defineProps<Props>()
const baTable = inject('baTable') as baTableClass

const rawValue = getCellValue(props.row, props.field, props.column, props.index)
const normalized = (v: unknown) => {
    if (typeof v === 'number') return v.toString()
    if (v === null || v === undefined || v === '') return '0'
    return String(v)
}
const displayValue = ref(normalized(rawValue))

const mountedAt = ref(0)
onMounted(() => {
    mountedAt.value = Date.now()
})

const onChange = (value: string | number | boolean) => {
    const newVal = String(value)
    const prevVal = normalized(rawValue)
    if (prevVal === newVal) return
    if ([null, undefined, ''].includes(rawValue) && newVal === '0') return
    if (Date.now() - mountedAt.value < 150) return

    loading.value = true
    baTable.api
        .postData('edit', {
            [baTable.table.pk!]: props.row[baTable.table.pk!],
            [props.field.prop!]: value,
        })
        .then(() => {
            displayValue.value = newVal
            baTable.onTableAction('field-change', { value: value, ...props })
        })
        .finally(() => {
            loading.value = false
        })
}
</script>
