<script setup lang="ts">
import { reactive, onMounted, ref, nextTick } from "vue";
import { http } from "@/utils/http";
import { useRenderIcon } from "@/components/ReIcon/src/hooks";
import { ElMessage, ElMessageBox } from "element-plus";
import ErrorLog from "./error.vue";

defineOptions({ name: "AdminLog" });

const activeTab = ref("operation");
const queryRef = ref();
const detailVisible = ref(false);
const currentLog = ref<any>(null);

const state = reactive({
  formQuery: {
    username: "",
    startDate: "",
    endDate: ""
  },
  dateRange: [] as string[],
  pageQuery: {
    pageNum: 1,
    pageSize: 10,
    total: 0
  },
  tableData: {
    height: 500,
    data: [] as Array<any>,
    loading: false,
    columns: [
      { label: "ID", prop: "id", width: 80 },
      { label: "操作用户", prop: "username", width: 120 },
      { label: "操作名称", prop: "operation", width: 200 },
      { label: "请求方法", prop: "method", width: 150 },
      { label: "IP地址", prop: "ip", width: 130 },
      { label: "耗时(ms)", prop: "executeTime", width: 100 },
      { label: "操作时间", prop: "createTime", width: 170 }
    ]
  }
});

onMounted(() => {
  loadData();
  nextTick(() => {
    const bodyHeight = document.body.clientHeight;
    const queryHeight = queryRef.value?.$el?.clientHeight || 0;
    state.tableData.height = bodyHeight - queryHeight - 260;
  });
});

const loadData = (refresh: boolean = false) => {
  if (refresh) {
    state.pageQuery.pageNum = 1;
  }

  if (state.dateRange && state.dateRange.length === 2) {
    state.formQuery.startDate = state.dateRange[0];
    state.formQuery.endDate = state.dateRange[1];
  } else {
    state.formQuery.startDate = "";
    state.formQuery.endDate = "";
  }

  state.tableData.loading = true;
  http.request<any>("get", "/system-log/list", { params: { ...state.formQuery, ...state.pageQuery } })
    .then((res: any) => {
      const { list, total } = res || {};
      state.tableData.data = list || [];
      state.pageQuery.total = total || 0;
    })
    .catch(() => {
      state.tableData.data = [];
    })
    .finally(() => {
      state.tableData.loading = false;
    });
};

const handleSizeChange = (size: number) => {
  state.pageQuery.pageSize = size;
  loadData(true);
};

const handleCurrentChange = (page: number) => {
  state.pageQuery.pageNum = page;
  loadData();
};

const handleSearch = () => {
  loadData(true);
};

const handleReset = () => {
  state.formQuery = {
    username: "",
    startDate: "",
    endDate: ""
  };
  state.dateRange = [];
  loadData(true);
};

const handleDetail = (row: any) => {
  currentLog.value = row;
  detailVisible.value = true;
};

const handleClearLog = async () => {
  await ElMessageBox.confirm("确定要清空所有操作日志吗？此操作不可恢复！", "警告", { type: "warning" });
  try {
    await http.request("post", "/system-log/clear");
    ElMessage.success("清空成功");
    loadData(true);
  } catch (error) {
    ElMessage.error("清空失败");
  }
};

const getExecuteTimeType = (time: number) => {
  if (time > 1000) return "danger";
  if (time > 500) return "warning";
  return "success";
};
</script>

<template>
  <div class="page-container">
    <el-tabs v-model="activeTab" type="border-card">
      <el-tab-pane label="操作日志" name="operation">
        <el-form ref="queryRef" :model="state.formQuery" inline class="search-form">
        <el-form-item label="操作用户">
          <el-input
            v-model="state.formQuery.username"
            placeholder="请输入操作用户"
            clearable
            style="width: 150px"
            @keyup.enter="handleSearch"
          />
        </el-form-item>
        <el-form-item label="操作时间">
          <el-date-picker
            v-model="state.dateRange"
            type="daterange"
            range-separator="至"
            start-placeholder="开始日期"
            end-placeholder="结束日期"
            value-format="YYYY-MM-DD"
            style="width: 240px"
            @change="handleSearch"
          />
        </el-form-item>
        <el-form-item>
          <el-button
            type="primary"
            :icon="useRenderIcon('ri/search-line')"
            @click="handleSearch"
          >
            查询
          </el-button>
          <el-button
            :icon="useRenderIcon('ri/refresh-line')"
            @click="handleReset"
          >
            重置
          </el-button>
          <el-button
            type="danger"
            :icon="useRenderIcon('ri/delete-bin-line')"
            @click="handleClearLog"
            :disabled="state.tableData.data.length === 0"
          >
            清空日志
          </el-button>
        </el-form-item>
      </el-form>

      <el-table
        v-loading="state.tableData.loading"
        :data="state.tableData.data"
        :height="state.tableData.height"
        border
        stripe
      >
        <template #empty>
          <el-empty description="暂无数据" />
        </template>
        <el-table-column
          v-for="col in state.tableData.columns"
          :key="col.prop"
          :prop="col.prop"
          :label="col.label"
          :width="col.width"
          show-overflow-tooltip
        >
          <template #default="{ row }">
            <template v-if="col.prop === 'executeTime'">
              <el-tag :type="getExecuteTimeType(row.executeTime)" size="small">
                {{ row.executeTime }}
              </el-tag>
            </template>
            <template v-else>
              {{ row[col.prop] }}
            </template>
          </template>
        </el-table-column>
        <el-table-column label="操作" width="80" fixed="right">
          <template #default="{ row }">
            <el-button type="primary" link size="small" @click="handleDetail(row)">
              详情
            </el-button>
          </template>
        </el-table-column>
      </el-table>

      <div class="pagination-container">
        <el-pagination
          v-model:current-page="state.pageQuery.pageNum"
          v-model:page-size="state.pageQuery.pageSize"
          :total="state.pageQuery.total"
          :page-sizes="[10, 20, 50, 100]"
          layout="total, sizes, prev, pager, next, jumper"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
        />
      </div>

    <!-- 详情对话框 -->
    <el-dialog v-model="detailVisible" title="日志详情" width="600px">
      <el-descriptions v-if="currentLog" :column="2" border>
        <el-descriptions-item label="操作用户">{{ currentLog.username }}</el-descriptions-item>
        <el-descriptions-item label="IP地址">{{ currentLog.ip }}</el-descriptions-item>
        <el-descriptions-item label="操作名称" :span="2">{{ currentLog.operation }}</el-descriptions-item>
        <el-descriptions-item label="请求方法" :span="2">{{ currentLog.method }}</el-descriptions-item>
        <el-descriptions-item label="耗时">{{ currentLog.executeTime }}ms</el-descriptions-item>
        <el-descriptions-item label="操作时间">{{ currentLog.createTime }}</el-descriptions-item>
      </el-descriptions>
      <div v-if="currentLog && currentLog.requestParam" class="detail-section">
        <div class="section-title">请求参数</div>
        <el-input
          type="textarea"
          :rows="6"
          :model-value="currentLog.requestParam"
          readonly
        />
      </div>
      <template #footer>
        <el-button @click="detailVisible = false">关闭</el-button>
      </template>
    </el-dialog>
      </el-tab-pane>
      <el-tab-pane label="错误日志" name="error">
        <ErrorLog />
      </el-tab-pane>
    </el-tabs>
  </div>
</template>

<style scoped lang="scss">
.page-container {
  padding: 15px;
}

.search-form {
  margin-bottom: 15px;
}

.pagination-container {
  display: flex;
  justify-content: flex-end;
  margin-top: 15px;
}

.detail-section {
  margin-top: 15px;

  .section-title {
    font-weight: 500;
    margin-bottom: 10px;
    color: var(--el-text-color-primary);
  }

  :deep(.el-textarea__inner) {
    font-family: monospace;
    font-size: 13px;
    background: var(--el-fill-color-lighter);
  }
}
</style>
