<script setup lang="ts">
import { ref, computed, onMounted } from 'vue';
import { getApprovalList, getUserApprovalStats, syncCurrentUserApprovals, getTemplateList, getApprovalDetail, type WecomApprovalVo, type ApprovalStats, type WecomTemplate, type WecomApprovalDetail } from '@/api/wecom';
import { ElMessage } from 'element-plus';

// Tab
const activeTab = ref('all');

const tabs = [
  { key: 'pending', label: '待我审批', statusFilter: '1' as string },
  { key: 'my', label: '我发起的', statusFilter: '' as string },
  { key: 'done', label: '已审批', statusFilter: '2' as string },
  { key: 'all', label: '全部', statusFilter: '' as string },
];

// Filters
const filters = ref({ type: '', status: '' as string | number, keyword: '' });
const search = computed({
  get: () => filters.value.keyword,
  set: (v: string) => { filters.value.keyword = v; },
});

// Stats
const approvalStats = ref<ApprovalStats>({ pending: 0, approved: 0, rejected: 0, revoked: 0, total: 0 });

const statCards = computed(() => [
  { label: '我发起的', value: approvalStats.value.mine || approvalStats.value.total || 0, color: '#1d5af3' },
  { label: '审批中', value: approvalStats.value.pending || 0, color: '#f59e0b' },
  { label: '已通过', value: approvalStats.value.approved || 0, color: '#22c55e' },
  { label: '已驳回', value: approvalStats.value.rejected || 0, color: '#ef4444' },
]);

// Table data
const approvals = ref<WecomApprovalVo[]>([]);
const templates = ref<WecomTemplate[]>([]);
const loading = ref(false);
const currentPage = ref(1);
const pageSize = ref(10);
const total = ref(0);

// 状态选项（使用数字值）
const statusOptions = [
  { value: 1, label: '审批中' },
  { value: 2, label: '已通过' },
  { value: 3, label: '已驳回' },
  { value: 4, label: '已撤销' },
];

const statusTagMap: Record<string, any> = {
  1: 'warning', 2: 'success', 3: 'danger', 4: 'info',
};

const statusTextMap: Record<number, string> = {
  1: '审批中', 2: '已通过', 3: '已驳回', 4: '已撤销', 6: '通过后撤销',
};

async function loadStats() {
  try {
    const res = await getUserApprovalStats();
    console.log('统计数据API响应:', res);
    // res 是 { code: 200, data: {...} } 格式，需要提取 data
    approvalStats.value = (res?.data || res) as ApprovalStats;
    console.log('统计数据:', approvalStats.value);
  } catch (e) {
    console.error('加载统计数据失败:', e);
  }
}

async function loadTemplates() {
  try {
    const res = await getTemplateList();
    console.log('模板API响应:', res);
    // res 是 { code: 200, data: [...] } 格式，需要提取 data
    const templateList = Array.isArray(res) ? res : (res?.data || []);
    // 过滤掉模板名称为空的模板
    templates.value = templateList.filter(t => t.templateName && t.templateName.trim());
    console.log('过滤后的模板:', templates.value);
  } catch (e) {
    console.error('加载模板失败:', e);
  }
}

async function loadData() {
  loading.value = true;
  try {
    const statusFilter = tabs.find(t => t.key === activeTab.value)?.statusFilter;
    const res = await getApprovalList({
      pageNum: currentPage.value,
      pageSize: pageSize.value,
      type: filters.value.type || undefined,
      status: statusFilter || (filters.value.status ? String(filters.value.status) : undefined),
      keyword: filters.value.keyword || undefined,
    });
    console.log('审批列表API响应:', res);
    // res 是 { code: 200, data: { rows: [...], total: ... } } 格式
    const data = res?.data || res;
    approvals.value = data?.rows || [];
    total.value = data?.total || 0;
    console.log('审批列表:', approvals.value.length, '条');
  } catch (error: any) {
    console.error('加载审批列表失败:', error);
    ElMessage.error(error?.message || '加载审批列表失败');
  } finally {
    loading.value = false;
  }
}

async function handleSync() {
  try {
    loading.value = true;
    const result = await syncCurrentUserApprovals();
    if (result instanceof Error) return;
    // result 是 { code: 200, data: "同步完成..." } 格式
    const message = (result?.data || result) as string;
    ElMessage.success(message || '同步完成');
    await loadData();
    await loadStats();
  } catch {
    // 拦截器已显示错误
  } finally {
    loading.value = false;
  }
}

// 详情弹窗
const detailVisible = ref(false);
const detailLoading = ref(false);
const currentDetail = ref<WecomApprovalDetail | null>(null);

async function handleView(row: WecomApprovalVo) {
  detailVisible.value = true;
  detailLoading.value = true;
  currentDetail.value = null;

  try {
    const res = await getApprovalDetail(row.spNo);
    console.log('审批详情API响应:', res);

    // 后端返回格式: { code: 200, msg: "JSON字符串", data: null }
    // 需要从 msg 字段中解析 JSON
    let detailData: any;

    if (res?.msg && typeof res.msg === 'string') {
      // 第一次解析：从 msg 字段获取审批单基本信息
      detailData = JSON.parse(res.msg);
      console.log('第一层解析结果:', detailData);

      // 第二次解析：applyData 字段也是 JSON 字符串
      if (detailData?.applyData && typeof detailData.applyData === 'string') {
        detailData.apply_data = JSON.parse(detailData.applyData);
        console.log('apply_data 解析结果:', detailData.apply_data);
      }

      // 转换字段名格式（后端使用驼峰，前端期望蛇形）
      currentDetail.value = {
        sp_no: detailData.spNo,
        sp_name: detailData.spName,
        sp_status: detailData.spStatus,
        template_id: detailData.templateId,
        apply_time: detailData.applyTime,
        applyer: {
          userid: detailData.applyerUserid,
          party: detailData.applyerParty || '',
        },
        apply_data: detailData.apply_data,
        nodes: [], // nodesData 也需要解析
        comments: [], // 暂无评论数据
      };

      // 解析 nodesData（实际保存的是 process_list）
      if (detailData?.nodesData && typeof detailData.nodesData === 'string') {
        try {
          const processList = JSON.parse(detailData.nodesData);
          console.log('process_list 解析结果:', processList);

          // 转换 process_list.node_list 为前端期望的 nodes 格式
          if (processList?.node_list && Array.isArray(processList.node_list)) {
            currentDetail.value.nodes = processList.node_list.map(node => ({
              sp_status: node.sp_status,
              apv_rel: node.apv_rel,
              sub_node: node.sub_node_list?.map(sub => ({
                sp_status: sub.sp_yj,
                approver: { userid: sub.userid },
                speech: sub.speech || '',
                sp_time: sub.sptime,
              })) || [],
            }));
            console.log('nodes 解析结果:', currentDetail.value.nodes);
          }
        } catch (e) {
          console.warn('nodesData 解析失败:', e);
        }
      }

      console.log('最终审批详情:', currentDetail.value);
    } else {
      console.warn('审批详情数据格式异常:', res);
    }
  } catch (e) {
    console.error('获取审批详情失败:', e);
    ElMessage.error('获取审批详情失败');
    detailVisible.value = false;
  } finally {
    detailLoading.value = false;
  }
}

function getStatusText(status: number): string {
  const statusMap: Record<number, string> = {
    1: '审批中', 2: '已通过', 3: '已驳回', 4: '已撤销', 6: '通过后撤销',
  };
  return statusMap[status] || '未知状态';
}

function getControlTypeText(control: string): string {
  const controlMap: Record<string, string> = {
    'Text': '文本',
    'Textarea': '多行文本',
    'Number': '数字',
    'Money': '金额',
    'Date': '日期',
    'Selector': '选择器',
    'Contact': '联系人',
    'Location': '位置',
    'RelatedApproval': '关联审批',
    'File': '文件',
    'Table': '表格',
    'Attendance': '打卡',
    'Vacation': '假期',
    'Trip': '出差',
    'Overtime': '加班',
    'Work': '工作',
    'Switch': '开关',
  };
  return controlMap[control] || control;
}

// Format timestamp to readable date
function formatTime(ts: number): string {
  if (!ts) return '--';
  const d = new Date(ts * 1000);
  return d.toLocaleString('zh-CN', { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit' });
}

function formatAmount(n: number | null): string {
  if (!n) return '—';
  return `¥${n.toLocaleString('zh-CN', { minimumFractionDigits: 0, maximumFractionDigits: 2 })}`;
}

/**
 * 根据企业微信审批控件规范提取value内容
 * 参考：https://developer.work.weixin.qq.com/document/path/91983
 */
function extractValueByControl(control: string, value: any): string {
  if (!value || typeof value !== 'object') {
    return '--';
  }

  // 企业微信通用的空数组字段（需要过滤）
  const emptyFields = ['docs', 'tips', 'files', 'classes', 'members', 'children',
                       'students', 'sum_field', 'stat_field', 'departments', 'wedrive_files',
                       'related_approval'];

  // 根据控件类型提取对应的value字段
  switch (control) {
    case 'Text':
    case 'Textarea':
      // 文本控件：value.text
      return value.text || '--';

    case 'Number':
      // 数字控件：value.number
      return value.number ? String(value.number) : '--';

    case 'Money':
      // 金额控件：value.money（已单独处理）
      return value.money ? String(value.money) : '--';

    case 'Date':
      // 日期控件：value.date（时间戳）或 value.date_range
      if (value.date) {
        return formatTime(value.date);
      } else if (value.date_range?.begin && value.date_range?.end) {
        return `${formatTime(value.date_range.begin)} 至 ${formatTime(value.date_range.end)}`;
      }
      return '--';

    case 'Selector':
      // 选择器控件：value.selector.title（单选）或 value.selector.options（多选）
      if (value.selector?.title) {
        return value.selector.title;
      } else if (value.selector?.options && Array.isArray(value.selector.options)) {
        return value.selector.options.map(opt => opt.title || opt.key).join(', ');
      }
      return '--';

    case 'Contact':
      // 联系人控件：value.contacts（数组）
      if (value.contacts && Array.isArray(value.contacts) && value.contacts.length > 0) {
        return value.contacts.map(c => c.name || c.userid).join(', ');
      }
      return '--';

    case 'Location':
      // 位置控件：value.location.title
      return value.location?.title || '--';

    case 'File':
      // 文件控件：value.files（数组）
      if (value.files && Array.isArray(value.files) && value.files.length > 0) {
        return value.files.map(f => f.name || f.file_id).join(', ');
      }
      return '无附件';

    case 'Table':
      // 表格控件：value.children（多行数据）
      if (value.children && Array.isArray(value.children) && value.children.length > 0) {
        const rows = value.children.map(row => {
          // 每行可能包含多个单元格，提取有意义的数据
          return Object.entries(row)
            .filter(([k, v]) => !emptyFields.includes(k) && v !== null && v !== undefined)
            .map(([k, v]) => typeof v === 'object' ? extractValueByControl('', v) : String(v))
            .join(' | ');
        });
        return rows.join('\n');
      }
      return '--';

    case 'PunchCorrection':
      // 补卡控件：value.punch_correction
      if (value.punch_correction) {
        const parts = [];
        if (value.punch_correction.state) {
          parts.push(`状态: ${value.punch_correction.state}`);
        }
        if (value.punch_correction.time) {
          parts.push(`时间: ${formatTime(value.punch_correction.time)}`);
        }
        if (value.punch_correction.daymonthyear) {
          parts.push(`日期: ${formatTime(value.punch_correction.daymonthyear)}`);
        }
        return parts.length > 0 ? parts.join('\n') : '--';
      }
      return '--';

    case 'Attendance':
      // 打卡控件：value.attendance
      if (value.attendance) {
        return value.attendance.title || value.attendance.type || '--';
      }
      return '--';

    case 'Vacation':
      // 假期控件：value.vacation
      if (value.vacation) {
        const parts = [];
        if (value.vacation.type) parts.push(`类型: ${value.vacation.type}`);
        if (value.vacation.begin) parts.push(`开始: ${formatTime(value.vacation.begin)}`);
        if (value.vacation.end) parts.push(`结束: ${value.vacation.end}`);
        return parts.length > 0 ? parts.join('\n') : '--';
      }
      return '--';

    case 'Trip':
      // 出差控件：value.trip
      if (value.trip) {
        const parts = [];
        if (value.trip.destination) parts.push(`目的地: ${value.trip.destination}`);
        if (value.trip.begin) parts.push(`开始: ${formatTime(value.trip.begin)}`);
        if (value.trip.end) parts.push(`结束: ${formatTime(value.trip.end)}`);
        if (value.trip.duration) parts.push(`时长: ${value.trip.duration}`);
        return parts.length > 0 ? parts.join('\n') : '--';
      }
      return '--';

    case 'Overtime':
      // 加班控件：value.overtime
      if (value.overtime) {
        const parts = [];
        if (value.overtime.begin) parts.push(`开始: ${formatTime(value.overtime.begin)}`);
        if (value.overtime.end) parts.push(`结束: ${formatTime(value.overtime.end)}`);
        if (value.overtime.duration) parts.push(`时长: ${value.overtime.duration}`);
        return parts.length > 0 ? parts.join('\n') : '--';
      }
      return '--';

    case 'Work':
      // 工作控件：value.work
      if (value.work) {
        return value.work.title || value.work.type || '--';
      }
      return '--';

    case 'Switch':
      // 开关控件：value.switch
      return value.switch ? '是' : '否';

    default:
      // 未知控件类型：通用提取逻辑
      return extractValueGeneric(value, emptyFields);
  }
}

/**
 * 通用数据提取方法（用于未知控件类型）
 */
function extractValueGeneric(value: any, emptyFields: string[]): string {
  const meaningfulData: string[] = [];

  for (const [key, val] of Object.entries(value)) {
    if (emptyFields.includes(key)) continue;
    if (!val || (Array.isArray(val) && val.length === 0)) continue;

    if (typeof val === 'string' && val.trim()) {
      meaningfulData.push(val.trim());
    } else if (typeof val === 'number') {
      meaningfulData.push(String(val));
    } else if (typeof val === 'object' && !Array.isArray(val)) {
      // 从对象中提取常见文本字段
      const textFields = ['state', 'title', 'name', 'text', 'content', 'type', 'destination', 'duration'];
      for (const field of textFields) {
        if (val[field] && typeof val[field] === 'string') {
          meaningfulData.push(`${field}: ${val[field]}`);
          break;
        }
      }
    }
  }

  return meaningfulData.length > 0 ? meaningfulData.join('\n') : '--';
}

function getTemplateName(templateId: string): string {
  // 优先使用数据中的 templateName，否则从模板列表中查找
  const approval = approvals.value.find(a => a.templateId === templateId);
  if (approval?.templateName) {
    return approval.templateName;
  }
  const template = templates.value.find(t => t.templateId === templateId);
  return template?.templateName || '未知类型';
}

function onTabChange() {
  currentPage.value = 1;
  loadData();
}

function handlePageChange(page: number) {
  currentPage.value = page;
  loadData();
}

function handleSearch() {
  currentPage.value = 1;
  loadData();
}

function getNodeTitle(apvRel: number): string {
  const apvRelMap: Record<number, string> = {
    1: '发起人',
    2: '审批人',
    3: '抄送人',
    4: '办理人',
  };
  return apvRelMap[apvRel] || '审批节点';
}

function getNodeStatusText(status: number): string {
  const nodeStatusMap: Record<number, string> = {
    1: '审批中',
    2: '已同意',
    3: '已驳回',
    4: '已转审',
  };
  return nodeStatusMap[status] || '待处理';
}

function getNodeStatusType(status: number): string {
  const typeMap: Record<number, string> = {
    1: 'warning',
    2: 'success',
    3: 'danger',
    4: 'info',
  };
  return typeMap[status] || 'info';
}

onMounted(() => {
  loadData();
  loadStats();
  loadTemplates();
});
</script>

<template>
  <div class="approval-page">
    <!-- Header -->
    <div class="page-header">
      <div class="header-tabs">
        <div
          v-for="tab in tabs"
          :key="tab.key"
          class="header-tab"
          :class="{ active: activeTab === tab.key }"
          @click="activeTab = tab.key; onTabChange()"
        >
          {{ tab.label }}
          <span v-if="tab.key === 'pending' && approvalStats.pending" class="tab-count">{{ approvalStats.pending }}</span>
          <span v-if="tab.key === 'my' && approvalStats.total" class="tab-count">{{ approvalStats.total }}</span>
          <span v-if="tab.key === 'done' && approvalStats.approved" class="tab-count">{{ approvalStats.approved }}</span>
        </div>
      </div>
      <div class="header-actions">
        <el-button round @click="handleSync">
          <el-icon><Download /></el-icon> 同步
        </el-button>
      </div>
    </div>

    <!-- Filters -->
    <div class="filter-bar">
      <el-select v-model="filters.type" placeholder="审批类型" clearable style="width: 160px" @change="handleSearch">
        <el-option v-for="t in templates" :key="t.templateId" :label="t.templateName" :value="t.templateName" />
      </el-select>
      <el-select v-model="filters.status" placeholder="审批状态" clearable style="width: 140px" @change="handleSearch">
        <el-option v-for="s in statusOptions" :key="s.value" :label="s.label" :value="s.value" />
      </el-select>
      <el-input v-model="search" placeholder="搜索审批单号或标题..." clearable style="width: 220px" @keyup.enter="handleSearch" />
    </div>

    <!-- Stats -->
    <div class="approval-stats">
      <div class="a-stat" v-for="s in statCards" :key="s.label">
        <div class="a-stat-dot" :style="{ background: s.color }"></div>
        <span class="a-stat-value">{{ s.value }}</span>
        <span class="a-stat-label">{{ s.label }}</span>
      </div>
    </div>

    <!-- Table -->
    <div class="table-card" v-loading="loading">
      <el-table :data="approvals" stripe style="width: 100%" row-class-name="approval-row">
        <el-table-column prop="spNo" label="审批单号" width="150">
          <template #default="{ row }">
            <span class="mono-id">{{ row.spNo }}</span>
          </template>
        </el-table-column>
        <el-table-column label="审批类型" width="140">
          <template #default="{ row }">
            <span class="type-tag">{{ getTemplateName(row.templateId) }}</span>
          </template>
        </el-table-column>
        <el-table-column prop="spName" label="审批标题" min-width="200">
          <template #default="{ row }">
            <div class="cell-title">{{ row.spName || '--' }}</div>
            <div class="cell-sub">{{ row.summaryInfo || '' }}</div>
          </template>
        </el-table-column>
        <el-table-column label="金额" width="120" align="right">
          <template #default="{ row }">
            <span class="amount" v-if="row.amount">{{ formatAmount(row.amount) }}</span>
            <span class="no-amount" v-else>—</span>
          </template>
        </el-table-column>
        <el-table-column label="状态" width="100" align="center">
          <template #default="{ row }">
            <el-tag :type="statusTagMap[row.spStatus] || 'info'" size="small" effect="light" round>{{ row.spStatusText || statusTextMap[row.spStatus] || '未知' }}</el-tag>
          </template>
        </el-table-column>
        <el-table-column label="提交时间" width="170">
          <template #default="{ row }">
            {{ formatTime(row.applyTime) }}
          </template>
        </el-table-column>
        <el-table-column label="操作" width="120" fixed="right">
          <template #default="{ row }">
            <el-button type="primary" link size="small" @click="handleView(row)">详情</el-button>
          </template>
        </el-table-column>
      </el-table>
      <div class="table-footer">
        <span class="footer-info">共 {{ total }} 条记录</span>
        <el-pagination
          v-model:current-page="currentPage"
          :page-size="pageSize"
          :total="total"
          layout="total, prev, pager, next, jumper"
          @current-change="handlePageChange"
        />
      </div>
    </div>

    <!-- 详情弹窗 -->
    <el-dialog
      v-model="detailVisible"
      title="审批详情"
      width="700px"
      :close-on-click-modal="false"
    >
      <div v-loading="detailLoading" style="min-height: 200px">
        <div v-if="currentDetail">
          <!-- 基本信息 -->
          <div class="detail-section">
            <h4 class="section-title">基本信息</h4>
            <div class="detail-row">
              <span class="detail-label">审批单号:</span>
              <span class="detail-value mono-id">{{ currentDetail.sp_no }}</span>
            </div>
            <div class="detail-row">
              <span class="detail-label">审批标题:</span>
              <span class="detail-value">{{ currentDetail.sp_name }}</span>
            </div>
            <div class="detail-row">
              <span class="detail-label">审批状态:</span>
              <el-tag :type="statusTagMap[currentDetail.sp_status] || 'info'" size="small" effect="light" round>
                {{ statusTextMap[currentDetail.sp_status] || '未知' }}
              </el-tag>
            </div>
            <div class="detail-row">
              <span class="detail-label">提交时间:</span>
              <span class="detail-value">{{ formatTime(currentDetail.apply_time) }}</span>
            </div>
            <div class="detail-row">
              <span class="detail-label">申请人:</span>
              <span class="detail-value">{{ currentDetail.applyer?.userid }} ({{ currentDetail.applyer?.party || '无部门' }})</span>
            </div>
          </div>

          <!-- 申请内容 -->
          <div class="detail-section">
            <h4 class="section-title">申请内容</h4>
            <div v-if="currentDetail.apply_data?.contents?.length">
              <div v-for="(item, idx) in currentDetail.apply_data.contents" :key="idx" class="form-item">
                <div class="form-label">{{ item.title?.[0]?.text || item.id }}</div>
                <div class="form-value">
                  <!-- 根据企业微信控件规范显示内容 -->
                  <div style="white-space: pre-wrap">
                    <template v-if="item.control === 'Money'">
                      <!-- 金额控件：格式化显示 -->
                      <span class="amount">{{ formatAmount(item.value?.money || 0) }}</span>
                    </template>
                    <template v-else>
                      {{ extractValueByControl(item.control, item.value) }}
                    </template>
                  </div>
                </div>
              </div>
            </div>
            <div v-else style="color: #999; padding: 20px; text-align: center">
              无申请内容数据
              <div style="margin-top: 10px; font-size: 12px">apply_data: {{ JSON.stringify(currentDetail.apply_data, null, 2) }}</div>
            </div>
          </div>

          <!-- 审批流程 -->
          <div class="detail-section" v-if="currentDetail.nodes?.length">
            <h4 class="section-title">审批流程</h4>
            <div v-for="(node, idx) in currentDetail.nodes" :key="idx" class="approval-node">
              <div class="node-header">
                <span class="node-title">{{ getNodeTitle(node.apv_rel) }}</span>
                <el-tag :type="getNodeStatusType(node.sp_status)" size="small">
                  {{ getNodeStatusText(node.sp_status) }}
                </el-tag>
              </div>
              <div v-for="(sub, sIdx) in node.sub_node" :key="sIdx" class="node-item">
                <div class="approver-info">
                  <span class="approver">{{ sub.approver?.userid }}</span>
                  <span class="approve-time">{{ formatTime(sub.sp_time) }}</span>
                </div>
                <div class="approve-result">
                  <el-tag :type="getNodeStatusType(sub.sp_status)" size="small">
                    {{ getNodeStatusText(sub.sp_status) }}
                  </el-tag>
                  <span v-if="sub.speech" class="speech">{{ sub.speech }}</span>
                </div>
              </div>
            </div>
          </div>

          <!-- 评论记录 -->
          <div class="detail-section" v-if="currentDetail.comments?.length">
            <h4 class="section-title">评论记录</h4>
            <div v-for="(comment, idx) in currentDetail.comments" :key="idx" class="comment-item">
              <div class="comment-header">
                <span class="commenter">{{ comment.commentUserInfo?.userid }}</span>
                <span class="comment-time">{{ formatTime(comment.commentTime) }}</span>
              </div>
              <div class="comment-content">{{ comment.commentContent }}</div>
            </div>
          </div>
        </div>
        <div v-else style="text-align: center; padding: 40px; color: #999">
          加载失败或数据为空
        </div>
      </div>
    </el-dialog>
  </div>
</template>

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

.page-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 20px;
}

.header-tabs {
  display: flex;
  gap: 4px;
  background: #fff;
  border-radius: 12px;
  padding: 4px;
  box-shadow: var(--shadow-sm);
}

.header-tab {
  padding: 8px 20px;
  border-radius: 10px;
  cursor: pointer;
  font-size: 13.5px;
  font-weight: 500;
  color: var(--color-text-secondary);
  transition: all 0.25s ease;
  display: flex;
  align-items: center;
  gap: 6px;

  &:hover { color: var(--color-text-primary); background: #f8f7f5; }
  &.active {
    background: var(--color-accent);
    color: #fff;
    box-shadow: 0 2px 8px rgba(29,90,243,0.3);
  }
}

.tab-count {
  font-size: 11px;
  padding: 1px 7px;
  border-radius: 20px;
  background: rgba(0,0,0,0.08);
  .active & { background: rgba(255,255,255,0.25); }
}

.header-actions {
  display: flex;
  gap: 8px;
}

.filter-bar {
  display: flex;
  gap: 10px;
  margin-bottom: 16px;
  flex-wrap: wrap;
}

.approval-stats {
  display: flex;
  gap: 24px;
  margin-bottom: 16px;
  padding: 16px 20px;
  background: #fff;
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
}

.a-stat {
  display: flex;
  align-items: center;
  gap: 8px;
}

.a-stat-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
}

.a-stat-value {
  font-size: 20px;
  font-weight: 700;
  color: var(--color-text-primary);
}

.a-stat-label {
  font-size: 12px;
  color: var(--color-text-secondary);
}

.table-card {
  background: #fff;
  border-radius: var(--radius-lg);
  padding: 20px;
  box-shadow: var(--shadow-sm);
}

.mono-id {
  font-family: 'SF Mono', Menlo, monospace;
  font-size: 12.5px;
  color: var(--color-accent);
  font-weight: 600;
}

.type-tag {
  font-size: 13px;
  font-weight: 500;
  color: var(--color-text-secondary);
}

.cell-title {
  font-size: 13.5px;
  font-weight: 600;
  color: var(--color-text-primary);
}

.cell-sub {
  font-size: 12px;
  color: var(--color-text-secondary);
  margin-top: 2px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 200px;
}

.amount {
  font-weight: 700;
  color: var(--color-text-primary);
  font-size: 13px;
}

.no-amount {
  color: #ccc;
}

.table-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-top: 16px;
  padding-top: 16px;
  border-top: 1px solid #f5f3f0;
}

.footer-info {
  font-size: 13px;
  color: var(--color-text-secondary);
}

@media (max-width: 768px) {
  .approval-stats {
    flex-wrap: wrap;
    gap: 12px;
  }

  .filter-bar {
    flex-direction: column;
  }
}

.detail-section {
  margin-bottom: 24px;

  &:last-child {
    margin-bottom: 0;
  }
}

.section-title {
  font-size: 15px;
  font-weight: 600;
  color: var(--color-text-primary);
  margin-bottom: 16px;
  padding-bottom: 8px;
  border-bottom: 2px solid var(--color-accent);
}

.detail-row {
  display: flex;
  align-items: flex-start;
  margin-bottom: 12px;
  gap: 12px;

  &:last-child {
    margin-bottom: 0;
  }
}

.detail-label {
  min-width: 100px;
  font-size: 13px;
  color: var(--color-text-secondary);
  flex-shrink: 0;
}

.detail-value {
  font-size: 13px;
  color: var(--color-text-primary);
  flex: 1;
}

.form-item {
  background: #f8f9fa;
  border-radius: 8px;
  padding: 12px 16px;
  margin-bottom: 12px;

  &:last-child {
    margin-bottom: 0;
  }
}

.form-label {
  font-size: 12px;
  color: var(--color-text-secondary);
  margin-bottom: 8px;
}

.form-value {
  font-size: 13px;
  color: var(--color-text-primary);
  font-weight: 500;
}

.file-item {
  color: var(--color-accent);
  margin-bottom: 4px;
}

.approval-node {
  background: #f8f9fa;
  border-radius: 8px;
  padding: 12px 16px;
  margin-bottom: 12px;

  &:last-child {
    margin-bottom: 0;
  }
}

.node-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 12px;
}

.node-title {
  font-size: 13px;
  font-weight: 600;
  color: var(--color-text-primary);
}

.node-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 8px 0;
  border-bottom: 1px solid #e9ecef;

  &:last-child {
    border-bottom: none;
  }
}

.approver-info {
  display: flex;
  align-items: center;
  gap: 16px;
}

.approver {
  font-size: 13px;
  color: var(--color-text-primary);
  font-weight: 500;
}

.approve-time {
  font-size: 12px;
  color: var(--color-text-secondary);
}

.approve-result {
  display: flex;
  align-items: center;
  gap: 8px;
}

.speech {
  font-size: 12px;
  color: var(--color-text-secondary);
  margin-left: 8px;
}

.comment-item {
  background: #f8f9fa;
  border-radius: 8px;
  padding: 12px 16px;
  margin-bottom: 12px;

  &:last-child {
    margin-bottom: 0;
  }
}

.comment-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 8px;
}

.commenter {
  font-size: 13px;
  color: var(--color-text-primary);
  font-weight: 500;
}

.comment-time {
  font-size: 12px;
  color: var(--color-text-secondary);
}

.comment-content {
  font-size: 13px;
  color: var(--color-text-primary);
  line-height: 1.6;
}
</style>
