<template>
  <el-dialog v-model="open" title="操作日志详细" width="720px" append-to-body close-on-click-modal class="oper-info-dialog" @closed="info = null">
    <template v-if="info">
      <div class="info-top-card">
        <div class="info-status-badge" :class="info.status === 0 ? 'is-success' : 'is-error'">
          <span class="info-status-dot"></span>
          {{ info.status === 0 ? '正常' : '失败' }}
        </div>
        <span class="info-method-tag">{{ info.requestMethod }} {{ info.operUrl }}</span>
      </div>

      <div class="info-grid">
        <div class="info-grid-cell">
          <span class="info-grid-label">操作人员</span>
          <span class="info-grid-value">{{ info.operName }} / {{ info.deptName }}</span>
        </div>
        <div class="info-grid-cell">
          <span class="info-grid-label">操作地址</span>
          <span class="info-grid-value">{{ info.operIp }} / {{ info.operLocation }}</span>
        </div>
        <div class="info-grid-cell">
          <span class="info-grid-label">操作模块</span>
          <span class="info-grid-value">{{ info.title }} / {{ typeFormat(info) }}</span>
        </div>
        <div class="info-grid-cell">
          <span class="info-grid-label">消耗时间</span>
          <span class="info-grid-value">{{ info.costTime }}ms</span>
        </div>
        <div class="info-grid-cell">
          <span class="info-grid-label">操作时间</span>
          <span class="info-grid-value">{{ proxy.parseTime(info.operTime) }}</span>
        </div>
      </div>

      <div class="info-section">
        <div class="info-section-title">操作方法</div>
        <div class="info-code-block">{{ info.method }}</div>
      </div>

      <div class="info-section">
        <div class="info-section-title">请求参数</div>
        <div class="info-json-block">
          <VueJsonPretty :data="formatToJsonObject(info.operParam)" />
        </div>
      </div>

      <div class="info-section">
        <div class="info-section-title">返回参数</div>
        <div class="info-json-block">
          <VueJsonPretty :data="formatToJsonObject(info.jsonResult)" />
        </div>
      </div>

      <div v-if="info.status === 1" class="info-error-card">
        <div class="info-error-title">
          <el-icon><CircleCloseFilled /></el-icon>
          异常信息
        </div>
        <div class="info-error-msg">{{ info.errorMsg }}</div>
      </div>
    </template>
  </el-dialog>
</template>

<script setup lang="ts">
import type { OperLogForm } from '@/api/monitor/operlog/types';
import VueJsonPretty from 'vue-json-pretty';
import 'vue-json-pretty/lib/styles.css';

const open = ref(false);
const info = ref<OperLogForm | null>(null);
function openDialog(row: OperLogForm) {
  info.value = row;
  open.value = true;
}

function closeDialog() {
  open.value = false;
}

defineExpose({
  openDialog,
  closeDialog
});

function formatToJsonObject(data: string) {
  try {
    return JSON.parse(data);
  } catch (error) {
    return data;
  }
}

const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const { sys_oper_type } = toRefs<any>(proxy?.useDict('sys_oper_type'));
const typeFormat = (row: OperLogForm) => {
  return proxy?.selectDictLabel(sys_oper_type.value, row.businessType);
};
</script>

<style scoped lang="scss">
/* ==================== 弹窗容器 ==================== */
:global(.oper-info-dialog .el-dialog__header) {
  padding: 24px 28px 0;
  margin: 0;
  border-bottom: none;
}

:global(.oper-info-dialog .el-dialog__title) {
  font-size: 18px;
  font-weight: 600;
  color: #1f2937;
  letter-spacing: 0.5px;
}

:global(.oper-info-dialog .el-dialog__body) {
  padding: 20px 28px 28px;
}

/* ==================== 顶部状态条 ==================== */
.info-top-card {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px 20px;
  background: #f9fafb;
  border-radius: 12px;
  margin-bottom: 24px;
  border: 1px solid #f0f2f5;
}

.info-status-badge {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
  font-weight: 600;
  padding: 6px 16px;
  border-radius: 8px;
}

.info-status-badge.is-success {
  color: #059669;
  background: #ecfdf5;
}

.info-status-badge.is-error {
  color: #dc2626;
  background: #fef2f2;
}

.info-status-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  flex-shrink: 0;
}

.is-success .info-status-dot {
  background: #10b981;
}

.is-error .info-status-dot {
  background: #ef4444;
}

.info-method-tag {
  font-size: 13px;
  color: #6b7280;
  background: #fff;
  padding: 5px 12px;
  border-radius: 6px;
  border: 1px solid #e5e7eb;
  font-family: 'SF Mono', 'Monaco', 'Menlo', monospace;
  max-width: 380px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ==================== 信息网格 ==================== */
.info-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 14px;
  margin-bottom: 28px;
}

.info-grid-cell {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 14px 16px;
  background: #f9fafb;
  border-radius: 10px;
  border: 1px solid #f0f2f5;
}

.info-grid-label {
  font-size: 12px;
  font-weight: 500;
  color: #9ca3af;
  text-transform: uppercase;
  letter-spacing: 0.5px;
}

.info-grid-value {
  font-size: 14px;
  font-weight: 600;
  color: #1f2937;
}

/* ==================== 分区 ==================== */
.info-section {
  margin-bottom: 22px;
}

.info-section-title {
  font-size: 14px;
  font-weight: 600;
  color: #1f2937;
  margin-bottom: 10px;
  display: flex;
  align-items: center;
  gap: 8px;

  &::before {
    content: '';
    width: 4px;
    height: 14px;
    background: #3b82f6;
    border-radius: 2px;
  }
}

/* ==================== 代码块 ==================== */
.info-code-block {
  padding: 14px 18px;
  background: #1e293b;
  color: #e2e8f0;
  border-radius: 10px;
  font-size: 13px;
  font-family: 'SF Mono', 'Monaco', 'Menlo', monospace;
  line-height: 1.6;
  word-break: break-all;
  overflow-x: auto;
}

/* ==================== JSON 块 ==================== */
.info-json-block {
  background: #1e293b;
  border-radius: 10px;
  padding: 16px 20px;
  max-height: 260px;
  overflow-y: auto;

  :deep(.vjs-tree) {
    color: #e2e8f0;
    font-size: 13px;
  }

  :deep(.vjs-key) {
    color: #93c5fd;
  }

  :deep(.vjs-value__string) {
    color: #86efac;
  }

  :deep(.vjs-value__number) {
    color: #fde68a;
  }

  :deep(.vjs-value__boolean) {
    color: #c4b5fd;
  }

  :deep(.vjs-value__null) {
    color: #fca5a5;
  }
}

/* ==================== 错误卡片 ==================== */
.info-error-card {
  margin-top: 4px;
  padding: 16px 20px;
  background: #fef2f2;
  border-radius: 12px;
  border: 1px solid #fecaca;
}

.info-error-title {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
  font-weight: 600;
  color: #dc2626;
  margin-bottom: 10px;
}

.info-error-msg {
  font-size: 13px;
  color: #991b1b;
  line-height: 1.6;
  font-family: 'SF Mono', 'Monaco', 'Menlo', monospace;
  padding: 12px 16px;
  background: #fff;
  border-radius: 8px;
  border: 1px solid #fecaca;
  word-break: break-all;
}
</style>
