<template>
  <AppPage>
    <n-card>
      <n-tabs default-value="Server" justify-content="space-evenly" type="line" @update-value="tabChange">
        <n-tab-pane name="Server" tab="服务端">
          <n-form
            ref="serverFormRef"
            :model="serverFormModel"
            :rules="serverFormRules"
          >
            <n-form-item label="IP段" path="ipScope" :rule="{
              required: true,
              type: 'array',
              message: 'IP段不能为空',
              trigger: ['change','blur']
            }">
              <n-select
                v-model:value="serverFormModel.ipScope"
                filterable
                multiple
                tag
                placeholder="输入，按回车确认"
                :show-arrow="false"
                :show="false"
              />
            </n-form-item>
            <n-form-item label="监听端口" path="listenPort" :rule="[
              {
                required: true,
                type: 'number',
                message: '监听端口不能为空',
                trigger: ['change','blur']
              },
              {
                min: 1120,
                type: 'number',
                message: '端口最低设置为1120',
                trigger: ['change','blur']
              },
              {
                max: 65535,
                type: 'number',
                message: '端口最高设置为65535',
                trigger: ['change','blur']
              }
            ]">
              <n-input-number :min="1120" :max="65535" v-model:value="serverFormModel.listenPort"/>
            </n-form-item>
            <n-form-item label="私钥" path="privateKey">
              <n-input v-model:value="serverFormModel.privateKey"/>
            </n-form-item>
            <n-form-item label="公钥" path="publicKey">
              <n-input v-model:value="serverFormModel.publicKey"/>
            </n-form-item>
            <n-form-item label="上行脚本" path="postUpScript">
              <n-input v-model:value="serverFormModel.postUpScript"/>
            </n-form-item>
            <n-form-item label="下行脚本" path="postDownScript">
              <n-input v-model:value="serverFormModel.postDownScript"/>
            </n-form-item>
            <n-form-item>
              <n-button type="info" @click="updateServerConf">确认</n-button>
            </n-form-item>
          </n-form>
        </n-tab-pane>
        <n-tab-pane name="Global" tab="全局">
          <n-form
            ref="globalFormRef"
            :model="globalFormModel"
            :rules="globalFormRules"
          >
            <n-form-item label="公网IP" path="endpointAddress" class="pid">
              <n-input v-model:value="globalFormModel.endpointAddress"/>
              <n-button style="margin-top: 5px" size="small" type="warning" @click="getPublicAddr">获取地址</n-button>
            </n-form-item>
            <n-form-item label="DNS" path="dnsServer" :rule="{
              required: true,
              type: 'array',
              message: 'dns不能为空',
              trigger: ['change','blur']
            }">
              <n-select
                v-model:value="globalFormModel.dnsServer"
                filterable
                multiple
                tag
                placeholder="输入，按回车确认"
                :show-arrow="false"
                :show="false"
              />
            </n-form-item>
            <n-form-item label="MTU" path="MTU" :rule="[
              {
                required: true,
                type: 'number',
                message: 'MTU不能为空',
                trigger: ['change','blur']
              },
              {
                min: 1120,
                type: 'number',
                message: 'MTU最低设置为100',
                trigger: ['change','blur']
              },
              {
                max: 3000,
                type: 'number',
                message: 'MTU最高设置为3000',
                trigger: ['change','blur']
              }
            ]">
              <n-input-number :min="100" :max="3000" v-model:value="globalFormModel.MTU"/>
            </n-form-item>
            <n-form-item label="persistentKeepalive" path="persistentKeepalive" :rule="[
              {
                required: true,
                type: 'number',
                message: 'persistentKeepalive不能为空',
                trigger: ['change','blur']
              },
              {
                min: 15,
                type: 'number',
                message: 'persistentKeepalive最低设置为15',
                trigger: ['change','blur']
              },
              {
                max: 300,
                type: 'number',
                message: 'persistentKeepalive最高设置为300',
                trigger: ['change','blur']
              }
            ]">
              <n-input-number :min="15" :max="300" v-model:value="globalFormModel.persistentKeepalive"/>
            </n-form-item>
            <n-form-item label="firewallMark" path="firewallMark">
              <n-input v-model:value="globalFormModel.firewallMark"/>
            </n-form-item>
            <n-form-item label="table" path="table">
              <n-input v-model:value="globalFormModel.table"/>
            </n-form-item>
            <n-form-item label="configPath" path="configFilePath">
              <n-input v-model:value="globalFormModel.configFilePath"/>
            </n-form-item>
            <n-form-item>
              <n-button type="info" @click="updateGlobalConf">确认</n-button>
            </n-form-item>
          </n-form>
        </n-tab-pane>
        <n-tab-pane name="Other" tab="其他">
            <n-button style="float:right;margin-bottom: 10px" size="small" type="info" @click="showAddModal = !showAddModal">添加</n-button>
            <n-data-table
              :columns="tableColumns"
              :data="taleData.data"
            />
        </n-tab-pane>
      </n-tabs>
    </n-card>
    <n-modal
      :title="editFormModel.describe"
      v-model:show="showEditModal"
      preset="card"
      style="width: 30%"
    >
      <n-form
        ref="editFormRef"
        :model="editFormModel"
      >
        <n-form-item v-for="(item,index) in editFormModel.data" :label="index">
          <n-input v-if="typeof item === 'string'" v-model:value="editFormModel.data[index]"/>
          <n-input-number v-else-if="typeof item === 'number'" v-model:value="editFormModel.data[index]"/>
          <n-radio-group v-else-if="typeof item === 'boolean'" :value="editFormModel.data[index]">
            <n-radio :value="true" :checked="editFormModel.data[index] === true" @change="editFormModel.data[index] = true">是</n-radio>
            <n-radio :value="false" :checked="editFormModel.data[index] === false" @change="editFormModel.data[index] = false">否</n-radio>
          </n-radio-group>
        </n-form-item>
        <n-form-item label="配置描述">
          <n-input v-model:value="editFormModel.describe" />
        </n-form-item>
        <n-form-item>
          <n-button type="info" @click="updateSetting">确认</n-button>
        </n-form-item>
      </n-form>
    </n-modal>
    <n-modal
      title="添加"
      v-model:show="showAddModal"
      preset="card"
      style="width: 30%"
    >
      <n-form :model="addFormModel" ref="addFormRef">
        <n-form-item label="Code">
          <n-input v-model:value="addFormModel.code"></n-input>
        </n-form-item>
        <n-form-item label="选项">
          <n-dynamic-input v-model:value="addFormModel.data" preset="pair" key-placeholder="键" value-placeholder="值"/>
        </n-form-item>
        <n-form-item label="描述">
          <n-input v-model:value="addFormModel.describe"></n-input>
        </n-form-item>
        <n-form-item>
          <n-button type="info" @click="addSetting">确认</n-button>
        </n-form-item>
      </n-form>
    </n-modal>
  </AppPage>
</template>
<script setup>

// 服务端配置表单ref
import AppPage from '@/components/page/AppPage.vue'
import api from '@/views/setting/api'
import { NButton } from 'naive-ui'
import { renderIcon } from '@/utils'
import event from '@/utils/event/event'

const { $bus } = event();
const tabCode = ref("")

// 表头
const tableColumns = [
  {
    title: 'code',
    key: 'code',
    align: 'center',
    titleAlign: 'center',
  },
  {
    title: "描述",
    key: "describe",
    align: 'center',
    titleAlign: 'center',
  },
  {
    title: '操作',
    key: 'action',
    align: 'center',
    titleAlign: 'center',
    render: (row) => {
      return [
        h(NButton, {
          size: 'small',
          color: '#4389DA',
          onClick: () => listBtn(row, "EDIT")
        }, {
          icon: renderIcon('mingcute:edit-line', { size: 14 }),
        }),
        h(NButton, {
          size: 'small',
          style: 'margin-left: 5px',
          color: '#ED1518',
          onClick: () => listBtn(row, "DELETE")
        }, {
          icon: renderIcon('icon-park-outline:delete', { size: 14 }),
        })
      ]
    }
  }
]

const taleData = ref({
  data: []
})

// 服务端表单ref
const serverFormRef = ref(null)
// 全局设置表单ref
const globalFormRef = ref(null)
// 编辑模态框表单ref
const editFormRef = ref(null)
// 添加模态框表单ref
const addFormRef = ref(null)
// 编辑模态框展示
const showEditModal = ref(false)
// 添加模态框展示
const showAddModal = ref(false)

// 服务端表单数据
const serverFormModel = ref({
  ipScope: [],
  listenPort: 51820,
  privateKey: '',
  publicKey: '',
  postUpScript: '',
  postDownScript: ''
})
// 全局设置表单数据
const globalFormModel = ref({
  MTU: 1450,
  configFilePath: '',
  dnsServer: [],
  endpointAddress: '',
  firewallMark: '',
  persistentKeepalive: 15,
  table: ''
})
// 编辑表单数据
const editFormModel = ref({
  code: '',
  data: '',
  describe: ''
})
// 添加表单数据
const addFormModel = ref({
  code: '',
  data: [
    {
      key: '',
      value: ''
    }
  ],
  describe: ''
})

// 服务端表单数据验证
const serverFormRules = {
  privateKey: [
    { required: true, message: '密钥不能为空', trigger: 'blur' }
  ],
  publicKey: [
    { required: true, message: '公钥不能为空', trigger: 'blur' }
  ]
}
// 全局表单数据验证
const globalFormRules = {
  endpointAddress: [
    { required: true, message: '公网IP不能为空', trigger: 'blur' }
  ],
  configFilePath: [
    { required: true, message: '文件地址不能为空', trigger: 'blur' }
  ]
}

// 获取服务端配置
async function getServerConfig () {
  const res = await api.getSetting({
    code: "WG_SERVER"
  })
  if (res.data.code === 200) {
    serverFormModel.value = JSON.parse(res.data.data)
  }
}

// 获取全局配置
async function getGlobalConfig () {
  const res = await api.getSetting({
    code: "WG_SETTING"
  })
  if (res.data.code === 200) {
    globalFormModel.value = JSON.parse(res.data.data)
  }
}

// 更改服务端配置
async function updateServerConf() {
  serverFormRef.value?.validate(async (errors) => {
    if (errors) {
      return errors
    }
    const res = await api.setSetting({
      code: "WG_SERVER",
      data: JSON.stringify(serverFormModel.value)
    })
    if (res.data.code === 200) {
      await getServerConfig()
      $message.success("操作成功")
    }
  })

}

// 更改全局配置
async function updateGlobalConf() {
  globalFormRef.value?.validate(async (errors) => {
    if (errors) {
      return errors
    }
    const res = await api.setSetting({
      code: "WG_SETTING",
      data: JSON.stringify(globalFormModel.value)
    })
    if (res.data.code === 200) {
      await getGlobalConfig()
      $message.success("操作成功")
    }
  })
}

// 获取公网IP地址
async function getPublicAddr() {
  const res = await api.publicAddr()
  if (res.data.code === 200) {
    globalFormModel.value.endpointAddress = res.data.data
  }
}

// 获取全部配置
function allSetting() {
  api.allSettings().then(res => {
    if (res.data.code === 200) {
      taleData.value.data = res.data.data
    }
  })
}

// tab切换事件
function tabChange(code) {
  switch (code) {
    case "Server":
      getServerConfig()
      tabCode.value = "Server"
      break;
    case "Global":
      getGlobalConfig()
      tabCode.value = "Global"
      break;
    case "Other":
      allSetting()
      tabCode.value = "Other"
      break;
  }
}

// 列表操作按钮
function listBtn(row,code) {
  switch (code) {
    case "EDIT":
      showEditModal.value = true
      editFormModel.value.describe = row.describe
      editFormModel.value.data = JSON.parse(row.data)
      editFormModel.value.code = row.code
      break;
    case "DELETE":
      $dialog.confirm({
        type: 'warning',
        title: '删除',
        content: `是否删除设置：【${row.describe}】？`,
        async confirm() {
          const res = await api.delSetting(row.code)
          if (res.data.code === 200) {
            $message.success("操作成功")
            allSetting()
          }
        },
      })
      break;
  }
}

// 更改配置信息
async function updateSetting() {
    const res = await api.setSetting({
      code: editFormModel.value.code,
      data: JSON.stringify(editFormModel.value.data),
      describe: editFormModel.value.describe
    })
    if (res.data.code === 200) {
      showEditModal.value = false
      allSetting()
    }
}

// 添加设置
async function addSetting() {
  const dataObj = {}
  for (const item of addFormModel.value.data) {
    dataObj[item.key] = item.value
  }

  const addFormData = {
    code: addFormModel.value.code,
    data: JSON.stringify(dataObj),
    describe: addFormModel.value.describe
  }

  const res = await api.setSetting(addFormData)
  if (res.data.code === 200) {
    showAddModal.value = false
    addFormModel.value = {
      code: '',
      data: [
        {
          key: '',
          value: ''
        }
      ],
      describe: ''
    }
    allSetting()
  }
}

$bus.on("refreshSetting",value => {
  if (value) {
    if (tabCode.value === "" || tabCode.value === undefined) {
      getServerConfig()
    } else {
      switch (tabCode.value) {
        case "Server":
          getServerConfig()
          break;
        case "Global":
          getGlobalConfig()
          break;
      }
    }
  }
})
getServerConfig()
</script>
<style lang="scss">
.pid .n-form-item-blank {
  display: inline;
}
</style>