<template>
  <el-dialog v-model="dialogFormVisible" title="编辑通信参数" @close="handleClose">
    <el-form :model="form" ref="formRef" :rules="rules">
      <el-form-item label="设备名称" :label-width="formLabelWidth" prop="device_name">
        <el-input v-model="form.device_name" autocomplete="false" />
      </el-form-item>
      <el-form-item label="设备中文名" :label-width="formLabelWidth" prop="device_name_chn">
        <el-input v-model="form.device_name_chn" autocomplete="false" />
      </el-form-item>
      <!-- <el-form-item label="设备序号" :label-width="formLabelWidth" prop="device_name_chn">
        <el-input v-model="form.device_id" autocomplete="false" />
      </el-form-item> -->
      <el-form-item label="所属站点" :label-width="formLabelWidth" prop="station_id">
        <el-input v-model="form.station_id" autocomplete="false" />
      </el-form-item>
      <el-form-item label="协议名称" :label-width="formLabelWidth" prop="protocol_name">
        <el-select v-model="form.protocol_name" @change="handleProtocolChange(form.protocol_name, [])">
          <el-option v-for="protocolName in store.protocolNames" :label="protocolName.label" :value="protocolName.value" />
        </el-select>
      </el-form-item>
      <el-form-item label="通信模式" :label-width="formLabelWidth" prop="communicate_mode">
        <el-select v-model="form.communicate_mode" @change="handleModeChange">
          <el-option label="TCP_SERVER" value="TCP_SERVER" />
          <el-option label="TCP_CLIENT" value="TCP_CLIENT" />
          <el-option label="UDP" value="UDP" />
          <el-option label="UDP_MC" value="UDP_MC" />
        </el-select>
      </el-form-item>
      <div v-if="isTcp">
        <el-form-item label="IP" :label-width="formLabelWidth" prop="tcp_ip">
          <el-input v-model="form.tcp_ip" autocomplete="false" />
        </el-form-item>
        <el-form-item label="端口" :label-width="formLabelWidth" prop="tcp_port">
          <el-input v-model="form.tcp_port" autocomplete="false" />
        </el-form-item>
      </div>
      <div v-else>
        <el-form-item label="源IP" :label-width="formLabelWidth" prop="udp_ip_src">
          <el-input v-model="form.udp_ip_src" autocomplete="false" />
        </el-form-item>
        <el-form-item label="源端口" :label-width="formLabelWidth" prop="udp_port_src">
          <el-input v-model="form.udp_port_src" autocomplete="false" />
        </el-form-item>
        <el-form-item label="目标IP" :label-width="formLabelWidth" prop="udp_ip_dst">
          <el-input v-model="form.udp_ip_dst" autocomplete="false" />
        </el-form-item>
        <el-form-item label="目标端口" :label-width="formLabelWidth" prop="udp_port_dst">
          <el-input v-model="form.udp_port_dst" autocomplete="false" />
        </el-form-item>
      </div>
      <el-form-item label="监控属性" :label-width="formLabelWidth">
        <el-checkbox v-model="checkAll" :indeterminate="isIndeterminate" @change="handleCheckAllChange">
          Check all
        </el-checkbox>
        <el-checkbox-group v-model="checked_performance_fields" @change="handleCheckedFieldsChange">
          <el-checkbox v-for="field in performance_fields" :key="field" :label="field">
            {{ field }}
          </el-checkbox>
        </el-checkbox-group>
      </el-form-item>

    </el-form>
    <template #footer>
      <span class="dialog-footer">
        <el-button @click="dialogFormVisible = false">取消</el-button>
        <el-button type="primary" @click="submit_form">
          确定
        </el-button>
      </span>
    </template>
  </el-dialog>
</template>


<script setup lang="ts">
import { reactive, ref, watch } from 'vue';
import type { CheckboxValueType, ElForm } from 'element-plus';
import { ElMessage, FormRules } from 'element-plus'
import axios from 'axios';

import { DeviceInfo } from "./types";
import { useProtocolNamesStore } from '@/stores/protocolNames'; 

// protocol name 存储
const store = useProtocolNamesStore()
// form 表单对象
const formRef = ref<typeof ElForm>()
// 弹出框是否可见，默认不可见
// 弹出框表单 label 的宽度
const dialogFormVisible = ref(false)
const formLabelWidth = "120px"

// 父组件往这里传的类型
type porpsType = {
  isShow: boolean,
  deviceInfo?: DeviceInfo,
  type: string,
  tabType: string
}
const props = defineProps<porpsType>()
// 返回父组件的方法
const emit = defineEmits(['close', 'changeDeviceInfo'])
// 关闭弹出框的执行的操作
const handleClose = () => {
  // 向父组件发射关闭弹出框的事件
  emit('close')
  // 表单所有的校验和数据重置
  formRef.value!.resetFields()
}

// 默认表单数据
const form = ref<DeviceInfo>({
  station_id: "",
  device_id: 0,
  device_name: "",
  device_name_chn: "",
  protocol_name: "",
  communicate_mode: "",
  tcp_ip: "",
  tcp_port: 0,
  udp_ip_src: "",
  udp_port_src: 0,
  udp_ip_dst: "",
  udp_port_dst: 0
})

// 检测弹出框是否弹出，如果弹出赋值
watch(() => props.isShow, () => {
  dialogFormVisible.value = props.isShow
  
  // 判断传下来的类型是不是 edit，如果是，需要将展示的数据放到表单上
  if (props.isShow && props.type === "edit") {
    form.value = {
      id: props.deviceInfo!.id,
      station_id: props.deviceInfo!.station_id,
      device_id: props.deviceInfo!.device_id,
      device_name: props.deviceInfo!.device_name,
      device_name_chn: props.deviceInfo!.device_name_chn,
      protocol_name: props.deviceInfo!.protocol_name,
      communicate_mode: props.deviceInfo!.communicate_mode,
      tcp_ip: props.deviceInfo!.tcp_ip,
      tcp_port: props.deviceInfo!.tcp_port,
      udp_ip_src: props.deviceInfo!.udp_ip_src,
      udp_port_src: props.deviceInfo!.udp_port_src,
      udp_ip_dst: props.deviceInfo!.udp_ip_dst,
      udp_port_dst: props.deviceInfo!.udp_port_dst,
    }
    handleModeChange(form.value.communicate_mode)
    checked_performance_fields.value = props.deviceInfo!.checked_performance_fields!
    handleProtocolChange(form.value.protocol_name, checked_performance_fields.value)
  }
})

// 校验 ip 是否正确
const validateIP = (_: any, value: any, callback: any) => {
  if (value === '') {
    callback(new Error('Please input the IP again'))
  }
  const ipRegex = /^(\d{1,3}\.){3}\d{1,3}$/;
  if (!ipRegex.test(value)) {
    callback(new Error('请输入有效的IP地址'));
  } else {
    callback();
  }
}

// 校验 port 是否正确
const validatePort = (_: any, value: any, callback: any) => {
  if (value === '') {
    callback(new Error('Please input the port again'))
  }
  const portRegex = /^[1-9]\d{1,4}$/;
  if (!portRegex.test(value)) {
    callback(new Error('请输入有效的端口'));
  } else {
    callback();
  }
}

// 表单校验规则
const rules = reactive<FormRules<typeof form>>({
  station_id: [{ required: true, message: 'Please input station id', trigger: 'blur' }],
  // device_id: [{ required: true, message: 'Please input device id', trigger: 'blur' }],
  device_name: [{ required: true, message: 'Please input device name', trigger: 'blur' }],
  device_name_chn: [{ required: true, message: 'Please input device name chn', trigger: 'blur' }],
  protocol_name: [{ required: true, message: 'Please input protocol name', trigger: 'blur' }],
  communicate_mode: [{ required: true, message: 'Please input communicate mode', trigger: 'blur' }],
  tcp_ip: [
    { required: true, message: 'Please input tcp ip', trigger: 'blur' },
    { validator: validateIP, trigger: 'blur' }],
  tcp_port: [
    { required: true, message: 'Please input tcp port', trigger: 'blur' },
    { validator: validatePort, trigger: 'blur'}
  ],
  udp_ip_src: [
    { required: true, message: 'Please input upd src ip', trigger: 'blur' },
    { validator: validateIP, trigger: 'blur' }],
  udp_port_src: [
    { required: true, message: 'Please input udp src port', trigger: 'blur' },
    { validator: validatePort, trigger: 'blur'}
  ],
  udp_ip_dst: [
    { required: true, message: 'Please input udp dst ip', trigger: 'blur' },
    { validator: validateIP, trigger: 'blur' }],
  udp_port_dst: [
    { required: true, message: 'Please input udp dst port', trigger: 'blur' },
    { validator: validatePort, trigger: 'blur'}
  ],

})

// 下拉框选择触发的事件
const handleProtocolChange = (protocol_name: string, checked_fields: string[]) => {
  axios.get('/api/device_communication/protocol_performance/' + protocol_name + '/')
    .then((res) => {
      performance_fields.value = res.data
      checked_performance_fields.value = checked_fields
    })
    .catch((err) => {
      console.log(err);
    })
}

// 性能参数相关
const checkAll = ref(false)
// 设置不确定状态，仅负责样式控制
const isIndeterminate = ref(true)
const performance_fields = ref<string[]>([])
const checked_performance_fields = ref<string[]>([])

// 全选
const handleCheckAllChange = (val: CheckboxValueType) => {
  checked_performance_fields.value = val ? performance_fields.value : []
  isIndeterminate.value = false
}

// 选中某个
const handleCheckedFieldsChange = (value: CheckboxValueType[]) => {
  const checkedCount = value.length
  checkAll.value = checkedCount === performance_fields.value.length
  isIndeterminate.value = checkedCount > 0 && checkedCount < performance_fields.value.length
}

// 选择通信模式后
const isTcp = ref(true)
const handleModeChange = (value: string) => {
  console.log(value)
  isTcp.value = value.toUpperCase().includes('TCP'.toUpperCase())
}

// 提交表单
const submit_form = () => {
  // 表单字段全部正确才能提交
  formRef.value!.validate((valid: boolean) => {
    if (valid) {
      submit()
    } else {
      ElMessage({
        message: '请检查表单',
        type: 'error'
      })
    }
  })
}

const submit = () => {
  // 获取表单数据
  let data: DeviceInfo = {
    station_id: form.value.station_id,
    device_id: form.value.device_id,
    device_name: form.value.device_name,
    device_name_chn: form.value.device_name_chn,
    protocol_name: form.value.protocol_name,
    communicate_mode: form.value.communicate_mode,
    tcp_ip: form.value.tcp_ip,
    tcp_port: form.value.tcp_port,
    udp_ip_src: form.value.udp_ip_src,
    udp_port_src: form.value.udp_port_src,
    udp_ip_dst: form.value.udp_ip_dst,
    udp_port_dst: form.value.udp_port_dst,
    performance_fields: JSON.stringify(checked_performance_fields.value)
  }

  if (props.type === "add") {
    // 添加通信参数方法
    axios.post('/api/device_communication/' + props.tabType + '/', data)
      .then((res) => {
        console.log(res.data)
        data = res.data
        ElMessage({
          message: '创建成功',
          type: 'success'
        })
        emit('changeDeviceInfo', data)
      })
      .catch((err) => {
        console.log(err);
      })
  }
  else if (props.type === "edit")
  {
    // 修改通信参数方法
    data.id = form.value.id

    axios.put('/api/device_communication/' + props.tabType + '/' + data.id + '/', data)
      .then((res) => {
        console.log(res);
        ElMessage({
          message: '修改成功',
          type: 'success'
        })
        emit('changeDeviceInfo', data)
      })
      .catch((err) => {
        console.log(err);
      })
  }
  emit('close')
}


</script>
