<template>
  <div class="app-container">
    <div class="head-container">
      <el-form
        :inline="true"
        label-position="right"
        label-width="=100px"
        label-suffix=":"
      >
        <el-form-item :label="$t('Log.label')">
          <el-select
            v-model="query.label"
            clearable
            size="mini"
            :placeholder="$t('Log.label')"
            style="width: 240px;"
          >
            <el-option
              v-for="item in tagList"
              :label="item"
              :value="item"
            />
          </el-select>
        </el-form-item>
        <el-form-item :label="$t('Log.level')">
          <el-select
            v-model="query.level"
            clearable
            size="mini"
            :placeholder="$t('Log.level')"
          >
            <el-option
              v-for="item in levelOptions"
              :label="item.label"
              :value="item.value"
            />
          </el-select>
        </el-form-item>
        <el-form-item :label="$t('Log.search')">
          <el-input
            v-model="query.message"
            clearable
            size="mini"
            :placeholder="$t('Log.content')"
          />
        </el-form-item>
        <el-form-item :label="$t('Log.link_id')">
          <el-input
            v-model="query.tlogTraceId"
            clearable
            size="mini"
            :placeholder="$t('Log.link_id_msg')"
          />
        </el-form-item>
        <el-form-item :label="$t('Log.time')">
          <el-date-picker
            v-model="query.createTime"
            type="datetimerange"
            :range-separator="$t('Log.to')"
            :start-placeholder="$t('Log.start_time')"
            :end-placeholder="$t('Log.end_time')"
          />
        </el-form-item>
        <el-form-item label="压缩查看" prop="isRequest">
          <el-switch
            v-model="compressedView"
            active-color="#409EFF"
            inactive-color="#F56C6C"
            :active-value="true"
            :inactive-valu="false"
          />
        </el-form-item>
        <el-form-item>
          <el-button type="primary" size="mini" @click="queryData">
            {{ $t('common.Query') }}
          </el-button>
        </el-form-item>
      </el-form>
    </div>
    <!--表格渲染-->
    <el-card shadow="hover" style="width: 100%; height: 620px; overflow-y: auto" class="log-warpper">
      <div style="width: 100%">
        <div v-for="(log, index) in logs" :key="index">
          <div v-if="compressedView" style="margin-bottom: 5px; font-size: 16px;">
            <span style="color: #000000;">{{ timestampToDate(log.time) }}</span> -
            <span style="color: #000569;">{{ log.currIp === null ? '0.0.0.0' : log.currIp }}</span> -
            <span style="color: #111fc7;">{{ log.severity }}</span> -
            <span style="color: #3498db;">{{ log.logger }}</span> -
            <span style="color: #28b23a;">[{{ log.thread }}]</span> -
            <span style="color: #d51313;">{{ log.tlogTraceId === null ? '无链路id' : log.tlogTraceId }}</span> -
            <span
              style="color: #000000;"
              class="sql-message"
              @click="handleCopySQL(log.message)"
            >
              {{ log.message }}
            </span>
          </div>
          <div v-else class="log-detailed">
            <el-row class="log-row">
              <el-col :span="2" class="log-label">
                时间：
              </el-col>
              <el-col :span="22">
                <span class="log-time">{{ timestampToDate(log.time) }}</span>
              </el-col>
            </el-row>
            <el-row class="log-row">
              <el-col :span="2" class="log-label">
                host：
              </el-col>
              <el-col :span="22">
                <span class="log-host">{{ log.host }}</span>
              </el-col>
            </el-row>
            <el-row class="log-row">
              <el-col :span="2" class="log-label">
                执行IP：
              </el-col>
              <el-col :span="22">
                <span class="log-ip">{{ log.currIp === null ? '0.0.0.0' : log.currIp }}</span>
              </el-col>
            </el-row>
            <el-row class="log-row">
              <el-col :span="2" class="log-label">
                API路径：
              </el-col>
              <el-col :span="22">
                <span class="log-api">{{ log.apiPath === null ? '无' : log.apiPath }}</span>
              </el-col>
            </el-row>
            <el-row class="log-row">
              <el-col :span="2" class="log-label">
                MDC标签：
              </el-col>
              <el-col :span="22">
                <span class="log-tag">{{ log.tag === null ? '未配置MDC' : log.tag }}</span>
              </el-col>
            </el-row>
            <el-row class="log-row">
              <el-col :span="2" class="log-label">
                日志级别：
              </el-col>
              <el-col :span="22">
                <span :class="['log-level', getLevelClass(log.severity)]">{{ log.severity }}</span>
              </el-col>
            </el-row>
            <el-row class="log-row">
              <el-col :span="2" class="log-label">
                类名：
              </el-col>
              <el-col :span="22">
                <span class="log-logger">{{ log.logger }}</span>
              </el-col>
            </el-row>
            <el-row class="log-row">
              <el-col :span="2" class="log-label">
                线程名：
              </el-col>
              <el-col :span="22">
                <span class="log-thread">{{ log.thread }}</span>
              </el-col>
            </el-row>
            <el-row class="log-row">
              <el-col :span="2" class="log-label">
                链路标识：
              </el-col>
              <el-col :span="22">
                <span class="log-trace">{{ log.tlogTraceId === null ? '无链路id' : log.tlogTraceId }}</span>
              </el-col>
            </el-row>
            <el-row class="log-row">
              <el-col :span="2" class="log-label">
                日志信息：
              </el-col>
              <el-col :span="22">
                <span class="log-message sql-message" @click="handleCopySQL(log.message)">{{ transSQL(log.message) }}</span>
              </el-col>
            </el-row>
          </div>
        </div>
      </div>
    </el-card>
    <!--  分页  -->
    <el-pagination
      :page-sizes="[100, 500, 1000]"
      :page-size.sync="query.size"
      :total="query.total"
      :current-page.sync="query.page"
      style="margin-top: 8px;"
      layout="total, prev, pager, next, sizes"
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
    />
  </div>
</template>

<script>
import luceneOperation from '@/views/lucene/api/lucene'
export default {
  name: 'LuceneLog',
  data() {
    return {
      permission: {
        add: ['admin', 'param:add'],
        edit: ['admin', 'param:edit'],
        del: ['admin', 'param:del']
      },
      levelOptions: [{
        value: 'DEBUG',
        label: 'DEBUG'
      }, {
        value: 'INFO',
        label: 'INFO'
      }, {
        value: 'ERROR',
        label: 'ERROR'
      }, {
        value: 'WARN',
        label: 'WARN'
      }],
      rules: {},
      logs: [],
      tagList: [],
      query: {
        tlogTraceId: '',
        message: '',
        page: 0,
        size: 100,
        total: 0,
        createTime: ''
      },
      compressedView: true
    }
  },
  created() {
    this.queryData()
    this.getTagList()
  },
  methods: {
    getLevelClass(level) {
      if (!level) return 'level-unknown'
      switch (level.toUpperCase()) {
        case 'ERROR': return 'level-error'
        case 'WARN': return 'level-warn'
        case 'DEBUG': return 'level-debug'
        case 'INFO': return 'level-info'
        default: return 'level-unknown'
      }
    },
    timestampToDate(timestamp) {
      const date = new Date(timestamp)
      const year = date.getFullYear()
      const month = String(date.getMonth() + 1).padStart(2, '0')
      const day = String(date.getDate()).padStart(2, '0')
      const hours = String(date.getHours()).padStart(2, '0')
      const minutes = String(date.getMinutes()).padStart(2, '0')
      const seconds = String(date.getSeconds()).padStart(2, '0')
      // 添加毫秒处理（强制3位数）
      const milliseconds = String(date.getMilliseconds()).padStart(3, '0')

      return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}.${milliseconds}`
    },
    // 处理SQL复制
    handleCopySQL(message) {
      // 1. 使用正则匹配SQL语句
      const sqlMatch = message.match(/\[ SQL: ([^\]]+)\s*\]/)

      if (sqlMatch && sqlMatch[1]) {
        const sql = sqlMatch[1].trim()
        this.copyToClipboard(sql)
      } else {
        this.$message.warning('未检测到可复制的SQL语句')
      }
    },
    transSQL(message) {
      const sqlMatch = message.match(/\[ SQL: ([^\]]+)\s*\]/)

      // 兼容性更好的写法
      if (!sqlMatch || !sqlMatch[1]) {
        return message
      }
      const rawSQL = sqlMatch[1].trim()
      return rawSQL
    },
    // 复制文本到剪贴板
    copyToClipboard(text) {
      // 现代浏览器方法
      if (navigator.clipboard) {
        navigator.clipboard.writeText(text)
          .then(() => this.showSuccess())
          .catch(err => this.showError(err))
      }
      // 兼容旧浏览器
      else {
        const textarea = document.createElement('textarea')
        textarea.value = text
        textarea.style.position = 'fixed'
        document.body.appendChild(textarea)
        textarea.select()

        try {
          const success = document.execCommand('copy')
          success ? this.showSuccess() : this.showError()
        } catch (err) {
          this.showError(err)
        }

        document.body.removeChild(textarea)
      }
    },

    // 显示成功提示
    showSuccess() {
      this.$message({
        message: 'SQL已复制到剪贴板',
        type: 'success',
        duration: 2000
      })
    },

    // 显示错误提示
    showError(err) {
      console.error('复制失败:', err)
      this.$message.error('复制失败，请手动复制')
    },
    handleSizeChange(val) {
      this.query.size = val
      this.queryData()
    },
    handleCurrentChange(val) {
      this.query.page = val
      this.queryData()
    },
    getTagList() {
      luceneOperation.getTagName().then(res => {
        this.tagList = res
      })
    },
    queryData() {
      if (this.query.createTime) {
        this.query.startTime = this.query.createTime[0]
        this.query.endTime = this.query.createTime[1]
      }
      luceneOperation.getLogData(this.query).then(res => {
        console.log(res)
        this.logs = res.content
        this.query.total = res.totalElements
      })
    }
  }
}
</script>

<style scoped>
/* 详细视图样式 */
.log-detailed {
  padding: 10px;
  border: 1px solid #EBEEF5;
  border-radius: 4px;
  background-color: #fafafa;
}

.log-row {
  margin-bottom: 5px;
  line-height: 22px;
}

.log-label {
  font-weight: 600;
  color: #606266;
  text-align: right;
  padding-right: 12px;
}

/* 日志元素样式 */
.log-time {
  color: #303133;
  font-weight: bold;
}

.log-ip {
  color: #000569;
  padding: 2px 4px;
  background-color: #f0f9ff;
  border-radius: 3px;
}

.log-level {
  font-weight: bold;
  padding: 2px 6px;
  border-radius: 3px;
}

.level-error .log-level,
.log-level.level-error {
  background-color: #fef0f0;
  color: #F56C6C;
}

.level-warn .log-level,
.log-level.level-warn {
  background-color: #fdf6ec;
  color: #E6A23C;
}

.level-info .log-level,
.log-level.level-info {
  background-color: #ecf5ff;
  color: #409EFF;
}

.level-debug .log-level,
.log-level.level-debug {
  background-color: #f0f9eb;
  color: #67C23A;
}

.log-logger {
  color: #3498db;
  font-family: monospace;
  max-width: 300px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.log-thread {
  color: #28b23a;
  font-family: monospace;
}

.log-trace {
  color: #d51313;
  font-family: monospace;
  background-color: #fff7f7;
  padding: 2px 4px;
  border-radius: 3px;
}

.log-host {
  color: #048815;
}

.log-api {
  color: #8c6a03;
  font-family: monospace;
}

.log-tag {
  color: #d20118;
}

.log-message {
  color: #000000;
  display: block;
  margin-top: 4px;
  padding: 6px;
  background-color: #f8f8f8;
  border-radius: 3px;
  white-space: pre-wrap;
  word-break: break-all;
  font-family: monospace;
}

/* SQL语句样式 */
.sql-message {
  cursor: pointer;
  transition: all 0.3s;
  position: relative;
  background: #f4faff;
  color: #2d8cf0;
  font-weight: bold;
  border-left: 3px solid #2d8cf0;
  transition: background 0.2s;
}

.sql-message:hover {
  background-color: #ecf5ff;
  box-shadow: 0 0 6px rgba(32, 160, 255, 0.3);
}

.sql-message:hover::after {
  content: "点击复制SQL";
  position: absolute;
  right: 10px;
  top: 3px;
  font-size: 12px;
  color: #409EFF;
  background-color: #ecf5ff;
  padding: 2px 5px;
  border-radius: 3px;
}

.sql-message.copied {
  background: #e1f3d8;
  color: #67c23a;
}

</style>
