<template>
  <div class="app-container">
    <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
      <el-form-item label="IP地址" prop="ipAddress">
        <el-input
          v-model="queryParams.ipAddress"
          placeholder="请输入IP地址"
          clearable
          @keyup.enter.native="handleQuery"
        />
      </el-form-item>
      <el-form-item label="开始时间" prop="accessStartTime">
        <el-date-picker clearable
                        v-model="queryParams.accessStartTime"
                        type="date"
                        value-format="yyyy-MM-dd"
                        placeholder="请选择允许访问的开始时间"
        >
        </el-date-picker>
      </el-form-item>
      <el-form-item label="结束时间" prop="accessEndTime">
        <el-date-picker clearable
                        v-model="queryParams.accessEndTime"
                        type="date"
                        value-format="yyyy-MM-dd"
                        placeholder="请选择允许访问的结束时间"
        >
        </el-date-picker>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
      </el-form-item>
    </el-form>

    <el-row :gutter="10" class="mb8">
      <el-col :span="1.5">
        <el-button
          type="primary"
          plain
          icon="el-icon-plus"
          size="mini"
          @click="handleAdd"
          v-hasPermi="['system:whitelist:add']"
        >新增
        </el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="success"
          plain
          icon="el-icon-edit"
          size="mini"
          :disabled="single"
          @click="handleUpdate"
          v-hasPermi="['system:whitelist:edit']"
        >修改
        </el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="danger"
          plain
          icon="el-icon-delete"
          size="mini"
          :disabled="multiple"
          @click="handleDelete"
          v-hasPermi="['system:whitelist:remove']"
        >删除
        </el-button>
      </el-col>
      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
    </el-row>

    <el-table v-loading="loading" :data="whitelistList" @selection-change="handleSelectionChange">
      <el-table-column type="selection" width="55" align="center"/>
      <el-table-column type="index" label="序号" width="50"/>
      <el-table-column label="IP地址" align="center" prop="ipAddress" min-width="120px">
        <template slot-scope="scope">
          <span> {{scope.row.ipAddress?scope.row.ipAddress:scope.row.ipRangeStart+" - " + scope.row.ipRangeEnd}} </span>
        </template>
      </el-table-column>
      <el-table-column label="开放时间" align="center" prop="ipRangeStart" min-width="120px">
        <template slot-scope="scope">
          <span> {{!scope.row.accessStartTime?"不限时间":parseTime(scope.row.accessStartTime)+" - " + parseTime(scope.row.accessEndTime)}} </span>
        </template>
      </el-table-column>
      <el-table-column label="状态" align="center" key="status" min-width="20px">
        <template slot-scope="scope">
          <el-switch v-model="scope.row.status" active-value="0" inactive-value="1"
                     @change="handleStatusChange(scope.row)"
          ></el-switch>
        </template>
      </el-table-column>
      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
        <template slot-scope="scope">
          <el-button
            size="mini"
            type="text"
            icon="el-icon-edit"
            @click="handleUpdate(scope.row)"
            v-hasPermi="['system:whitelist:edit']"
          >修改
          </el-button>
          <el-button
            size="mini"
            type="text"
            icon="el-icon-delete"
            @click="handleDelete(scope.row)"
            v-hasPermi="['system:whitelist:remove']"
          >删除
          </el-button>
        </template>
      </el-table-column>
    </el-table>

    <pagination
      v-show="total>0"
      :total="total"
      :page.sync="queryParams.pageNum"
      :limit.sync="queryParams.pageSize"
      @pagination="getList"
    />

    <!-- 添加或修改【请填写功能名称】对话框 -->
    <el-dialog title="新增" :visible.sync="open" width="800px">
      <el-form ref="form" :model="form" :rules="rules">
        <!-- IP 地址选择 -->
        <el-form-item label="IP地址" required>
          <el-radio-group v-model="ipType">
            <el-radio label="single">单IP地址</el-radio>
            <el-radio label="range">IP地址段</el-radio>
          </el-radio-group>
          <el-row v-show="ipType === 'single'" :gutter="24">
            <el-col :span="10">
              <IpInput
                style="margin-top: 10px"
                v-model="form.ipAddress"
                :disabled=false
              />
            </el-col>
          </el-row>
          <el-row v-show="ipType === 'range'" :gutter="24">
            <el-col :span="10">
              <IpInput
                v-model="form.ipRangeStart"
                style="margin-top: 10px"
                :disabled=false
              />
            </el-col>
            <el-col :span="1">
              <div style="margin-top: 10px">
                <span>—</span>
              </div>
            </el-col>
            <el-col :span="10">
              <IpInput
                v-model="form.ipRangeEnd"
                style="margin-top: 10px"
                :disabled=false
              />
            </el-col>
          </el-row>
        </el-form-item>
        <!-- 访问时间设置 -->
        <el-form-item label="设置访问时间" required>
          <el-radio-group v-model="timeLimit">
            <el-radio label="unlimited">不限时间</el-radio>
            <el-radio label="limited">限制时间</el-radio>
          </el-radio-group>
          <el-row v-if="timeLimit === 'limited'" :gutter="24">
            <el-col :span="10">
              <el-date-picker
                v-model="form.accessStartTime"
                type="datetimerange"
                value-format="yyyy-MM-dd HH:mm:ss"
                range-separator="至"
                start-placeholder="开始日期"
                end-placeholder="结束日期">
              </el-date-picker>
            </el-col>
          </el-row>

        </el-form-item>
        <!-- 确认与取消按钮 -->
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="addSubmitForm">确 定</el-button>
        <el-button @click="cancel">取 消</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import { addWhitelist, delWhitelist, getWhitelist, listWhitelist, updateWhitelist,updateSysIpWhitelistStatus } from '@/api/system/ipWhitelist'
import IpInput from '@/components/bonus/IpInput/index.vue'
import { parseTime } from '../../../utils/bonus'
import { changeUserStatus } from '@/api/system/user'

export default {
  components: { IpInput },
  name: 'Whitelist',
  data() {
    return {
      // 遮罩层
      loading: true,
      // 选中数组
      ids: [],
      // 非单个禁用
      single: true,
      // 非多个禁用
      multiple: true,
      // 显示搜索条件
      showSearch: true,
      // 总条数
      total: 0,
      // 【请填写功能名称】表格数据
      whitelistList: [],
      // 弹出层标题
      title: '',
      // 是否显示弹出层
      open: false,
      // 查询参数
      queryParams: {
        pageNum: 1,
        pageSize: 10,
        ipAddress: null,
        ipRangeStart: null,
        ipRangeEnd: null,
        accessStartTime: null,
        accessEndTime: null,
        createdAt: null,
        updatedAt: null
      },
      ipType: 'single',
      timeLimit: 'unlimited',
      // 表单参数
      form: {},
      // 表单校验
      rules: {
        ipAddress: [
          { required: true, message: '记录创建时间不能为空', trigger: 'blur' }
        ],
        ipRangeStart: [
          { required: true, message: '记录更新时间不能为空', trigger: 'blur' }
        ],
        ipRangeEnd: [
          { required: true, message: '记录更新时间不能为空', trigger: 'blur' }
        ]
      }
    }
  },
  created() {
    this.getList()
  },
  methods: {
    // 用户状态修改
    handleStatusChange(row) {
      let text = row.status === '0' ? '启用' : '停用'
      this.$modal.confirm('确认要"' + text + '吗？').then(function() {
        return updateSysIpWhitelistStatus(row.id, row.status)
      }).then(() => {
        this.$modal.msgSuccess(text + '成功')
      }).catch(function() {
        row.status = row.status === '0' ? '1' : '0'
      })
    },
    // 格式化时间为时分秒（HH:mm:ss）
    formatTime(timeStr) {
      return new Date(`1970-01-01T${timeStr.slice(11)}`); // 只取时分秒部分
    },
    parseTime,
    /** 查询【请填写功能名称】列表 */
    getList() {
      this.loading = true
      listWhitelist(this.queryParams).then(response => {
        this.whitelistList = response.rows
        this.total = response.total
        this.loading = false
      })
    },
    // 取消按钮
    cancel() {
      this.open = false
      this.reset()
    },
    // 表单重置
    reset() {
      this.form = {
        id: null,
        ipAddress: null,
        ipRangeStart: null,
        ipRangeEnd: null,
        accessStartTime: null,
        accessEndTime: null,
        createdAt: null,
        updatedAt: null
      }
      this.ipType ='single'
      this.timeLimit = 'unlimited'
      this.resetForm('form')
    },
    /** 搜索按钮操作 */
    handleQuery() {
      this.queryParams.pageNum = 1
      this.getList()
    },
    /** 重置按钮操作 */
    resetQuery() {
      this.resetForm('queryForm')
      this.handleQuery()
    },
    // 多选框选中数据
    handleSelectionChange(selection) {
      this.ids = selection.map(item => item.id)
      this.single = selection.length !== 1
      this.multiple = !selection.length
    },
    /** 新增按钮操作 */
    handleAdd() {
      this.reset()
      this.open = true
      this.title = '添加【请填写功能名称】'
    },
    /** 修改按钮操作 */
    handleUpdate(row) {
      this.reset()
      const id = row.id || this.ids
      getWhitelist(id).then(response => {
        this.form = response.data
        if (!this.form.ipAddress){
          this.ipType = 'range'
        }else {
          this.ipType = 'single'
        }
        if (!this.form.accessStartTime){
          this.timeLimit = 'unlimited'
        }else {
          this.timeLimit = 'limited'
          this.form.accessStartTime=[this.formatTime(this.form.accessStartTime), this.formatTime(this.form.accessEndTime)]
        }
        this.open = true
        this.title = '修改'
      })
    },
    addSubmitForm() {
      if (this.ipType === 'single') {
        if (!this.form.ipAddress) {
          this.$modal.msgWarning('请输入正确的ip地址')
          return
        } else {
          this.form.ipRangeStart = null
          this.form.ipRangeEnd = null
        }
      } else {
        if (!this.form.ipRangeStart || !this.form.ipRangeEnd) {
          this.$modal.msgWarning('请输入正确的ip地址段')
          return
        } else {
          if (!this.checkSameSubnet(this.form.ipRangeStart, this.form.ipRangeEnd)){
            this.$modal.msgWarning('请输入正确的ip地址段')
            return
          }
          if (!this.checkIpRangeValidity(this.form.ipRangeStart, this.form.ipRangeEnd)){
            this.$modal.msgWarning('请输入正确的ip地址段')
            return
          }
          this.form.ipAddress = null
        }
      }
      if (this.timeLimit === 'limited') {
        if (!this.form.accessStartTime){
          this.$modal.msgWarning('请选择访问时间段')
          return
        }else {
          const date = this.form.accessStartTime;
          this.form.accessStartTime = date[0];
          this.form.accessEndTime = date[1];
        }
      }else {
        this.form.accessStartTime = null;
        this.form.accessEndTime = null;
      }
      if (this.form.id != null) {
        updateWhitelist(this.form).then(response => {
          this.$modal.msgSuccess('修改成功')
          this.open = false
          this.getList()
        })
      } else {
        addWhitelist(this.form).then(response => {
          this.$modal.msgSuccess('新增成功')
          this.open = false
          this.getList()
        })
      }
    },
    // 将IP地址转换为二进制
    ipToBinary(ip) {
      return ip
        .split('.')
        .map((octet) => ('00000000' + parseInt(octet, 10).toString(2)).slice(-8))
        .join('')
    },

// 判断IP地址属于哪个类（A、B、C类）
    getClass(ip) {
      const firstOctet = parseInt(ip.split('.')[0], 10)
      if (firstOctet >= 1 && firstOctet <= 127) return 'A'
      if (firstOctet >= 128 && firstOctet <= 191) return 'B'
      if (firstOctet >= 192 && firstOctet <= 223) return 'C'
      return 'Unknown'
    },

// 获取默认子网掩码
    getDefaultSubnetMask(ip) {
      const ipClass = this.getClass(ip)
      switch (ipClass) {
        case 'A':
          return '255.0.0.0' // /8
        case 'B':
          return '255.255.0.0' // /16
        case 'C':
          return '255.255.255.0' // /24
        default:
          return null
      }
    },

// 将IP地址和子网掩码进行按位与运算，得到网络部分
    applySubnetMask(ipBinary, subnetBinary) {
      let network = ''
      for (let i = 0; i < 32; i++) {
        network += ipBinary[i] === subnetBinary[i] ? ipBinary[i] : '0'
      }
      return network
    },

// 判断两个IP是否在同一个网段
    checkSameSubnet(ip1, ip2) {
      const subnetMask = this.getDefaultSubnetMask(ip1)
      if (!subnetMask) return false // 如果没有子网掩码，则无法判断
      const ip1Binary = this.ipToBinary(ip1)
      const ip2Binary = this.ipToBinary(ip2)
      const subnetBinary = this.ipToBinary(subnetMask)

      const ip1Network = this.applySubnetMask(ip1Binary, subnetBinary)
      const ip2Network = this.applySubnetMask(ip2Binary, subnetBinary)

      return ip1Network === ip2Network
    },

// 检查IP范围是否有效
    checkIpRangeValidity(startIp, endIp) {
      const startBinary = this.ipToBinary(startIp)
      const endBinary = this.ipToBinary(endIp)
      // 确保起始IP小于等于结束IP
      return startBinary <= endBinary
    },
    /** 提交按钮 */
    submitForm() {
      this.$refs['form'].validate(valid => {
        if (valid) {

        }
      })
    },
    /** 删除按钮操作 */
    handleDelete(row) {
      const ids = row.id || this.ids
      this.$modal.confirm('是否确认删除这些数据项？').then(function() {
        return delWhitelist(ids)
      }).then(() => {
        this.getList()
        this.$modal.msgSuccess('删除成功')
      }).catch(() => {
      })
    },
    /** 导出按钮操作 */
    handleExport() {
      this.download('system/whitelist/export', {
        ...this.queryParams
      }, `whitelist_${new Date().getTime()}.xlsx`)
    }
  }
}
</script>

<style lang="scss" scoped>
.el-radio__original {
  display: none !important; /* 隐藏原生 radio 输入，但仍然允许交互 */
}

.el-radio:focus:not(.is-focus):not(:active):not(.is-disabled) .el-radio__inner {
  box-shadow: none !important;
}
</style>
