<template>
  <view class="request-detail">
    <!-- 页面标题栏 -->
    <view class="page-header" v-if="!embedded">
      <uni-nav-bar 
        left-icon="back" 
        title="请假详情" 
        @clickLeft="navigateBack"
        right-text="刷新"
        @clickRight="loadDetail"
      ></uni-nav-bar>
    </view>

    <!-- 主内容区 -->
    <scroll-view class="content-scroll" scroll-y>
      <!-- 加载中状态 -->
      <view v-if="loading" class="loading-container">
        <uni-load-more type="loading" color="#409EFF"></uni-load-more>
      </view>

      <view v-else class="content-wrapper">
        <!-- 顶部摘要 -->
        <view class="form-summary">
          <view class="summary-left">
            <view class="summary-title">{{ detail.leaveType || '请假申请' }}</view>
            <view class="summary-sub">
              申请编号：{{ detail.bizId || '-' }} · 
              状态：<view class="status-tag" :class="statusType">{{ statusText }}</view>
            </view>
          </view>
          <view class="summary-right">
            <view class="summary-item">
              <view class="k">申请人</view>
              <view class="v">{{ detail.createBy || '-' }}<text v-if="detail.empNo" class="text-muted">({{ detail.empNo }})</text></view>
            </view>
            <view class="summary-item">
              <view class="k">请假时长</view>
              <view class="v">{{ detail.hours || '0' }} 小时</view>
            </view>
          </view>
        </view>

        <!-- 请假日期信息 -->
        <view class="block-title">请假日期</view>
        <view class="inner-card">
          <view class="descriptions-list">
            <view class="descriptions-item">
              <view class="label">开始时间</view>
              <view class="value date-time">{{ formatDate(detail.startTime) }}</view>
            </view>
            <view class="descriptions-item">
              <view class="label">结束时间</view>
              <view class="value date-time">{{ formatDate(detail.endTime) }}</view>
            </view>
            <view class="descriptions-item">
              <view class="label">请假类型</view>
              <view class="value">{{ detail.leaveType || '-' }}</view>
            </view>
            <view class="descriptions-item">
              <view class="label">时长(小时)</view>
              <view class="value">{{ detail.hours || '0' }} 小时</view>
            </view>
            <view class="descriptions-item">
              <view class="label">创建时间</view>
              <view class="value">{{ formatDate(detail.createTime) }}</view>
            </view>
            <view class="descriptions-item">
              <view class="label">更新时间</view>
              <view class="value">{{ formatDate(detail.updateTime) }}</view>
            </view>
          </view>
        </view>

        <!-- 请假理由说明 -->
        <view class="block-title">请假理由说明</view>
        <view class="inner-card">
          <view class="reason-section">
            <view class="reason-label">事由</view>
            <view class="reason-content">{{ detail.reason || '未填写' }}</view>
          </view>
          <view v-if="detail.handover" class="reason-section">
            <view class="reason-label">工作交接</view>
            <view class="reason-content">{{ detail.handover }}</view>
          </view>
          <view v-if="detail.remark" class="reason-section">
            <view class="reason-label">备注</view>
            <view class="reason-content">{{ detail.remark }}</view>
          </view>
        </view>

        <!-- 申请附件 -->
        <view class="block-title">申请附件</view>
        <view class="inner-card" v-if="attachmentLoading">
          <view class="loading-small">
            <uni-load-more type="loading" color="#409EFF" size="small"></uni-load-more>
          </view>
        </view>
        <view class="inner-card" v-else>
          <view v-if="attachmentList.length > 0" class="attachment-list">
            <view v-for="file in attachmentList" :key="file.ossId" class="attachment-item">
              <view class="file-info">
                <uni-icons type="paper" size="24" color="#9aa3b2"></uni-icons>
                <view class="file-details">
                  <view class="file-name">{{ file.originalName || file.fileName || `文件${file.ossId}` }}</view>
                  <view class="file-meta">
                    <text v-if="file.fileSize">{{ formatFileSize(file.fileSize) }}</text>
                    <text v-if="file.createTime" class="file-time">{{ formatDate(file.createTime) }}</text>
                  </view>
                </view>
              </view>
              <view class="file-actions">
                <button class="file-btn" size="mini" @click="previewFile(file)">预览</button>
                <button class="file-btn" size="mini" @click="downloadFile(file.ossId)">下载</button>
              </view>
            </view>
          </view>
          <view v-else class="empty">暂无附件</view>
        </view>

        <!-- 审批意见 -->
        <view v-if="currentTask" class="approve-section">
          <view class="section-title">审批意见</view>
          <textarea 
            v-model="approveForm.comment"
            placeholder="请输入审批意见（可选）"
            class="approve-textarea"
          ></textarea>
        </view>

        <!-- 审批操作按钮 -->
        <view v-if="!embedded && (canApprove || canWithdraw)" class="action-buttons">
          <button 
            v-if="canApprove" 
            class="btn approve-btn" 
            :loading="actionLoading"
            @click="handleApprove"
          >
            通过
          </button>
          <button 
            v-if="canApprove" 
            class="btn reject-btn" 
            :loading="actionLoading"
            @click="handleReject"
          >
            驳回
          </button>
          <button 
            v-if="canWithdraw" 
            class="btn withdraw-btn" 
            :loading="actionLoading"
            @click="handleWithdraw"
          >
            撤回
          </button>
        </view>

        <!-- 流转历史 -->
        <view class="flow-history">
          <view class="section-title">流转历史</view>
          <view v-if="flowHistory.length > 0" class="timeline">
            <view 
              v-for="(item, index) in flowHistory" 
              :key="index"
              class="timeline-item"
            >
              <!-- 时间轴点 -->
              <view class="timeline-dot" :class="getTimelineType(item.action)"></view>
              <!-- 时间轴内容 -->
              <view class="timeline-content">
                <view class="timeline-time">{{ formatDate(item.createTime) }}</view>
                <view class="timeline-card">
                  <view class="action-text">{{ getActionText(item.action) }}</view>
                  <view class="operator">处理人: {{ item.createBy || '系统' }}</view>
                  <view v-if="item.comment" class="comment">意见: {{ item.comment }}</view>
                </view>
              </view>
            </view>
          </view>
          <view v-else class="no-data">暂无流转记录</view>
        </view>
      </view>
    </scroll-view>
  </view>
</template>

<script>
// 导入API（需适配Uniapp的request请求，此处保留原API结构，实际需替换为uni.request）
import { getLeaveReq } from '@/api/hrm/leave'
import { getTodoTaskByBiz, approveFlowTask, rejectFlowTask, withdrawFlowTask, listFlowAction, queryInstanceByBiz, getFlowInstance, listFlowNode } from '@/api/hrm/flow'
import { listByIds } from '@/api/oa/oss'

export default {
  name: 'LeaveDetail',
  props: {
    embedded: { type: Boolean, default: false }
  },
  data() {
    return {
      loading: false,
      actionLoading: false,
      detail: {},
      currentTask: null,
      flowHistory: [],
      approveForm: {
        comment: ''
      },
      attachmentList: [],
      attachmentLoading: false,
      flowInstance: null, // 流程实例信息
      flowNodes: [], // 流程节点列表
      currentNode: null, // 当前节点信息
      bizId: null // 从onLoad获取的业务ID
    }
  },
  computed: {
    statusText() {
      const statusMap = {
        'draft': '草稿',
        'pending': '审批中',
        'approved': '已通过',
        'rejected': '已驳回',
        'withdrawn': '已撤回'
      }
      return statusMap[this.detail.status] || this.detail.status || '未知'
    },
    statusType() {
      const typeMap = {
        'draft': 'info',
        'pending': 'warning',
        'approved': 'success',
        'rejected': 'danger',
        'withdrawn': 'info'
      }
      return typeMap[this.detail.status] || 'info'
    },
    canWithdraw() {
      // 只有待审批状态且是当前用户提交的才能撤回
      return this.detail.status === 'pending' && this.detail.createBy === this.$store.getters.name
    },
    canApprove() {
      // 只有待审批状态且是当前用户待审批的才能审批
      return this.detail.status === 'pending' && (this.currentTask?.assigneeUserName === this.$store.getters.name || this.currentTask?.assigneeUserId === this.$store.getters.id)
    }
  },
  onLoad(options) {
    // Uniapp通过onLoad获取页面参数
    this.bizId = options.bizId || options.id
    this.loadDetail()
  },
  methods: {
    // 返回上一页（适配Uniapp路由）
    navigateBack() {
      uni.navigateBack({
        delta: 1
      })
    },
    async loadDetail() {
      const bizId = this.bizId
      if (!bizId) return
      
      this.loading = true
      try {
        // 加载请假单详情
        const detailRes = await getLeaveReq(bizId)
        this.detail = detailRes.data || {}
        
        // 加载流程实例信息
        await this.loadFlowInstance()
        
        // 加载当前待办任务
        await this.loadCurrentTask()
        
        // 加载流转历史和附件
        await Promise.all([
          this.loadFlowHistory(),
          this.loadAttachments()
        ])
      } catch (error) {
        console.error('加载详情失败:', error)
        uni.showToast({
          title: '加载详情失败',
          icon: 'error'
        })
      } finally {
        this.loading = false
      }
    },
    
    async loadCurrentTask() {
      const bizId = this.bizId
      if (!bizId) {
        this.currentTask = null
        return
      }
      try {
        const res = await getTodoTaskByBiz('leave', bizId)
        this.currentTask = res?.data || null
      } catch (error) {
        console.error('加载待办任务失败:', error)
        this.currentTask = null
      }
    },
    async loadFlowInstance() {
      if (!this.detail.instId) {
        // 如果没有instId，尝试通过bizType和bizId查询
        try {
          const res = await queryInstanceByBiz('leave', this.bizId)
          const instances = res.data || []
          if (instances.length > 0) {
            this.flowInstance = instances[0]
            this.detail.instId = instances[0].instId
            // 加载流程节点信息
            await this.loadFlowNodes()
            // 根据当前节点ID查找节点信息
            if (this.flowInstance.currentNodeId) {
              this.currentNode = this.flowNodes.find(n => n.nodeId === this.flowInstance.currentNodeId) || null
            }
          }
        } catch (e) {
          console.error('加载流程实例失败:', e)
        }
      } else {
        // 如果有instId，直接加载
        try {
          const res = await getFlowInstance(this.detail.instId)
          this.flowInstance = res.data || null
          // 加载流程节点信息
          await this.loadFlowNodes()
          // 根据当前节点ID查找节点信息
          if (this.flowInstance && this.flowInstance.currentNodeId) {
            this.currentNode = this.flowNodes.find(n => n.nodeId === this.flowInstance.currentNodeId) || null
          }
        } catch (e) {
          console.error('加载流程实例失败:', e)
        }
      }
    },
    async loadFlowNodes() {
      if (!this.flowInstance || !this.flowInstance.tplId) {
        this.flowNodes = []
        return
      }
      try {
        const res = await listFlowNode({ tplId: this.flowInstance.tplId, pageNum: 1, pageSize: 500 })
        this.flowNodes = res.rows || res.data || []
      } catch (e) {
        console.error('加载流程节点失败:', e)
        this.flowNodes = []
      }
    },

    async loadFlowHistory() {
      // 基于 instId 拉取流转历史（优先用 instId；无则不查）
      const instId = this.detail?.instId
      if (!instId) {
        this.flowHistory = []
        return
      }
      try {
        const res = await listFlowAction({ instId, pageNum: 1, pageSize: 200 })
        this.flowHistory = res.rows || res.data || []
      } catch (error) {
        this.flowHistory = []
      }
    },
    
    async handleApprove() {
      await this.handleAction('approve', '通过成功', '通过')
    },
    
    async handleReject() {
      await this.handleAction('reject', '已驳回', '驳回')
    },
    
    async handleWithdraw() {
      await this.handleAction('withdraw', '已撤回', '撤回')
    },
    
    async handleAction(action, successMsg, actionName) {
      if (!this.currentTask?.taskId) {
        uni.showToast({
          title: '未找到待办任务',
          icon: 'none'
        })
        return
      }
      
      // Uniapp确认弹窗
      uni.showModal({
        title: '提示',
        content: `确定${actionName}该申请吗？`,
        success: async (res) => {
          if (res.confirm) {
            this.actionLoading = true
            try {
              const payload = { remark: this.approveForm.comment }

              if (action === 'approve') {
                await approveFlowTask(this.currentTask.taskId, payload)
              } else if (action === 'reject') {
                await rejectFlowTask(this.currentTask.taskId, payload)
              } else if (action === 'withdraw') {
                await withdrawFlowTask(this.currentTask.taskId, payload)
              }

              uni.showToast({
                title: successMsg,
                icon: 'success'
              })
              await this.loadDetail()
              // 清空审批意见
              this.approveForm.comment = ''
            } catch (error) {
              console.error(`${actionName}失败:`, error)
              uni.showToast({
                title: error.message || `${actionName}失败`,
                icon: 'error'
              })
            } finally {
              this.actionLoading = false
            }
          }
        }
      })
    },
    
    formatDate(val) {
      if (!val) return '-'
      const d = new Date(val)
      const p = n => (n < 10 ? `0${n}` : n)
      return `${d.getFullYear()}-${p(d.getMonth() + 1)}-${p(d.getDate())} ${p(d.getHours())}:${p(d.getMinutes())}`
    },
    
    getActionText(action) {
      const map = {
        'submit': '提交申请',
        'approve': '通过',
        'reject': '驳回',
        'withdraw': '撤回',
        'cancel': '取消'
      }
      return map[action] || action
    },
    
    getTimelineType(action) {
      const map = {
        'submit': 'primary',
        'approve': 'success',
        'reject': 'danger',
        'withdraw': 'info',
        'cancel': 'info'
      }
      return map[action] || 'info'
    },
    async loadAttachments() {
      const fileIds = this.detail.accessoryApplyIds || this.detail.applyFileIds
      if (!fileIds) {
        this.attachmentList = []
        return
      }
      const ids = String(fileIds).split(',').map(id => id.trim()).filter(Boolean)
      if (ids.length === 0) {
        this.attachmentList = []
        return
      }
      this.attachmentLoading = true
      try {
        const res = await listByIds(ids)
        this.attachmentList = res.data || []
      } catch (e) {
        uni.showToast({
          title: '加载附件失败：' + (e.message || '未知错误'),
          icon: 'error'
        })
        this.attachmentList = []
      } finally {
        this.attachmentLoading = false
      }
    },
    formatFileSize(bytes) {
      if (!bytes) return '-'
      const units = ['B', 'KB', 'MB', 'GB']
      let size = Number(bytes)
      let unitIndex = 0
      while (size >= 1024 && unitIndex < units.length - 1) {
        size /= 1024
        unitIndex++
      }
      return `${size.toFixed(2)} ${units[unitIndex]}`
    },
    // 移动端附件预览
    previewFile(file) {
      if (file.url) {
        // 图片类文件直接预览，其他文件提示下载
        const fileExt = (file.originalName || '').split('.').pop().toLowerCase()
        const imageExts = ['jpg', 'jpeg', 'png', 'gif', 'bmp']
        
        if (imageExts.includes(fileExt)) {
          uni.previewImage({
            urls: [file.url],
            current: file.url
          })
        } else {
          uni.showModal({
            title: '提示',
            content: '该文件不支持预览，是否下载？',
            success: (res) => {
              if (res.confirm) {
                this.downloadFile(file.ossId)
              }
            }
          })
        }
      } else {
        uni.showToast({
          title: '文件URL不存在',
          icon: 'none'
        })
      }
    },
    // 移动端附件下载
    downloadFile(ossId) {
      uni.showLoading({
        title: '下载中...'
      })
      // Uniapp下载文件API
      uni.downloadFile({
        url: `/system/oss/download/${ossId}`,
        success: (res) => {
          uni.hideLoading()
          if (res.statusCode === 200) {
            // 打开下载的文件
            uni.openDocument({
              filePath: res.tempFilePath,
              showMenu: true,
              fail: (err) => {
                uni.showToast({
                  title: '打开文件失败',
                  icon: 'error'
                })
              }
            })
          } else {
            uni.showToast({
              title: '下载失败',
              icon: 'error'
            })
          }
        },
        fail: (err) => {
          uni.hideLoading()
          uni.showToast({
            title: '下载失败：' + err.message,
            icon: 'error'
          })
        }
      })
    }
  }
}
</script>

<style lang="scss" scoped>
.request-detail {
  min-height: 100vh;
  background-color: #f5f5f5;
  
  .page-header {
    background-color: #fff;
  }

  .content-scroll {
    height: calc(100vh - 44px);
    padding: 16rpx;
  }

  .loading-container {
    display: flex;
    justify-content: center;
    align-items: center;
    height: 400rpx;
  }

  .content-wrapper {
    gap: 16rpx;
    display: flex;
    flex-direction: column;
  }

  .form-summary {
    display: flex;
    flex-direction: column;
    gap: 12rpx;
    padding: 16rpx;
    border: 1px solid #e6e8ed;
    border-radius: 10rpx;
    background: linear-gradient(180deg, #ffffff 0%, #fbfcfe 100%);
  }

  .summary-title {
    font-size: 32rpx;
    font-weight: 800;
    color: #2b2f36;
  }

  .summary-sub {
    font-size: 24rpx;
    color: #8a8f99;
  }

  .status-tag {
    padding: 4rpx 8rpx;
    border-radius: 4rpx;
    font-size: 22rpx;
    color: #fff;
    
    &.success {
      background-color: #67c23a;
    }
    &.danger {
      background-color: #f56c6c;
    }
    &.warning {
      background-color: #e6a23c;
    }
    &.info {
      background-color: #909399;
    }
  }

  .summary-right {
    display: flex;
    gap: 24rpx;
    margin-top: 12rpx;
  }

  .summary-item .k {
    font-size: 24rpx;
    color: #8a8f99;
  }

  .summary-item .v {
    margin-top: 4rpx;
    font-weight: 700;
    color: #2b2f36;
    font-size: 26rpx;
  }

  .text-muted {
    color: #909399;
    margin-left: 8rpx;
    font-size: 22rpx;
  }

  .block-title {
    margin: 16rpx 0 8rpx;
    padding-left: 10rpx;
    font-weight: 700;
    color: #2f3440;
    border-left: 6rpx solid #9aa3b2;
    font-size: 28rpx;
  }

  .inner-card {
    border: 1px solid #e6e8ed;
    border-radius: 8rpx;
    background-color: #fff;
    padding: 16rpx;
  }

  .descriptions-list {
    display: flex;
    flex-wrap: wrap;
  }

  .descriptions-item {
    width: 50%;
    margin-bottom: 16rpx;
    display: flex;
    flex-direction: column;
    
    &:last-child {
      margin-bottom: 0;
    }
  }

  .descriptions-item .label {
    font-size: 24rpx;
    color: #8a8f99;
    margin-bottom: 4rpx;
  }

  .descriptions-item .value {
    font-size: 26rpx;
    color: #2b2f36;
  }

  .date-time {
    font-weight: 600;
    color: #2b2f36;
  }

  .reason-section {
    margin-bottom: 16rpx;
  }

  .reason-section:last-child {
    margin-bottom: 0;
  }

  .reason-label {
    font-size: 26rpx;
    font-weight: 600;
    color: #606266;
    margin-bottom: 8rpx;
  }

  .reason-content {
    padding: 16rpx;
    background: #f8f9fa;
    border-radius: 6rpx;
    color: #2b2f36;
    line-height: 1.6;
    white-space: pre-wrap;
    word-break: break-word;
    font-size: 26rpx;
  }

  .loading-small {
    padding: 20rpx 0;
    text-align: center;
  }

  .attachment-list {
    display: flex;
    flex-direction: column;
    gap: 10rpx;
  }

  .attachment-item {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 10rpx 12rpx;
    border: 1px solid #e6e8ed;
    border-radius: 8rpx;
    background: #fafbfc;
  }

  .file-info {
    display: flex;
    align-items: center;
    gap: 10rpx;
    flex: 1;
  }

  .file-details {
    flex: 1;
  }

  .file-name {
    font-weight: 600;
    color: #2b2f36;
    margin-bottom: 4rpx;
    font-size: 26rpx;
  }

  .file-meta {
    font-size: 22rpx;
    color: #8a8f99;
    display: flex;
    gap: 12rpx;
  }

  .file-time {
    margin-left: 8rpx;
  }

  .file-actions {
    display: flex;
    gap: 8rpx;
  }

  .file-btn {
    font-size: 22rpx;
    padding: 4rpx 8rpx;
    background-color: #f5f7fa;
    color: #409eff;
    border: none;
    border-radius: 4rpx;
  }

  .empty {
    color: #a0a3ad;
    font-size: 24rpx;
    padding: 20rpx 0;
    text-align: center;
  }

  .approve-section {
    margin-top: 20rpx;
    background: #f8f9fa;
    padding: 15rpx;
    border-radius: 8rpx;
  }

  .section-title {
    font-size: 28rpx;
    font-weight: bold;
    margin-bottom: 10rpx;
    color: #303133;
  }

  .approve-textarea {
    width: 100%;
    padding: 12rpx;
    border: 1px solid #e6e8ed;
    border-radius: 8rpx;
    background-color: #fff;
    min-height: 120rpx;
    font-size: 26rpx;
  }

  .action-buttons {
    display: flex;
    gap: 16rpx;
    margin-top: 20rpx;
  }

  .btn {
    flex: 1;
    height: 80rpx;
    line-height: 80rpx;
    border-radius: 8rpx;
    font-size: 28rpx;
    border: none;
    
    &.approve-btn {
      background-color: #67c23a;
      color: #fff;
    }
    
    &.reject-btn {
      background-color: #f56c6c;
      color: #fff;
    }
    
    &.withdraw-btn {
      background-color: #409eff;
      color: #fff;
    }
  }

  .flow-history {
    margin-top: 30rpx;
  }

  .no-data {
    text-align: center;
    color: #909399;
    padding: 40rpx 0;
    font-size: 24rpx;
  }

  .timeline {
    position: relative;
    padding-left: 30rpx;
    margin-left: 10rpx;
    
    &::before {
      content: '';
      position: absolute;
      left: 10rpx;
      top: 10rpx;
      bottom: 10rpx;
      width: 2rpx;
      background-color: #e6e8ed;
    }
  }

  .timeline-item {
    position: relative;
    margin-bottom: 30rpx;
    
    &:last-child {
      margin-bottom: 0;
    }
  }

  .timeline-dot {
    position: absolute;
    left: -36rpx;
    top: 0;
    width: 20rpx;
    height: 20rpx;
    border-radius: 50%;
    
    &.primary {
      background-color: #409eff;
    }
    &.success {
      background-color: #67c23a;
    }
    &.danger {
      background-color: #f56c6c;
    }
    &.info {
      background-color: #909399;
    }
  }

  .timeline-content {
    background-color: #fff;
    border-radius: 8rpx;
    padding: 16rpx;
    box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.04);
  }

  .timeline-time {
    font-size: 22rpx;
    color: #909399;
    margin-bottom: 8rpx;
  }

  .action-text {
    font-size: 26rpx;
    font-weight: 600;
    color: #303133;
    margin-bottom: 8rpx;
  }

  .operator {
    font-size: 24rpx;
    color: #606266;
    margin-bottom: 4rpx;
  }

  .comment {
    font-size: 24rpx;
    color: #606266;
    padding-top: 8rpx;
    border-top: 1px solid #f0f0f0;
  }
}
</style>