<script setup lang="ts">
import type { FormInstance } from 'element-plus';

import { markRaw, ref } from 'vue';

import { Delete, MoreFilled, Plus, Refresh } from '@element-plus/icons-vue';
import {
  ElAlert,
  ElButton,
  ElDialog,
  ElDropdown,
  ElDropdownItem,
  ElDropdownMenu,
  ElMessage,
  ElMessageBox,
  ElSwitch,
  ElTable,
  ElTableColumn,
  ElTag,
  ElTooltip,
} from 'element-plus';

import { api } from '#/api/request';
import HeaderSearch from '#/components/headerSearch/HeaderSearch.vue';
import ListPageShell from '#/components/page/ListPageShell.vue';
import PageData from '#/components/page/PageData.vue';
import { $t } from '#/locales';

import McpModal from './McpModal.vue';

const formRef = ref<FormInstance>();
const pageDataRef = ref();
const saveDialog = ref();
interface McpCheckItem {
  name: string;
  status: 'FAILED' | 'SUCCESS' | 'WARNING';
  message: string;
  detail?: string;
}

interface McpServerCheckResult {
  serverName: string;
  transport: string;
  status: 'FAILED' | 'SUCCESS' | 'WARNING';
  toolCount: number;
  checks: McpCheckItem[];
}

interface McpEnvironmentCheckResult {
  overallStatus: 'FAILED' | 'SUCCESS' | 'WARNING';
  servers: McpServerCheckResult[];
}

function reset(formEl: FormInstance | undefined) {
  formEl?.resetFields();
  pageDataRef.value.setQuery({});
}
function showDialog(row: any) {
  saveDialog.value.openDialog({ ...row });
}
function remove(row: any) {
  ElMessageBox.confirm($t('message.deleteAlert'), $t('message.noticeTitle'), {
    confirmButtonText: $t('message.ok'),
    cancelButtonText: $t('message.cancel'),
    type: 'warning',
    beforeClose: (action, instance, done) => {
      if (action === 'confirm') {
        instance.confirmButtonLoading = true;
        api
          .post('/api/v1/mcp/remove', { id: row.id })
          .then((res) => {
            instance.confirmButtonLoading = false;
            if (res.errorCode === 0) {
              ElMessage.success(res.message);
              reset(formRef.value);
              done();
            }
          })
          .catch(() => {
            instance.confirmButtonLoading = false;
          });
      } else {
        done();
      }
    },
  }).catch(() => {});
}
const handleUpdate = (row: any, isRefresh: boolean) => {
  if (isRefresh) {
    refreshLoadingMap.value[row.id] = true;
  } else {
    loadingMap.value[row.id] = true;
  }
  api.post('/api/v1/mcp/update', { ...row }).then((res) => {
    if (isRefresh) {
      refreshLoadingMap.value[row.id] = false;
    } else {
      loadingMap.value[row.id] = false;
    }
    if (res.errorCode === 0) {
      if (row.status) {
        ElMessage.success($t('mcp.message.startupSuccessful'));
      } else {
        ElMessage.success($t('mcp.message.stopSuccessful'));
      }
    }
    pageDataRef.value.setQuery({});
  });
};
const headerButtons = [
  {
    key: 'create',
    type: 'primary',
    text: $t('button.add'),
    icon: markRaw(Plus),
    data: { action: 'create' },
  },
];
const handleSearch = (params: string) => {
  pageDataRef.value.setQuery({ packageName: params, isQueryOr: true });
};
const handleHeaderButtonClick = (button: any) => {
  if (button.key === 'create') {
    showDialog({});
  }
};
const loadingMap = ref<Record<number | string, boolean>>({});
const refreshLoadingMap = ref<Record<number | string, boolean>>({});
const checkLoadingMap = ref<Record<number | string, boolean>>({});
const checkDialogVisible = ref(false);
const checkResult = ref<McpEnvironmentCheckResult>();

const checkTagType = (status?: string) => {
  if (status === 'SUCCESS') {
    return 'success';
  }
  if (status === 'WARNING') {
    return 'warning';
  }
  return 'danger';
};

const checkStatusLabel = (status?: string) => {
  if (status === 'SUCCESS') {
    return $t('mcp.check.status.success');
  }
  if (status === 'WARNING') {
    return $t('mcp.check.status.warning');
  }
  return $t('mcp.check.status.failed');
};

const handleCheck = (row: any) => {
  checkLoadingMap.value[row.id] = true;
  api
    .post('/api/v1/mcp/check', { configJson: row.configJson })
    .then((res) => {
      if (res.errorCode === 0) {
        checkResult.value = res.data;
        checkDialogVisible.value = true;
      }
    })
    .finally(() => {
      checkLoadingMap.value[row.id] = false;
    });
};
</script>

<template>
  <div class="flex h-full flex-col gap-6 p-6">
    <McpModal ref="saveDialog" @reload="reset" />
    <ElDialog
      v-model="checkDialogVisible"
      :title="$t('mcp.check.resultTitle')"
      width="720px"
    >
      <div v-if="checkResult" class="mcp-check-result">
        <ElAlert
          :closable="false"
          :type="
            checkResult.overallStatus === 'SUCCESS'
              ? 'success'
              : checkResult.overallStatus === 'WARNING'
                ? 'warning'
                : 'error'
          "
          :title="`${$t('mcp.check.overall')}: ${checkStatusLabel(
            checkResult.overallStatus,
          )}`"
          show-icon
        />
        <div
          v-for="server in checkResult.servers"
          :key="server.serverName"
          class="mcp-check-server"
        >
          <div class="mcp-check-server__head">
            <div>
              <div class="mcp-check-server__title">
                {{ server.serverName }}
              </div>
              <div class="mcp-check-server__meta">
                {{ server.transport || '-' }} · {{ $t('mcp.check.toolCount') }}
                {{ server.toolCount || 0 }}
              </div>
            </div>
            <ElTag :type="checkTagType(server.status)" size="small">
              {{ checkStatusLabel(server.status) }}
            </ElTag>
          </div>
          <div class="mcp-check-list">
            <div
              v-for="(item, index) in server.checks"
              :key="`${item.name}-${index}`"
              class="mcp-check-item"
            >
              <ElTag :type="checkTagType(item.status)" size="small">
                {{ checkStatusLabel(item.status) }}
              </ElTag>
              <div class="mcp-check-item__content">
                <div class="mcp-check-item__message">
                  {{ item.message }}
                </div>
                <div v-if="item.detail" class="mcp-check-item__detail">
                  {{ item.detail }}
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </ElDialog>
    <ListPageShell>
      <template #filters>
        <HeaderSearch
          :buttons="headerButtons"
          @search="handleSearch"
          @button-click="handleHeaderButtonClick"
        />
      </template>
      <PageData ref="pageDataRef" page-url="/api/v1/mcp/page" :page-size="10">
        <template #default="{ pageList }">
          <ElTable :data="pageList" border>
            <ElTableColumn prop="title" :label="$t('mcp.title')">
              <template #default="{ row }">
                <ElTooltip
                  :content="
                    row.clientOnline
                      ? $t('mcp.labels.clientOnline')
                      : $t('mcp.labels.clientOffline')
                  "
                  placement="top"
                >
                  <span
                    class="mr-2 inline-block h-2 w-2 rounded-full"
                    :class="row.clientOnline ? 'bg-green-500' : 'bg-red-500'"
                  ></span>
                </ElTooltip>
                {{ row.title }}
              </template>
            </ElTableColumn>
            <ElTableColumn prop="description" :label="$t('mcp.description')">
              <template #default="{ row }">
                {{ row.description }}
              </template>
            </ElTableColumn>
            <ElTableColumn prop="created" :label="$t('mcp.created')">
              <template #default="{ row }">
                {{ row.created }}
              </template>
            </ElTableColumn>
            <ElTableColumn prop="status" :label="$t('mcp.status')">
              <template #default="{ row }">
                <ElSwitch
                  v-model="row.status"
                  @change="() => handleUpdate(row, false)"
                  :loading="loadingMap[row.id]"
                  :disabled="loadingMap[row.id]"
                />
              </template>
            </ElTableColumn>
            <ElTableColumn
              :label="$t('common.handle')"
              width="150"
              align="right"
            >
              <template #default="{ row }">
                <div class="flex items-center gap-3">
                  <div v-access:code="'/api/v1/mcp/save'">
                    <ElButton
                      @click="handleUpdate({ ...row, status: true }, true)"
                      type="primary"
                      link
                      :icon="Refresh"
                      :loading="refreshLoadingMap[row.id]"
                    >
                      {{ $t('重启') }}
                    </ElButton>
                  </div>
                  <div v-access:code="'/api/v1/mcp/save'">
                    <ElButton type="primary" link @click="showDialog(row)">
                      {{ $t('button.edit') }}
                    </ElButton>
                  </div>

                  <ElDropdown>
                    <ElButton link :icon="MoreFilled" />
                    <template #dropdown>
                      <ElDropdownMenu>
                        <div v-access:code="'/api/v1/mcp/check'">
                          <ElDropdownItem @click="handleCheck(row)">
                            <ElButton
                              type="primary"
                              link
                              :loading="checkLoadingMap[row.id]"
                            >
                              {{ $t('mcp.check.action') }}
                            </ElButton>
                          </ElDropdownItem>
                        </div>
                        <div v-access:code="'/api/v1/mcp/remove'">
                          <ElDropdownItem @click="remove(row)">
                            <ElButton type="danger" :icon="Delete" link>
                              {{ $t('button.delete') }}
                            </ElButton>
                          </ElDropdownItem>
                        </div>
                      </ElDropdownMenu>
                    </template>
                  </ElDropdown>
                </div>
              </template>
            </ElTableColumn>
          </ElTable>
        </template>
      </PageData>
    </ListPageShell>
  </div>
</template>

<style scoped>
.mcp-check-result {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.mcp-check-server {
  padding: 12px;
  border: 1px solid var(--el-border-color-light);
  border-radius: 8px;
}

.mcp-check-server__head {
  display: flex;
  gap: 16px;
  align-items: flex-start;
  justify-content: space-between;
  margin-bottom: 12px;
}

.mcp-check-server__title {
  font-size: 13px;
  font-weight: 600;
  color: var(--el-text-color-primary);
}

.mcp-check-server__meta,
.mcp-check-item__detail {
  margin-top: 2px;
  font-size: 12px;
  color: var(--el-text-color-secondary);
}

.mcp-check-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.mcp-check-item {
  display: flex;
  gap: 8px;
  align-items: flex-start;
}

.mcp-check-item__content {
  min-width: 0;
}

.mcp-check-item__message {
  font-size: 12px;
  line-height: 20px;
  color: var(--el-text-color-primary);
}
</style>
