<template>
  <el-drawer v-model="visible" title="操作日志详情" size="60%">
    <div class="log-detail" v-if="log">
      <el-descriptions :column="2" border>
        <el-descriptions-item label="日志ID" label-width="150px">
          {{ log.id }}
        </el-descriptions-item>
        <el-descriptions-item label="请求方法" label-width="150px">
          <el-tag :type="getMethodTagType(log.method)" size="small">
            {{ log.method }}
          </el-tag>
        </el-descriptions-item>
        <el-descriptions-item label="用户ID" label-width="150px"> 
          {{ log.user_id }}
        </el-descriptions-item>
        <el-descriptions-item label="用户姓名" label-width="150px">
          {{ log.user_name }}
        </el-descriptions-item>
        <el-descriptions-item label="操作模块" label-width="150px">
          {{ log.module }}
        </el-descriptions-item>
        <el-descriptions-item label="操作动作" label-width="150px">
          {{ log.action }}
        </el-descriptions-item>
        <el-descriptions-item label="操作状态" label-width="150px">
          <el-tag :type="log.status === 1 ? 'success' : 'danger'" size="small">
            {{ log.status === 1 ? "成功" : "失败" }}
          </el-tag>
        </el-descriptions-item>
        <el-descriptions-item label="请求URL" :span="2" label-width="150px">
          <div class="url-text">{{ log.url }}</div>
        </el-descriptions-item>
        <el-descriptions-item label="IP地址" label-width="150px">
          {{ log.ip }}
        </el-descriptions-item>
        <el-descriptions-item label="操作时间" label-width="150px" :span="2">
          {{ log.create_time }}
        </el-descriptions-item>
        <el-descriptions-item label="用户代理" label-width="150px" :span="2">
          <div class="user-agent-text">{{ log.user_agent || "无" }}</div>
        </el-descriptions-item>
        <el-descriptions-item label="请求参数" :span="2" label-width="150px">
          <div class="json-content">
            <div class="json-header">
              <el-icon><Document /></el-icon>
              <span>请求数据</span>
            </div>
            <pre v-if="log.request_data">{{ formatJson(log.request_data) }}</pre>
            <span v-else class="empty-text">无</span>
          </div>
        </el-descriptions-item>
        <el-descriptions-item label="响应数据" :span="4" label-width="150px">
          <div class="json-content">
            <div class="json-header">
              <el-icon><Document /></el-icon>
              <span>响应数据</span>
            </div>
            <pre v-if="log.response_data">{{ formatJson(log.response_data) }}</pre>
            <span v-else class="empty-text">无</span>
          </div>
        </el-descriptions-item>
        <el-descriptions-item v-if="log.error_message" label="错误信息" :span="2">
          <div class="error-message">{{ log.error_message }}</div>
        </el-descriptions-item>
      </el-descriptions>
    </div>
    <div v-else class="loading-container">
      <el-empty description="加载中..." />
    </div>
  </el-drawer>
</template>

<script setup lang="ts">
import { ref, watch } from "vue";
import { Document } from "@element-plus/icons-vue";
import { getOperationLogDetail } from "@/api/operationLog";

interface OperationLog {
  id: number;
  user_id: number;
  user_account: string;
  user_name: string;
  module: string;
  action: string;
  method: string;
  url: string;
  ip: string;
  user_agent: string;
  request_data: string;
  response_data: string;
  status: number;
  error_message: string;
  execution_time: number;
  create_time: string;
}

const props = defineProps({
  modelValue: {
    type: Boolean,
    default: false,
  },
  logId: {
    type: Number,
    default: undefined,
  },
});

const emit = defineEmits(["update:modelValue"]);

const visible = ref(false);
const log = ref<OperationLog | null>(null);
const loading = ref(false);

// 获取请求方法标签类型
const getMethodTagType = (method: string): string => {
  const typeMap: Record<string, string> = {
    GET: "primary",
    POST: "success",
    PUT: "warning",
    DELETE: "danger",
    PATCH: "",
  };
  return typeMap[method] || "";
};

// 格式化 JSON
const formatJson = (jsonString: string): string => {
  try {
    const obj = typeof jsonString === "string" ? JSON.parse(jsonString) : jsonString;
    return JSON.stringify(obj, null, 2);
  } catch (e) {
    return jsonString;
  }
};

// 获取日志详情
const fetchLogDetail = async (logId?: number) => {
  const targetId = logId || props.logId;
  if (!targetId) {
    return;
  }

  loading.value = true;
  log.value = null; // 清空之前的数据
  try {
    const res = await getOperationLogDetail(targetId);
    if (res.code === 200) {
      log.value = res.data;
      // console.log(log.value);
    } else {
      console.error("获取日志详情失败:", res?.msg || "未知错误");
      log.value = null;
    }
  } catch (error: any) {
    console.error("获取日志详情失败", error);
    log.value = null;
  } finally {
    loading.value = false;
  }
};

// 监听 modelValue 变化
watch(
  () => props.modelValue,
  (newVal) => {
    visible.value = newVal;
    if (newVal && props.logId) {
      fetchLogDetail();
    }
  }
);

// 监听 visible 变化
watch(visible, (newVal) => {
  if (!newVal) {
    emit("update:modelValue", false);
    log.value = null;
  }
});

// 暴露方法给父组件
defineExpose({
  open: (logId: number) => {
    if (logId) {
      fetchLogDetail(logId);
    }
  },
});
</script>

<style lang="less" scoped>
.log-detail {
  padding: 20px;
}

.url-text {
  word-break: break-all;
  color: #606266;
}

.user-agent-text {
  word-break: break-all;
  color: #606266;
  font-size: 12px;
}

.json-content {
  width: 950px;
  max-height: 200px;
  min-height: 60px;
  overflow-y: auto;
  overflow-x: auto;
  background: #f5f7fa;
  padding: 10px;
  border-radius: 4px;
  border: 1px solid #e4e7ed;
  resize: vertical;
  transition: all 0.3s ease;

  &:hover {
    border-color: #c0c4cc;
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.1);
  }

  pre {
    margin: 0;
    font-family: "Monaco", "Consolas", monospace;
    font-size: 11px;
    line-height: 1.4;
    color: #303133;
    white-space: pre-wrap;
    word-wrap: break-word;
    max-width: 100%;
    overflow-x: auto;
  }

  .empty-text {
    color: #909399;
    font-style: italic;
  }
}

.error-message {
  color: #f56c6c;
  background: #fef0f0;
  padding: 10px;
  border-radius: 4px;
  word-break: break-all;
}

.json-header {
    display: flex;
    align-items: center;
    margin-bottom: 8px;
    padding-bottom: 6px;
    border-bottom: 1px solid #e4e7ed;
    font-size: 12px;
    color: #606266;
    font-weight: 500;

    .el-icon {
      margin-right: 6px;
      font-size: 14px;
    }
  }

  .loading-container {
    padding: 40px;
    text-align: center;
  }
</style>

