<template>
  <div class="app-container">
    <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
      <el-form-item label="文档名称" prop="docName">
        <el-input
          v-model="queryParams.docName"
          placeholder="请输入文档名称"
          clearable
          @keyup.enter.native="handleQuery"
        />
      </el-form-item>
      <el-form-item label="上传者" prop="createBy">
        <el-input
          v-model="queryParams.createBy"
          placeholder="请输入上传者"
          clearable
          @keyup.enter.native="handleQuery"
        />
      </el-form-item>
      <el-form-item>
        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
      </el-form-item>
    </el-form>

    <el-row :gutter="10" class="mb8">
      <el-col :span="1.5">
        <el-button
          type="primary"
          plain
          icon="el-icon-upload"
          size="mini"
          @click="handleUpload"
          v-hasPermi="['project:doc:upload']"
        >上传文档</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="danger"
          plain
          icon="el-icon-delete"
          size="mini"
          :disabled="multiple"
          @click="handleDelete"
          v-hasPermi="['project:doc:remove']"
        >删除</el-button>
      </el-col>
    </el-row>

    <el-table v-loading="loading" :data="docList" @selection-change="handleSelectionChange">
      <el-table-column type="selection" width="55" align="center" />
      <el-table-column label="文档名称" align="center" prop="docName" />
      <el-table-column label="所属项目" align="center" prop="projectName" />
      <el-table-column label="所属模块" align="center">
        <template slot-scope="scope">
          <span>{{ scope.row.moduleName || (scope.row.kindType === '0' || scope.row.kindType === 0 ? '项目文档' : '-') }}</span>
        </template>
      </el-table-column>
      <el-table-column label="文档类型" align="center">
        <template slot-scope="scope">
          <span>{{ (scope.row.docType) || (scope.row.docPath ? scope.row.docPath.split('.').pop() : '-') }}</span>
        </template>
      </el-table-column>
      <el-table-column label="文件大小" align="center">
        <template slot-scope="scope">
          <span>{{ scope.row.docSize || '-' }}</span>
        </template>
      </el-table-column>
      <el-table-column label="上传者" align="center" prop="createBy" />
      <el-table-column label="上传时间" align="center" prop="createTime" width="180">
        <template slot-scope="scope">
          <span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}</span>
        </template>
      </el-table-column>
      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
        <template slot-scope="scope">
          <el-button
            size="mini"
            type="text"
            icon="el-icon-download"
            @click="handleDownload(scope.row)"
            v-hasPermi="['project:doc:download']"
          >下载</el-button>
          <el-button
            size="mini"
            type="text"
            icon="el-icon-delete"
            @click="handleDelete(scope.row)"
            v-hasPermi="['project:doc:remove']"
          >删除</el-button>
        </template>
      </el-table-column>
    </el-table>

    <pagination
      v-show="total>0"
      :total="total"
      :page.sync="queryParams.pageNum"
      :limit.sync="queryParams.pageSize"
      @pagination="getList"
    />

    <!-- 上传文档对话框 -->
    <el-dialog :title="uploadTitle" :visible.sync="uploadOpen" width="600px" append-to-body>
      <el-form label-width="90px" size="small" style="margin-bottom: 10px;">
        <el-form-item label="文档类型">
          <el-radio-group v-model="upload.meta.kindType" @change="handleKindTypeChange">
            <el-radio :label="0" :disabled="isNormalUser">项目文档</el-radio>
            <el-radio :label="1">模块文档</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="所属项目">
          <el-select v-model="upload.meta.projectId" placeholder="请选择项目" filterable @change="handleProjectChange">
            <el-option v-for="p in projectOptions" :key="p.projectId" :label="p.projectName" :value="p.projectId"/>
          </el-select>
        </el-form-item>
        <el-form-item v-if="upload.meta.kindType === 1" label="所属模块">
          <el-select v-model="upload.meta.moduleId" placeholder="请选择模块" filterable :disabled="!moduleOptions.length">
            <el-option v-for="m in moduleOptions" :key="m.moduleId" :label="m.moduleName" :value="m.moduleId"/>
          </el-select>
        </el-form-item>
      </el-form>
      <el-upload
        ref="upload"
        :limit="1"
        accept=".pdf,.doc,.docx,.txt"
        :action="upload.url"
        :headers="upload.headers"
        :file-list="upload.fileList"
        :data="upload.data"
        :on-progress="handleFileUploadProgress"
        :on-success="handleFileSuccess"
        :on-error="handleFileError"
        :on-exceed="handleFileExceed"
        :auto-upload="false"
        :with-credentials="false"
        :http-request="customHttpRequest"
        drag
      >
        <i class="el-icon-upload"></i>
        <div class="el-upload__text">
          将文件拖到此处，或<em>点击上传</em>
        </div>
        <div class="el-upload__tip" slot="tip">
          <div>
            <strong>文档类型：</strong>{{ upload.meta.kindType === 1 ? '模块文档' : '项目文档' }}<br>
            <strong>所属项目：</strong>{{ (projectOptions.find(p=>String(p.projectId)===String(upload.meta.projectId))||{}).projectName || '-' }}<br>
            <template v-if="upload.meta.kindType === 1">
              <strong>所属模块：</strong>{{ (moduleOptions.find(m=>String(m.moduleId)===String(upload.meta.moduleId))||{}).moduleName || '-' }}
            </template>
          </div>
          <br>
          支持格式：PDF、DOC、DOCX、TXT
        </div>
      </el-upload>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="submitFileForm">确 定</el-button>
        <el-button @click="uploadOpen = false">取 消</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import { getToken } from '@/utils/auth'
import { listDoc, delDoc } from '@/api/project/doc'
import { listProject } from '@/api/project/project'
import { listModulesByProject, getMyModules } from '@/api/project/module'

export default {
  name: "Doc",
  computed: {
    // 是否项目管理员/平台管理员
    isProjectAdmin() {
      const roles = this.$store.state.user.roles || []
      return roles.some(r => {
        const key = typeof r === 'string' ? r : r.roleKey
        return key === 'project_admin' || key === 'platform_admin'
      })
    },
    // 是否普通用户（且不是管理员）
    isNormalUser() {
      const roles = this.$store.state.user.roles || []
      const hasNormal = roles.some(r => (typeof r === 'string' ? r : r.roleKey) === 'normal_user')
      return hasNormal && !this.isProjectAdmin
    },
    // 当前用户ID（用于前端过滤：项目管理员仅看见自己创建的项目）
    currentUserId() {
      const u = this.$store.state.user || {}
      return u.userId || u.user_id || u.id || null
    }
  },
  data() {
    return {
      // 遮罩层
      loading: true,
      // 选中数组
      ids: [],
      // 非多个禁用
      multiple: true,
      // 显示搜索条件
      showSearch: true,
      // 总条数
      total: 0,
      // 文档表格数据
      docList: [],
      // 弹出层标题
      uploadTitle: "",
      // 是否显示弹出层
      uploadOpen: false,
      // 查询参数
      queryParams: {
        pageNum: 1,
        pageSize: 10,
        docName: null,
        createBy: null,
        // 查询条件：根据上下文映射到 projectId 或 moduleId
        projectId: null,
        moduleId: null,
        kind_type: null,  // 文档类型：0=项目文档，1=模块文档
      },
      // 当前上下文信息
      currentContext: {
        pmodel_id: null,
        kind_type: null,
        moduleName: null,
        projectId: null,
        projectName: null,
        isViewMode: false
      },
      // 上传参数
      upload: {
        // 是否禁用上传
        isUploading: false,
        // 设置上传的请求头部
        headers: { Authorization: "Bearer " + getToken() },
        // 上传的地址
        url: process.env.VUE_APP_BASE_API + "/project/doc/upload",
        // 上传的文件列表
        fileList: [],
        // 上传时的额外参数
        data: {},
        // 选择元数据（不直接污染data，最终同步到data里提交）
        meta: {
          kindType: 0,
          projectId: null,
          moduleId: null,
        }
      },
      // 下拉选项
      projectOptions: [],
      moduleOptions: []
    };
  },
  created() {
    // 处理路由参数
    this.handleRouteParams();
    this.getList();
    // 初始化项目下拉（仅加载当前用户相关项目：后端会做数据权限控制）
    this.initProjects();
  },
  methods: {
    async initProjects() {
      try {
        if (this.isProjectAdmin) {
          // 项目管理员：仅显示自己创建的项目
          const projRes = await listProject({ pageNum: 1, pageSize: 9999 })
          const owned = (projRes && Array.isArray(projRes.rows))
            ? projRes.rows.filter(p => String(p.ownerId) === String(this.currentUserId))
            : []
          this.projectOptions = owned.map(p => ({ projectId: p.projectId, projectName: p.projectName || (`项目#${p.projectId}`) }))
        } else {
          // 普通用户：根据“我的模块”推导可见项目
          const myModRes = await getMyModules({ pageNum: 1, pageSize: 9999 })
          const map = new Map()
          if (myModRes && Array.isArray(myModRes.rows)) {
            myModRes.rows.forEach(m => {
              if (m.projectId && !map.has(m.projectId)) {
                map.set(m.projectId, { projectId: m.projectId, projectName: m.projectName || (`项目#${m.projectId}`) })
              }
            })
          }
          // 注：普通用户可保留路由上下文补入，管理员不补入非本人项目
          if (this.currentContext.projectId && !map.has(this.currentContext.projectId)) {
            map.set(this.currentContext.projectId, { projectId: this.currentContext.projectId, projectName: this.currentContext.projectName || (`项目#${this.currentContext.projectId}`) })
          }
          this.projectOptions = Array.from(map.values())
        }

        // 如果之前没选过，按上下文预选（仅当选项中存在）
        if (!this.upload.meta.projectId && this.currentContext.projectId) {
          const exists = this.projectOptions.some(p => String(p.projectId) === String(this.currentContext.projectId))
          this.upload.meta.projectId = exists ? this.currentContext.projectId : null
        }
        if (this.upload.meta.projectId) {
          await this.handleProjectChange(this.upload.meta.projectId)
        } else {
          this.moduleOptions = []
          this.upload.meta.moduleId = null
        }
      } catch (e) {
        this.projectOptions = []
      }
    },
    /** 处理路由参数 */
    handleRouteParams() {
      const query = this.$route.query;
      console.log('路由参数:', query); // 调试信息
      
      if (query.pmodel_id) {
        this.currentContext.pmodel_id = query.pmodel_id;
        this.queryParams.pmodel_id = query.pmodel_id;
        this.upload.data.pmodel_id = query.pmodel_id;
      }
      if (query.kind_type !== undefined && query.kind_type !== null) {
        // 确保kind_type是数字类型
        this.currentContext.kind_type = parseInt(query.kind_type);
        this.queryParams.kind_type = parseInt(query.kind_type);
        this.upload.data.kind_type = parseInt(query.kind_type);
      }
      if (query.moduleName) {
        this.currentContext.moduleName = query.moduleName;
      }
      if (query.projectId) {
        // 统一为数字，避免 el-select 由于类型不一致显示原始ID
        this.currentContext.projectId = parseInt(query.projectId);
      }
      if (query.projectName) {
        this.currentContext.projectName = query.projectName;
      }
      if (query.view === 'true') {
        this.currentContext.isViewMode = true;
      }
      
      console.log('处理后的上下文:', this.currentContext); // 调试信息
    },
    handleKindTypeChange() {
      if (this.upload.meta.kindType === 0) {
        this.upload.meta.moduleId = null;
      }
    },
    async handleProjectChange(projectId) {
      this.upload.meta.moduleId = null;
      if (!projectId) { this.moduleOptions = []; return; }
      try {
        const currentUid = String(this.currentUserId)
        // 无论角色，上传模块文档都只允许当前用户为接取人（assignee）
        // 因此下拉仅展示“我为接取人”的模块，避免误选
        let rows = []
        if (!this.isProjectAdmin && this.isNormalUser) {
          const res = await getMyModules({ pageNum: 1, pageSize: 9999 })
          rows = res && Array.isArray(res.rows) ? res.rows : []
        } else {
          const res = await listModulesByProject(projectId)
          rows = res && Array.isArray(res.rows) ? res.rows : []
        }
        this.moduleOptions = rows
          .filter(m => String(m.projectId) === String(projectId))
          .filter(m => (m.assigneeId != null && String(m.assigneeId) === currentUid)
                    || (m.assignee && (String(m.assignee) === currentUid
                        || m.assignee === (this.$store.getters && this.$store.getters.name)
                        || m.assignee === (this.$store.getters && this.$store.getters.nickName))))
      } catch (e) {
        this.moduleOptions = []
      }
    },
    /** 查询文档列表 */
    async getList() {
      this.loading = true;
      // 构建查询参数（根据上下文映射pmodel_id -> projectId/moduleId）
      const query = { ...this.queryParams };
      if (!query.projectId && !query.moduleId && this.currentContext.pmodel_id) {
        if (this.currentContext.kind_type === 0) {
          query.projectId = this.currentContext.pmodel_id;
        } else if (this.currentContext.kind_type === 1) {
          query.moduleId = this.currentContext.pmodel_id;
        }
      }
      // 参数命名转换：kind_type -> kindType（后端为驼峰）
      if (query.kind_type !== undefined) {
        query.kindType = query.kind_type;
        delete query.kind_type;
      }
      try {
        const { rows, total } = await listDoc(query);
        this.docList = rows || [];
        this.total = total || 0;
      } catch (e) {
        console.error('获取文档列表失败', e);
        this.docList = [];
        this.total = 0;
      } finally {
        this.loading = false;
      }
    },
    /** 搜索按钮操作 */
    handleQuery() {
      this.queryParams.pageNum = 1;
      this.getList();
    },
    /** 重置按钮操作 */
    resetQuery() {
      this.resetForm("queryForm");
      this.handleQuery();
    },
    // 多选框选中数据
    handleSelectionChange(selection) {
      this.ids = selection.map(item => item.docId);
      this.multiple = !selection.length;
    },
    /** 上传按钮操作 */
    async handleUpload() {
      if (this.currentContext.moduleName) {
        this.uploadTitle = `上传文档 - ${this.currentContext.moduleName}`;
      } else {
        this.uploadTitle = "上传文档";
      }
      // 每次打开均刷新一次项目集合，避免角色/指派变更导致的偶发不显示
      await this.initProjects()
      // 普通用户默认选择“模块文档”，并禁用“项目文档”的单选
      if (this.isNormalUser && !this.isProjectAdmin) {
        this.upload.meta.kindType = 1
      }
      // 预选：优先使用路由上下文；否则选第一项
      if (this.currentContext.projectId) {
        this.upload.meta.projectId = this.currentContext.projectId
      } else {
        // 默认不选任何项目，避免显示成固定ID
        this.upload.meta.projectId = null
      }
      // initProjects 内已处理联动
      this.uploadOpen = true;
    },
    /** 下载按钮操作 */
    async handleDownload(row) {
      const url = process.env.VUE_APP_BASE_API + '/project/doc/download/' + row.docId
      try {
        const res = await fetch(url, { headers: { Authorization: 'Bearer ' + getToken() } })
        const contentType = res.headers.get('content-type') || ''
        if (contentType.includes('application/json')) {
          const j = await res.json()
          this.$message.error(j.msg || '下载失败')
          return
        }
        const blob = await res.blob()
        const a = document.createElement('a')
        a.href = window.URL.createObjectURL(blob)
        a.download = row.docName || 'file'
        document.body.appendChild(a)
        a.click()
        a.remove()
      } catch (e) {
        this.$message.error('下载失败')
      }
    },
    /** 删除按钮操作（支持单条与批量） */
    handleDelete(row) {
      const docIds = row && row.docId ? row.docId : (this.ids && this.ids.length ? this.ids.join(',') : '');
      if (!docIds) {
        this.$modal.msgError('请先选择要删除的文档');
        return;
      }
      this.$modal
        .confirm('是否确认删除文档编号为"' + docIds + '"的数据项？')
        .then(() => delDoc(docIds))
        .then(() => {
          this.$modal.msgSuccess('删除成功');
          this.getList();
          this.ids = [];
          this.multiple = true;
        })
        .catch(() => {});
    },
    // 文件上传中处理
    handleFileUploadProgress(event, file, fileList) {
      this.upload.isUploading = true;
    },
    // 文件上传成功处理
    handleFileSuccess(response, file, fileList) {
      this.upload.isUploading = false;
      // 按后端 code 判断
      if (response && typeof response.code !== 'undefined' && Number(response.code) !== 200) {
        this.$message.error(response.msg || '上传失败')
        return
      }
      // 统一成功提示
      const msg = (response && (response.msg || response.message)) || '上传成功'
      this.$message.success(msg)
      // 关闭弹窗、清空文件列表
      this.uploadOpen = false
      this.$nextTick(() => {
        try { this.$refs.upload && this.$refs.upload.clearFiles() } catch(e) {}
      })
      // 同步筛选条件为当前上传目标并即时刷新列表
      const { kindType, projectId, moduleId } = this.upload.meta
      this.queryParams.kind_type = kindType
      if (kindType === 1) {
        this.queryParams.moduleId = moduleId
        this.queryParams.projectId = null
      } else {
        this.queryParams.projectId = projectId
        this.queryParams.moduleId = null
      }
      this.queryParams.pageNum = 1
      // 即时刷新列表
      this.getList()
    },
    // 文件上传失败处理（网络/后端错误）
    handleFileError(err, file, fileList) {
      this.upload.isUploading = false;
      this.$message.error('上传失败：' + (err && (err.msg || err.message) || '网络错误'));
    },
    // 文件数超出限制
    handleFileExceed(files, fileList) {
      this.$message.warning('一次最多上传 1 个文件');
    },
    // 自定义上传请求：支持大文件进度与中断恢复（预留）
    async customHttpRequest(options) {
      const { file, onProgress, onSuccess, onError } = options
      // 直接透传给默认 xhr，但保留钩子可用于分片
      try {
        const form = new FormData()
        form.append('file', file)
        Object.keys(this.upload.data || {}).forEach(k => form.append(k, this.upload.data[k]))
        const xhr = new XMLHttpRequest()
        xhr.open('POST', this.upload.url, true)
        const headers = this.upload.headers || {}
        Object.keys(headers).forEach(k => xhr.setRequestHeader(k, headers[k]))
        xhr.upload.onprogress = function (evt) {
          if (evt.lengthComputable && typeof onProgress === 'function') {
            onProgress({ percent: Math.round((evt.loaded / evt.total) * 100) })
          }
        }
        xhr.onreadystatechange = () => {
          if (xhr.readyState === 4) {
            if (xhr.status >= 200 && xhr.status < 300) {
              try {
                const res = JSON.parse(xhr.responseText || '{}')
                onSuccess && onSuccess(res)
              } catch (e) {
                onSuccess && onSuccess({ msg: '上传成功' })
              }
            } else {
              onError && onError(new Error('HTTP ' + xhr.status))
            }
          }
        }
        xhr.send(form)
      } catch (e) {
        onError && onError(e)
      }
    },
    // 提交上传文件
    submitFileForm() {
      // 将选择的元数据同步到上传表单字段
      const { kindType, projectId, moduleId } = this.upload.meta;
      this.upload.data.kindType = kindType;
      this.upload.data.projectId = projectId;
      if (kindType === 1) {
        this.upload.data.moduleId = moduleId;
      } else {
        delete this.upload.data.moduleId;
      }
      // 简单校验
      if (!projectId) {
        this.$modal.msgError('请选择所属项目');
        return;
      }
      if (kindType === 1 && !moduleId) {
        this.$modal.msgError('请选择所属模块');
        return;
      }
      // 增加上传中状态，避免重复点击
      this.upload.isUploading = true
      this.$refs.upload.submit();
    }
  }
};
</script>