<script setup lang="ts">
import { reactive, ref, onMounted } from 'vue';
import {
  listCacheName,
  listCacheKey,
  getCacheValue,
  clearCacheName,
  clearCacheKey,
  clearCacheSafe,
} from '@/api/monitor/cache';
import { PageContainer } from 'antdv-pro-layout';
import { ColumnsType } from 'ant-design-vue/lib/table/Table';
import { message } from 'ant-design-vue/lib';
import { hasPermissions } from '@/plugins/auth-user';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import useI18n from '@/hooks/useI18n';
const { t } = useI18n();
/**请求点击 */
let isClick = ref<boolean>(false);

/**缓存内容信息 */
let cacheKeyInfo = reactive({
  loading: true,
  data: {
    cacheKey: '',
    cacheName: '',
    cacheValue: '',
    remark: '',
  },
});

/**
 * 查询缓存内容详细
 * @param cacheKey
 */
function fnCacheKeyInfo(cacheKey: string) {
  if (!hasPermissions(['monitor:cache:query'])) return;
  if (isClick.value) return;
  isClick.value = true;
  cacheKeyInfo.loading = true;
  getCacheValue(cacheKeyTable.cacheName, cacheKey).then(res => {
    isClick.value = false;
    if (res.code === RESULT_CODE_SUCCESS) {
      cacheKeyInfo.data = Object.assign(cacheKeyInfo.data, res.data);
      cacheKeyInfo.loading = false;
    }
  });
}

/**键名列表表格字段列 */
let cacheKeyTableColumns: ColumnsType = [
  {
    title: t('common.rowId'),
    dataIndex: 'num',
    width: '50px',
    align: 'center',
    customRender(opt) {
      return opt.index + 1;
    },
  },
  {
    title: t('views.monitor.cache.cacheKey'),
    dataIndex: 'cacheKey',
    align: 'left',
    ellipsis: true,
    // 渲染值处理
    customRender(opt) {
      return opt.text;
    },
    // 自定义过滤控件
    customFilterDropdown: true,
    onFilter: (value, record) => {
      if (typeof value === 'string') {
        const nameLower = record.cacheKey.toLowerCase();
        return nameLower.includes(value.toLowerCase());
      }
    },
  },
  {
    title: t('common.operate'),
    key: 'option',
    align: 'center',
    width: '50px',
  },
];

/**键名列表表格数据 */
let cacheKeyTable = reactive({
  loading: false,
  data: [],
  /**当前键名列表的缓存名称 */
  cacheName: '',
});

/**
 * 清理指定缓存键名
 * @param cacheKey 键名列表中的缓存键名
 */
function fnCacheKeyClear(cacheKey: string) {
  if (isClick.value) return;
  isClick.value = true;
  const hide = message.loading(t('common.loading'), 0);
  clearCacheKey(cacheKeyTable.cacheName, cacheKey).then(res => {
    hide();
    isClick.value = false;
    if (res.code === RESULT_CODE_SUCCESS) {
      message.success({
        content: t('views.monitor.cache.clearCacheKeyOk', { txt: cacheKey }),
        duration: 3,
      });
      // 缓存内容显示且是删除的缓存键名，需要进行加载显示
      if (!cacheKeyInfo.loading && cacheKeyInfo.data.cacheKey === cacheKey) {
        cacheKeyInfo.loading = true;
      }
    } else {
      message.error({
        content: res.msg,
        duration: 3,
      });
    }
    fnCacheKeyList();
  });
}

/** 查询缓存键名列表 */
function fnCacheKeyList(cacheName: string = 'load') {
  if (cacheName === 'load') {
    cacheName = cacheKeyTable.cacheName;
  }
  if (!cacheName) {
    message.warning(t('views.monitor.cache.cacheKeyListErr'), 3);
    return;
  }
  if (isClick.value) return;
  isClick.value = true;
  cacheKeyTable.loading = true;
  listCacheKey(cacheName).then(res => {
    isClick.value = false;
    if (res.code === RESULT_CODE_SUCCESS && res.data) {
      cacheKeyTable.cacheName = cacheName;
      cacheKeyTable.data = res.data;
      cacheKeyTable.loading = false;
    }
  });
}

/**缓存列表表格数据 */
let cacheNameTable = reactive({
  loading: true,
  data: [],
});

/**缓存列表表格字段列 */
let cacheNameTableColumns: ColumnsType = [
  {
    title: t('common.rowId'),
    dataIndex: 'num',
    width: '50px',
    align: 'center',
    customRender(opt) {
      return opt.index + 1;
    },
  },
  {
    title: t('views.monitor.cache.cacheName'),
    dataIndex: 'cacheName',
    align: 'left',
    ellipsis: true,
    // 渲染值处理
    customRender(opt) {
      return opt.text;
    },
    // 自定义过滤控件
    customFilterDropdown: true,
    onFilter: (value, record) => {
      if (typeof value === 'string') {
        const nameLower = record.cacheName.toLowerCase();
        return nameLower.includes(value.toLowerCase());
      }
    },
  },
  {
    title: t('views.monitor.cache.remark'),
    dataIndex: 'remark',
    align: 'left',
    ellipsis: true,
  },
  {
    title: t('common.operate'),
    key: 'option',
    align: 'center',
    width: '50px',
  },
];

/**安全清理缓存 */
function fnClearCacheSafe() {
  if (isClick.value) return;
  isClick.value = true;
  const hide = message.loading(t('common.loading'), 0);
  clearCacheSafe().then(res => {
    hide();
    isClick.value = false;
    if (res.code === RESULT_CODE_SUCCESS) {
      message.success({
        content: t('views.monitor.cache.clearCacheSafeOk'),
        duration: 3,
      });
      cacheKeyTable.loading = true;
      cacheKeyInfo.loading = true;
    } else {
      message.error({
        content: res.msg,
        duration: 3,
      });
    }
  });
}

/**
 * 清理指定缓存名称
 * @param cacheName 缓存名称
 */
function fnCacheNameClear(cacheName: string) {
  if (isClick.value) return;
  isClick.value = true;
  const hide = message.loading(t('common.loading'), 0);
  clearCacheName(cacheName).then(res => {
    hide();
    isClick.value = false;
    if (res.code === RESULT_CODE_SUCCESS) {
      message.success({
        content: t('views.monitor.cache.clearCacheNameOk', { txt: cacheName }),
        duration: 3,
      });
      // 缓存内容显示且是删除的缓存名称，需要进行加载显示
      if (!cacheKeyInfo.loading && cacheKeyInfo.data.cacheName === cacheName) {
        cacheKeyInfo.loading = true;
      }
    } else {
      message.error({
        content: res.msg,
        duration: 3,
      });
    }
    fnCacheKeyList(cacheName);
  });
}

/**查询缓存名称列表 */
function fnCacheNameList() {
  if (isClick.value) return;
  isClick.value = true;
  cacheNameTable.loading = true;
  listCacheName().then(res => {
    isClick.value = false;
    if (res.code === RESULT_CODE_SUCCESS && res.data) {
      cacheNameTable.data = res.data;
      cacheNameTable.loading = false;
    }
  });
}

onMounted(() => {
  fnCacheNameList();
});
</script>

<template>
  <PageContainer>
    <a-row :gutter="20">
      <a-col :lg="8" :md="8" :xs="24">
        <a-card
          :title="t('views.monitor.cache.cacheList')"
          :bordered="false"
          :body-style="{ marginBottom: '24px', padding: 0 }"
        >
          <template #extra>
            <a-space :size="8" align="center">
              <a-tooltip>
                <template #title>
                  {{ t('common.reloadText') }}
                </template>
                <a-button type="text" @click.prevent="fnCacheNameList">
                  <template #icon><ReloadOutlined /></template>
                </a-button>
              </a-tooltip>
              <a-tooltip>
                <template #title>
                  {{ t('views.monitor.cache.clearCacheSafe') }}
                </template>
                <a-popconfirm
                  placement="bottomRight"
                  :title="t('views.monitor.cache.clearCacheSafeTip')"
                  :ok-text="t('common.ok')"
                  :cancel-text="t('common.cancel')"
                  @confirm="fnClearCacheSafe()"
                >
                  <a-button type="text" v-perms:has="['monitor:cache:remove']">
                    <template #icon><ClearOutlined /></template>
                  </a-button>
                </a-popconfirm>
              </a-tooltip>
            </a-space>
          </template>
          <a-table
            row-key="cacheName"
            size="small"
            :columns="cacheNameTableColumns"
            :data-source="cacheNameTable.data"
            :loading="cacheNameTable.loading"
            :scroll="{ y: 'calc(100vh - 350px)' }"
            :pagination="false"
            :row-selection="{
              type: 'radio',
              onChange: (selectedRowKeys: (string|number)[]) => fnCacheKeyList(selectedRowKeys[0] as string),
            }"
          >
            <template
              #customFilterDropdown="{
                setSelectedKeys,
                selectedKeys,
                confirm,
                clearFilters,
                column,
              }"
            >
              <div style="padding: 8px">
                <a-input
                  :placeholder="
                    t('views.monitor.cache.filterPlace', { txt: column.title })
                  "
                  :value="selectedKeys[0]"
                  style="width: 188px; margin-bottom: 8px; display: block"
                  @change="
                    (e:any)=> setSelectedKeys(e.target.value ? [e.target.value] : [])
                  "
                  @pressEnter="confirm()"
                />
                <a-button
                  type="primary"
                  size="small"
                  style="width: 90px; margin-right: 8px"
                  @click="confirm()"
                >
                  {{ t('views.monitor.cache.filter') }}
                </a-button>
                <a-button
                  size="small"
                  style="width: 90px"
                  @click="clearFilters({ confirm: true })"
                >
                  {{ t('common.reset') }}
                </a-button>
              </div>
            </template>
            <template #bodyCell="{ column, record }">
              <template v-if="column.key === 'option'">
                <a-popconfirm
                  placement="topRight"
                  :title="t('views.monitor.cache.clearCacheNameTip')"
                  ,
                  :ok-text="t('common.ok')"
                  :cancel-text="t('common.cancel')"
                  @confirm="fnCacheNameClear(record.cacheName)"
                >
                  <a-button type="text" v-perms:has="['monitor:cache:remove']">
                    <template #icon><ClearOutlined /></template>
                  </a-button>
                </a-popconfirm>
              </template>
            </template>
          </a-table>
        </a-card>
      </a-col>

      <a-col :lg="8" :md="8" :xs="24">
        <a-card
          :title="t('views.monitor.cache.keyNameList')"
          :bordered="false"
          :body-style="{ marginBottom: '24px', padding: 0 }"
        >
          <template #extra>
            <a-tooltip>
              <template #title>
                {{ t('common.reloadText') }}
              </template>
              <a-button type="text" @click.prevent="fnCacheKeyList()">
                <template #icon><ReloadOutlined /></template>
              </a-button>
            </a-tooltip>
          </template>
          <a-table
            row-key="cacheKey"
            size="small"
            :columns="cacheKeyTableColumns"
            :data-source="cacheKeyTable.data"
            :loading="cacheKeyTable.loading"
            :scroll="{ y: 'calc(100vh - 350px)' }"
            :pagination="false"
            :row-selection="{
              type: 'radio',
              onChange: (selectedRowKeys: (string|number)[]) => fnCacheKeyInfo(selectedRowKeys[0] as string),
            }"
          >
            <template
              #customFilterDropdown="{
                setSelectedKeys,
                selectedKeys,
                confirm,
                clearFilters,
                column,
              }"
            >
              <div style="padding: 8px">
                <a-input
                  :placeholder="
                    t('views.monitor.cache.filterPlace', { txt: column.title })
                  "
                  :value="selectedKeys[0]"
                  style="width: 188px; margin-bottom: 8px; display: block"
                  @change="
                    (e:any) => setSelectedKeys(e.target.value ? [e.target.value] : [])
                  "
                  @pressEnter="confirm()"
                />
                <a-button
                  type="primary"
                  size="small"
                  style="width: 90px; margin-right: 8px"
                  @click="confirm()"
                >
                  {{ t('views.monitor.cache.filter') }}
                </a-button>
                <a-button
                  size="small"
                  style="width: 90px"
                  @click="clearFilters({ confirm: true })"
                >
                  {{ t('common.reset') }}
                </a-button>
              </div>
            </template>
            <template #bodyCell="{ column, record }">
              <template v-if="column.key === 'option'">
                <a-popconfirm
                  placement="topRight"
                  :title="t('views.monitor.cache.clearCacheKeyTip')"
                  ,
                  :ok-text="t('common.ok')"
                  :cancel-text="t('common.cancel')"
                  @confirm="fnCacheKeyClear(record.cacheKey)"
                >
                  <a-button type="text" v-perms:has="['monitor:cache:remove']">
                    <template #icon><DeleteOutlined /></template>
                  </a-button>
                </a-popconfirm>
              </template>
            </template>
          </a-table>
        </a-card>
      </a-col>

      <a-col :lg="8" :md="8" :xs="24" v-perms:has="['monitor:cache:query']">
        <a-card
          :title="t('views.monitor.cache.keyContent')"
          :bordered="false"
          :body-style="{ marginBottom: '24px', padding: 0 }"
          :loading="cacheKeyInfo.loading"
        >
          <a-descriptions
            size="small"
            layout="vertical"
            :bordered="true"
            :column="1"
          >
            <a-descriptions-item :label="t('views.monitor.cache.cacheName')">
              {{ cacheKeyInfo.data.cacheName }}
            </a-descriptions-item>
            <a-descriptions-item :label="t('views.monitor.cache.cacheKey')">
              {{ cacheKeyInfo.data.cacheKey }}
            </a-descriptions-item>
            <a-descriptions-item :label="t('views.monitor.cache.cacheValue')">
              <a-typography-paragraph>
                <a-textarea
                  :value="cacheKeyInfo.data.cacheValue"
                  :auto-size="{ minRows: 4, maxRows: 20 }"
                  :maxlength="4000"
                  :disabled="true"
                />
              </a-typography-paragraph>
            </a-descriptions-item>
          </a-descriptions>
        </a-card>
      </a-col>
    </a-row>
  </PageContainer>
</template>

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