<template>
  <div>
    <div class="n-layout-page-header">
      <n-card :bordered="false" title="服务部署">
        在这里可以对游戏服务器节点进行维护，对游戏服务器进行版本发布、版本回退、基本状态监控等
      </n-card>
    </div>
    <n-card :bordered="false" class="proCard">
      <BasicForm
        @register="register"
        @submit="handleSubmit"
        @reset="handleReset"
        @keyup.enter="reloadTable"
        ref="searchFormRef"
      >
        <template #statusSlot="{ model, field }">
          <n-input v-model:value="model[field]" />
        </template>
      </BasicForm>
      <BasicTable
        :openChecked="true"
        :columns="columns"
        :request="loadDataTable"
        :row-key="(row) => row.id"
        ref="actionRef"
        :actionColumn="actionColumn"
        @update:checked-row-keys="onCheckedRow"
        :scroll-x="1090"
        :flex-height="false"
        :pagination="{ pageSize: 20 }"
        :resizeHeightOffset="-50000"
      >
        <template #tableTitle>
          <n-button type="primary" @click="addTable">
            <template #icon>
              <n-icon>
                <PlusOutlined />
              </n-icon>
            </template>
            新增服务器
          </n-button>

          <n-button
            type="success"
            @click="handleBatchDeploy"
            :disabled="batchDeployTaskDisabled"
            class="min-left-space"
          >
            <template #icon>
              <n-icon>
                <CodeSandboxOutlined />
              </n-icon>
            </template>
            批量发布
          </n-button>

          <n-button
            type="warning"
            @click="handleBatchStop"
            :disabled="batchDeployTaskDisabled"
            class="min-left-space"
          >
            <template #icon>
              <n-icon>
                <StopOutlined />
              </n-icon>
            </template>
            批量停服
          </n-button>
        </template>
      </BasicTable>

      <n-modal
        v-model:show="showModal"
        :show-icon="false"
        preset="dialog"
        :title="modalTitle"
        style="width: 40%"
      >
        <n-form
          :model="formParams"
          :rules="rules"
          ref="formRef"
          label-placement="left"
          :label-width="100"
          class="py-4"
        >
          <n-form-item label="服务器分组" path="group_id">
            <n-select v-model:value="formParams.group_id" :options="groupOptions" />
          </n-form-item>

          <n-form-item label="应用名称" path="name">
            <n-input placeholder="请输入名称" v-model:value="formParams.name" />
          </n-form-item>

          <n-form-item label="docker地址" path="docker_addr">
            <n-input placeholder="请输入docker地址" v-model:value="formParams.docker_addr" />
          </n-form-item>

          <n-form-item label="服务类型" path="server_type">
            <n-select v-model:value="formParams.server_type" :options="serverTypeOptions" />
          </n-form-item>

          <n-form-item label="容器名称" path="container_name">
            <n-input placeholder="请输入容器名称" v-model:value="formParams.container_name" />
          </n-form-item>

          <n-form-item label="ca.pem路径" path="ca_pem">
            <n-input placeholder="请输入" v-model:value="formParams.ca_pem" />
          </n-form-item>

          <n-form-item label="cert.pem路径" path="cert_pem">
            <n-input placeholder="请输入" v-model:value="formParams.cert_pem" />
          </n-form-item>

          <n-form-item label="key.pem路径" path="key_pem">
            <n-input placeholder="请输入" v-model:value="formParams.key_pem" />
          </n-form-item>

          <n-form-item label="部署MPRoom" path="is_mproom">
            <n-select v-model:value="formParams.is_mproom" :options="mpRoomOptions" />
          </n-form-item>

          <n-form-item label="备注" path="remark">
            <n-input type="textarea" placeholder="请输入备注" v-model:value="formParams.remark" />
          </n-form-item>
        </n-form>

        <template #action>
          <n-space>
            <n-button @click="() => (showModal = false)">取消</n-button>
            <n-button type="info" :loading="formBtnLoading" @click="confirmForm">确定</n-button>
          </n-space>
        </template>
      </n-modal>

      <n-modal
        v-model:show="showDeployModal"
        :show-icon="false"
        preset="dialog"
        :title="modalTitle"
      >
        <n-form
          :model="formDeployParams"
          ref="formDeployRef"
          label-placement="left"
          :label-width="100"
          class="py-4"
        >
          <n-form-item label="游戏版本号" path="version">
            <n-input placeholder="请输入游戏版本号" v-model:value="formDeployParams.version" />
          </n-form-item>

          <n-form-item label="选择部署服务" path="deployServ">
            <n-select
              v-model:value="formDeployParams.deployServ"
              multiple
              clearable
              :options="deployServOpt"
              :disabled="isBatchDeploy"
              @update:value="handleUpdateValue"
            />

            <template #feedback v-if="isBatchDeploy">
              <n-text style="color: red"
                >当前选择的服务类型存在不同类型，因此部署服务只能全选</n-text
              ></template
            >
          </n-form-item>
        </n-form>

        <template #action>
          <n-space>
            <n-button @click="() => (showDeployModal = false)">取消</n-button>
            <n-button type="info" :loading="formDeployBtnLoading" @click="confirmDeployForm"
              >确定</n-button
            >
          </n-space>
        </template>
      </n-modal>

      <n-modal v-model:show="showStopModal" :show-icon="false" preset="dialog" title="批量停服">
        <n-form
          :model="formStopParams"
          ref="formStopRef"
          label-placement="left"
          :label-width="80"
          class="py-4"
        >
          <n-form-item label="停止方式" path="stop_type">
            <n-select v-model:value="formStopParams.stop_type" :options="stopTypeOptions" />
            <template #feedback> 选择[强制停止]会立即终止服务，不会保存数据，谨慎选择</template>
          </n-form-item>
        </n-form>

        <template #action>
          <n-space>
            <n-button @click="() => (showStopModal = false)">取消</n-button>
            <n-button type="info" :loading="formStopBtnLoading" @click="confirmStopForm"
              >确定</n-button
            >
          </n-space>
        </template>
      </n-modal>
    </n-card>

    <RetrofitModal ref="RetrofitModalRef" :deploy_id="deploy_id" />
  </div>
</template>

<script lang="ts" setup>
  import { h, reactive, ref } from 'vue';
  import { useDialog, useMessage } from 'naive-ui';
  import { BasicTable, TableAction } from '@/components/Table';
  import {
    getDeployList,
    DeployDelete,
    DeployEdit,
    DeployTask,
    DeployStop,
  } from '@/api/deploy/deploy';
  import { columns, runStatus } from './columns';
  import { cloneDeep } from 'lodash-es';
  import { PlusOutlined, CodeSandboxOutlined, StopOutlined } from '@vicons/antd';
  import RetrofitModal from './modal/modal.vue';
  import { FormSchema, useForm } from '@/components/Form';
  import { useUserStoreWidthOut } from '@/store/modules/user';

  const defFormParams = {
    id: 0,
    group_id: 1,
    is_mproom: 1,
    container_name: '',
    name: '',
    docker_addr: '',
    ca_pem: '',
    cert_pem: '',
    key_pem: '',
    remark: '',
    server_type: 'grave',
  };

  const useUserStore = useUserStoreWidthOut();
  const deployServOpt = ref([]);
  const checkedIds = ref([]);
  const isBatchDeploy = ref(false);
  const batchDeployTaskDisabled = ref(true);
  const searchFormRef = ref<any>({});
  const message = useMessage();
  const modalTitle = ref('新增服务器');
  const showModal = ref(false);
  const formBtnLoading = ref(false);
  const showDeployModal = ref(false);
  const formDeployBtnLoading = ref(false);
  const dialog = useDialog();
  const actionRef = ref();
  const formParams = ref<any>(defFormParams);
  const formDeployRef = ref();
  const formRef = ref<any>({});
  const formStopRef = ref();
  const showStopModal = ref(false);
  const formStopBtnLoading = ref(false);

  const formStopParams = ref<any>({
    ids: 0,
    type: 0,
    stop_type: 2,
  });

  const rules = {
    name: {
      required: true,
      trigger: ['blur', 'input'],
      message: '请输入名称',
    },
  };

  const groupOptions = ref([
    {
      label: '微信',
      value: 1,
    },
    {
      label: '抖音',
      value: 2,
    },
  ]);

  const mpRoomOptions = ref([
    {
      label: '同意',
      value: 1,
    },
    {
      label: '禁止',
      value: 2,
    },
  ]);

  const serverTypeOptions = ref([
    {
      label: 'grave',
      value: 'grave',
    },
    {
      label: 'login',
      value: 'login',
    },
    {
      label: 'chaptermatch',
      value: 'chaptermatch',
    },
    {
      label: 'chaptersync',
      value: 'chaptersync',
    },
    {
      label: 'mproom',
      value: 'mproom',
    },
    // {
    //   label: 'gate',
    //   value: 'gate',
    // },
  ]);

  const stopTypeOptions = ref([
    {
      label: '停止',
      value: 2,
    },
    {
      label: '强制停止',
      value: 9,
    },
  ]);

  const runStatusOptions = ref(
    Object.entries(runStatus).map(([key, value]) => ({
      label: value,
      value: key,
    }))
  );

  const deployStatusOptions = ref([
    {
      value: 1,
      label: '等待部署',
    },
    {
      value: 2,
      label: '部署中',
    },
    {
      value: 3,
      label: '部署成功',
    },
    {
      value: 4,
      label: '部署失败',
    },
    {
      value: 5,
      label: '部署超时',
    },
  ]);

  const schemas: FormSchema[] = [
    {
      field: 'server_type',
      component: 'NSelect',
      label: '服务类型',
      componentProps: {
        multiple: true,
        placeholder: '请选择服务类型',
        options: serverTypeOptions.value,
        onUpdateValue: (e: any) => {
          console.log(e);
        },
      },
    },
    {
      field: 'name',
      component: 'NInput',
      label: '应用名称',
      componentProps: {
        placeholder: '请输入应用名称',
        onInput: (e: any) => {
          console.log(e);
        },
      },
    },
    {
      field: 'container_name',
      component: 'NInput',
      label: '容器名称',
      componentProps: {
        placeholder: '请输入容器名称',
        onInput: (e: any) => {
          console.log(e);
        },
      },
    },
    {
      field: 'run_status',
      component: 'NSelect',
      label: '运行状态',
      componentProps: {
        multiple: true,
        placeholder: '请选择',
        options: runStatusOptions.value,
        onUpdateValue: (e: any) => {
          console.log(e);
        },
      },
    },
    {
      field: 'deploy_status',
      component: 'NSelect',
      label: '部署状态',
      componentProps: {
        multiple: true,
        placeholder: '请选择',
        options: deployStatusOptions.value,
        onUpdateValue: (e: any) => {
          console.log(e);
        },
      },
    },
  ];

  const [register, {}] = useForm({
    gridProps: { cols: '6' },
    labelWidth: 80,
    schemas,
  });

  const actionColumn = reactive({
    width: 260,
    title: '操作',
    key: 'action',
    fixed: 'right',
    render(record) {
      return h(TableAction as any, {
        style: 'button',
        actions: [
          {
            type: 'success',
            label: '版本发布',
            onClick: handleDeploy.bind(null, record),
          },
          {
            type: 'default',
            label: '操作记录',
            onClick: handleConf.bind(null, record),
          },
          {
            label: '编辑',
            onClick: handleEdit.bind(null, record),
          },
          {
            label: '删除',
            onClick: handleDelete.bind(null, record),
          },
        ],
      });
    },
  });

  function addTable() {
    showModal.value = true;
    modalTitle.value = '新增服务器';
    formParams.value = cloneDeep(defFormParams);
  }

  function confirmForm(e) {
    e.preventDefault();
    formBtnLoading.value = true;
    formRef.value.validate((errors) => {
      if (!errors) {
        formParams.value.status = Number(formParams.value.status);
        formParams.value.sort = Number(formParams.value.sort);
        DeployEdit(formParams.value).then((_res) => {
          console.log('_res:' + JSON.stringify(_res));
          message.success('操作成功');
        });
        setTimeout(() => {
          showModal.value = false;
          reloadTable();
        });
      } else {
        message.error('请填写完整信息');
      }
      formBtnLoading.value = false;
    });
  }

  function confirmDeployForm(e) {
    e.preventDefault();
    formDeployBtnLoading.value = true;
    if (formDeployParams.value.type === 2) {
      formDeployParams.value.ids = checkedIds.value;
    }
    formDeployRef.value.validate((errors) => {
      if (!errors) {
        dialog.warning({
          title: '警告',
          content:
            '你确定要提交版本发布吗？此操作会重启该服务器节点的游戏服务，并重新部署当前提交的游戏版本号',
          positiveText: '确定',
          negativeText: '取消',
          onPositiveClick: () => {
            DeployTask(formDeployParams.value).then((_res) => {
              console.log('_res:' + JSON.stringify(_res));
              message.success('提交部署操作成功，部署结束后会推送结果通知，请稍后查看操作日志', {
                duration: 6000,
              });
            });
            setTimeout(() => {
              showDeployModal.value = false;
              reloadTable();
            });
          },
          onNegativeClick: () => {
            // message.error('取消');
          },
        });
      } else {
        message.error('请填写完整信息');
      }
      formDeployBtnLoading.value = false;
    });
  }

  function handleConf(record: Recordable) {
    console.log('handleConf', record);
    openUserModal(record.id);
  }

  const formDeployParams = ref<any>({
    id: 0,
    version: '',
    type: 0,
    deployServ: ['all'],
  });

  function handleDeploy(record: Recordable) {
    console.log('handleDeploy', record);

    const opt = useUserStore.config.deploy_serv_group_option[record.server_type];
    if (opt === undefined || opt == null || opt.length === 0) {
      message.error('获取服务选项失败，请联系服务端！');
      return;
    }

    showDeployModal.value = true;
    modalTitle.value = '版本发布';

    formDeployParams.value.type = 1;

    if (formDeployParams.value.id !== record.id) {
      formDeployParams.value.id = record.id;
      formDeployParams.value.deployServ = ['all'];
    }

    deployServOpt.value = opt;
    isBatchDeploy.value = false;
  }

  function handleEdit(record: Recordable) {
    console.log('handleEdit', record);
    showModal.value = true;
    modalTitle.value = '编辑服务器 ID：' + record.id;
    formParams.value = cloneDeep(record);
  }

  function handleDelete(record: Recordable) {
    console.log('点击了删除', record);
    dialog.warning({
      title: '警告',
      content: '你确定要删除？',
      positiveText: '确定',
      negativeText: '取消',
      onPositiveClick: () => {
        DeployDelete(record).then((_res) => {
          console.log('_res:' + JSON.stringify(_res));
          message.success('操作成功');
          reloadTable();
        });
      },
      onNegativeClick: () => {
        // message.error('取消');
      },
    });
  }

  const dataSource = ref({
    successful_order: 0,
    transaction_money: 0,
  });

  const loadDataTable = async (res) => {
    dataSource.value = await getDeployList({ ...searchFormRef.value?.formModel, ...res });
    return dataSource.value;
  };

  function onCheckedRow(rowKeys) {
    batchDeployTaskDisabled.value = rowKeys.length <= 0;
    checkedIds.value = rowKeys;
  }

  function reloadTable() {
    actionRef.value.reload();
  }

  const RetrofitModalRef = ref();
  const deploy_id = ref(0);
  function openUserModal(id) {
    deploy_id.value = id;
    const { openDrawer } = RetrofitModalRef.value;
    openDrawer();
  }

  function handleSubmit(values: Recordable) {
    console.log(values);
    reloadTable();
  }

  function handleReset(values: Recordable) {
    console.log(values);
    reloadTable();
  }

  function handleBatchDeploy(record: Recordable) {
    console.log('handleBatchDeploy', record);
    showDeployModal.value = true;
    modalTitle.value = '批量版本发布';
    formDeployParams.value.id = record.id;
    formDeployParams.value.deployServ = ['all'];
    formDeployParams.value.type = 2;
    isBatchDeploy.value = false;

    let serverType = '';
    for (const id of checkedIds.value) {
      const matchingData = dataSource.value.list.find((item) => item.id === id);
      if (matchingData) {
        if (serverType === '') {
          serverType = matchingData.server_type;
          continue;
        }

        if (serverType !== matchingData.server_type) {
          isBatchDeploy.value = true;
          break;
        }
      } else {
        message.error('批量选择的数据存在异常，请刷新后重试！');
        return;
      }
    }

    // 导入选项
    const opt = useUserStore.config.deploy_serv_group_option[serverType];
    if (opt === undefined || opt == null || opt.length === 0) {
      message.error('获取服务选项失败，请联系服务端！');
      return;
    }
    deployServOpt.value = opt;
  }

  function confirmStopForm(e) {
    e.preventDefault();
    formStopBtnLoading.value = true;
    if (formStopParams.value.type === 2) {
      formStopParams.value.ids = checkedIds.value;
    }
    formStopRef.value.validate((errors) => {
      if (!errors) {
        dialog.warning({
          title: '警告',
          content: '你确定要提交停服指令吗？此操作会停止该服务器节点的游戏服务',
          positiveText: '确定',
          negativeText: '取消',
          onPositiveClick: () => {
            DeployStop(formStopParams.value).then((_res) => {
              console.log('_res:' + JSON.stringify(_res));
              message.success('提交停服操作成功，部署结束后会推送结果通知，请稍后查看操作日志', {
                duration: 6000,
              });
            });
            setTimeout(() => {
              showStopModal.value = false;
              reloadTable();
            });
          },
          onNegativeClick: () => {
            // message.error('取消');
          },
        });
      } else {
        message.error('请填写完整信息');
      }
      formStopBtnLoading.value = false;
    });
  }

  function handleBatchStop(record: Recordable) {
    console.log('handleBatchStop', record);
    showStopModal.value = true;
    formStopParams.value.type = 2;
  }

  function handleUpdateValue(value) {
    console.log('handleUpdateValue value:' + JSON.stringify(value));
    // if (value.includes('all') && value.length > 1) {
    //   message.error('全选不能和其他服务同时选择！');
    //   return;
    // }

    if (value.includes('all') && value.length > 1) {
      value = value.filter((item) => item !== 'all');
    }
    formDeployParams.value.deployServ = value;
  }
</script>

<style lang="less" scoped></style>
