<script lang="ts" setup>
import { PageContainer } from 'antdv-pro-layout';
import { Modal } from 'ant-design-vue/es';
import { useFullscreen } from '@vueuse/core';
import { defineAsyncComponent, reactive, ref } from 'vue';
import { parseDuration } from '@/utils/date-utils';
import useI18n from '@/hooks/useI18n';
const { t } = useI18n();
const TerminalSSH = defineAsyncComponent(
  () => import('@/components/TerminalSSH/index.vue')
);
const TerminalTelnet = defineAsyncComponent(
  () => import('@/components/TerminalTelnet/index.vue')
);
const TerminalRedis = defineAsyncComponent(
  () => import('@/components/TerminalRedis/index.vue')
);
const HostList = defineAsyncComponent(
  () => import('./components/hostList.vue')
);

// 全屏
const terminalCard = ref<HTMLElement | null>(null);
const { isFullscreen, toggle } = useFullscreen(terminalCard);

/**主机对象信息状态类型 */
type HostStateType = {
  /**显示主机列表 */
  show: boolean;
  /**加载等待 */
  loading: boolean;
  /**查询参数 */
  params: {
    pageNum: number;
    pageSize: number;
  };
  /**数据总数 */
  total: number;
  data: Record<string, any>[];
};

/**主机对象信息状态 */
const hostState: HostStateType = reactive({
  show: false,
  loading: false,
  params: {
    pageNum: 1,
    pageSize: 20,
  },
  total: 0,
  data: [],
});

/**连接主机 */
function fnConnectHost(data: Record<string, any>) {
  const id = `${Date.now()}`;
  tabState.panes.push({
    id,
    status: false,
    host: data,
  });
  tabState.activeKey = id;
}

/**标签对象信息状态类型 */
type TabStateType = {
  /**激活选中 */
  activeKey: string;
  /**页签数据 */
  panes: {
    id: string;
    status: boolean;
    host: Record<string, any>;
    connectStamp?: string;
  }[];
};

/**标签对象信息状态 */
const tabState: TabStateType = reactive({
  activeKey: '0',
  panes: [
    {
      id: '0',
      host: {
        id: 0,
        title: t('views.tool.terminal.start'),
        type: '0',
      },
      status: true,
    },
  ],
});

/**
 * 终端连接状态
 * @param data 主机连接结果
 */
function fnTerminalConnect(data: Record<string, any>) {
  const { id, timeStamp } = data;
  const seconds = timeStamp / 1000;
  // 获取当前项下标
  const tab = tabState.panes.find(item => item.id === id);
  if (tab) {
    tab.status = true;
    tab.connectStamp = parseDuration(seconds);
  }
}

/**
 * 终端关闭状态
 * @param data 主机连接结果
 */
function fnTerminalClose(data: Record<string, any>) {
  const { id } = data;
  // 获取当前项下标
  const tab = tabState.panes.find(item => item.id === id);
  if (tab) {
    tab.status = false;
  }
}

/**
 * 标签更多菜单项
 * @param key 菜单key
 */
function fnTabMenu(key: string | number) {
  // 刷新当前
  if (key === 'reload') {
    const tabIndex = tabState.panes.findIndex(
      item => item.id === tabState.activeKey
    );
    if (tabIndex) {
      const tab = tabState.panes[tabIndex];
      Modal.confirm({
        title: t('common.tipTitle'),
        content: t('views.tool.terminal.reloadTip', {
          num: `${tab.host.hostType} - ${tab.host.title}`,
        }),
        onOk() {
          tabState.panes.splice(tabIndex, 1);
          tab.host && fnConnectHost(tab.host);
        },
      });
    }
  }
  // 关闭当前
  if (key === 'current') {
    fnTabClose(tabState.activeKey);
  }
  // 关闭其他
  if (key === 'other') {
    Modal.confirm({
      title: t('common.tipTitle'),
      content: t('views.tool.terminal.otherTip'),
      onOk() {
        hostState.show = false;
        tabState.panes = tabState.panes.filter(
          tab => tab.id === '0' || tab.id === tabState.activeKey
        );
        tabState.activeKey = tabState.activeKey;
      },
    });
  }
  // 关闭全部
  if (key === 'all') {
    Modal.confirm({
      title: t('common.tipTitle'),
      content: t('views.tool.terminal.allTip'),
      onOk() {
        hostState.show = false;
        tabState.panes.splice(1);
        tabState.activeKey = '0';
      },
    });
  }
}

/**
 * 导航标签关闭
 * @param id 标签的key
 */
function fnTabClose(id: string) {
  if (isFullscreen.value) toggle();

  // 获取当前项下标
  const tabIndex = tabState.panes.findIndex(tab => tab.id === id);
  if (tabIndex === -1) return;
  const item = tabState.panes[tabIndex];
  Modal.confirm({
    title: t('common.tipTitle'),
    content: t('views.tool.terminal.closeTip', {
      num: `${item.host.hostType.toUpperCase()} - ${item.host.title}`,
    }),
    onOk() {
      tabState.panes.splice(tabIndex, 1);
      // 激活前一项标签
      tabState.activeKey = tabState.panes[tabIndex - 1].id;
    },
  });
}
</script>

<template>
  <PageContainer>
    <a-card
      :bordered="false"
      size="small"
      :body-style="{ padding: '12px' }"
      ref="terminalCard"
    >
      <a-tabs
        class="terminal-tabs"
        hide-add
        size="small"
        tab-position="top"
        type="editable-card"
        :tab-bar-gutter="8"
        :tab-bar-style="{ margin: '0' }"
        v-model:activeKey="tabState.activeKey"
        @edit="(id:any) => fnTabClose(id)"
      >
        <a-tab-pane
          v-for="pane in tabState.panes"
          :key="pane.id"
          :closable="pane.id !== '0'"
        >
          <template #tab>
            <a-badge
              :status="pane.status ? 'success' : 'error'"
              :text="pane.host.title"
            />
          </template>

          <div class="pane-box">
            <!-- 非开始页的ssh主机 -->
            <TerminalSSH
              v-if="pane.id !== '0' && pane.host.hostType === 'ssh'"
              :id="pane.id"
              :hostId="pane.host.id"
              @connect="fnTerminalConnect"
              @close="fnTerminalClose"
            >
            </TerminalSSH>

            <!-- 非开始页的telnet主机 -->
            <TerminalTelnet
              v-if="pane.id !== '0' && pane.host.hostType === 'telnet'"
              :id="pane.id"
              :hostId="pane.host.id"
              init-cmd="help"
              :disable="true"
              @connect="fnTerminalConnect"
              @close="fnTerminalClose"
            >
            </TerminalTelnet>

            <!-- 非开始页的redis主机 -->
            <TerminalRedis
              v-if="pane.id !== '0' && pane.host.hostType === 'redis'"
              :id="pane.id"
              :hostId="pane.host.id"
              init-cmd="PING"
              @connect="fnTerminalConnect"
              @close="fnTerminalClose"
            >
            </TerminalRedis>

            <!-- 开始页 -->
            <div v-if="pane.id === '0'">
              <!-- 主机列表 -->
              <HostList
                v-show="tabState.activeKey === '0'"
                @modal="() => (isFullscreen ? toggle() : null)"
                @link="fnConnectHost"
              ></HostList>
            </div>
          </div>
        </a-tab-pane>

        <template #rightExtra>
          <a-space :size="8" align="center">
            <a-tooltip placement="topRight">
              <template #title>
                {{ t('loayouts.rightContent.fullscreen') }}
              </template>
              <a-button
                type="default"
                shape="circle"
                size="small"
                style="color: inherit"
                @click="toggle"
              >
                <template #icon>
                  <FullscreenExitOutlined v-if="isFullscreen" />
                  <FullscreenOutlined v-else />
                </template>
              </a-button>
            </a-tooltip>
            <!-- 非开始页的更多操作 -->
            <div v-show="tabState.activeKey !== '0'">
              <a-tooltip placement="topRight">
                <template #title>
                  {{ t('views.tool.terminal.more') }}
                </template>
                <a-dropdown trigger="click" placement="bottomRight">
                  <a-button type="ghost" shape="circle" size="small">
                    <template #icon><EllipsisOutlined /></template>
                  </a-button>
                  <template #overlay>
                    <a-menu @click="({ key }:any) => fnTabMenu(key)">
                      <a-menu-item key="reload">
                        {{ t('views.tool.terminal.reload') }}
                      </a-menu-item>
                      <a-menu-item key="current">
                        {{ t('views.tool.terminal.current') }}
                      </a-menu-item>
                      <a-menu-item key="other">
                        {{ t('views.tool.terminal.other') }}
                      </a-menu-item>
                      <a-menu-item key="all">
                        {{ t('views.tool.terminal.all') }}
                      </a-menu-item>
                    </a-menu>
                  </template>
                </a-dropdown>
              </a-tooltip>
            </div>
          </a-space>
        </template>
      </a-tabs>
    </a-card>
  </PageContainer>
</template>

<style lang="less" scoped>
.pane-box {
  height: calc(100vh - 200px);
  overflow-x: hidden;
}
</style>
