<template>
  <module-page-shell title="项目总览">
    <div class="project-overview">
      <section class="stats-grid">
        <article v-for="card in summaryCards" :key="card.label" class="stats-card">
          <div class="stats-card__label">{{ card.label }}</div>
          <div class="stats-card__value">{{ card.value }}</div>
          <div class="stats-card__hint">{{ card.hint }}</div>
        </article>
      </section>

      <section class="overview-panel query-list-panel">
        <div class="overview-panel__header">
          <div>
            <h3>项目总览列表</h3>
          </div>
          <el-button type="primary" class="create-button" @click="handleAdd" v-hasPermi="['risk:project:add']">
            新建项目
          </el-button>
        </div>

        <div class="project-filter-bar">
          <div class="project-filter-bar__field project-filter-bar__field--keyword">
            <el-input
              v-model="queryParams.keyword"
              placeholder="项目编号/名称/负责人"
              clearable
              @keyup.enter.native="handleQuery"
            />
          </div>
          <div class="project-filter-bar__field project-filter-bar__field--narrow">
            <el-select v-model="queryParams.projectStatus" placeholder="全部" clearable>
              <el-option label="阶段：全部" value="" />
              <el-option
                v-for="item in stageOptions"
                :key="item.value"
                :label="item.label"
                :value="item.value"
              />
            </el-select>
          </div>
          <div class="project-filter-bar__field project-filter-bar__field--date">
            <el-date-picker
              v-model="queryParams.dueDate"
              class="project-date-picker"
              type="date"
              value-format="yyyy-MM-dd"
              placeholder="年 / 月 / 日"
            />
          </div>
          <div class="project-filter-bar__actions">
            <el-button type="primary" class="project-filter-bar__button" @click="handleQuery">查询</el-button>
            <el-button class="project-filter-bar__button" @click="resetQuery">重置</el-button>
          </div>
        </div>

        <el-table
          v-loading="loading"
          :data="pagedProjects"
          class="overview-table"
          :header-cell-style="{ textAlign: 'center' }"
          :cell-style="{ textAlign: 'center' }"
        >
          <el-table-column label="项目编号" prop="projectCode" min-width="160" />
          <el-table-column label="项目名称" prop="projectName" min-width="250" show-overflow-tooltip />
          <el-table-column label="负责人" prop="projectManager" min-width="100" />
          <el-table-column label="阶段" min-width="120">
            <template slot-scope="scope">
              <el-tag class="stage-tag" :class="stageToneClass(scope.row.projectStatus)" effect="plain" size="small">
                {{ stageLabel(scope.row.projectStatus) }}
              </el-tag>
            </template>
          </el-table-column>
          <el-table-column label="资料完整度" min-width="140">
            <template slot-scope="scope">
              {{ buildProgressSnapshot(scope.row).materialText }}
            </template>
          </el-table-column>
          <el-table-column label="任务完成" min-width="120">
            <template slot-scope="scope">
              {{ buildProgressSnapshot(scope.row).taskText }}
            </template>
          </el-table-column>
          <el-table-column label="操作" min-width="500" fixed="right">
            <template slot-scope="scope">
              <div class="operation-group">
                <el-button type="primary" size="mini" @click="handleDetail(scope.row)">查看详情</el-button>
                <el-button size="mini" @click="goToProjectModule(scope.row, 'material')">资料上传</el-button>
                <el-button size="mini" @click="goToProjectModule(scope.row, 'task')">任务下发</el-button>
                <el-button size="mini" @click="goToProjectModule(scope.row, 'progress')">进度跟踪</el-button>
                <el-button size="mini" @click="goToProjectModule(scope.row, 'score')">评分汇总</el-button>
                <el-button size="mini" @click="goToProjectModule(scope.row, 'report')">报告导出</el-button>
              </div>
            </template>
          </el-table-column>
        </el-table>

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

      <el-dialog
        :visible.sync="formOpen"
        width="860px"
        top="7vh"
        append-to-body
        :close-on-click-modal="false"
        custom-class="project-dialog"
      >
        <span slot="title" class="dialog-title">{{ formTitle }}</span>
        <el-form ref="projectForm" :model="form" :rules="rules" label-position="top" class="project-form">
          <el-form-item label="项目编号" prop="projectCode">
            <el-input v-model="form.projectCode" placeholder="请输入项目编号" />
          </el-form-item>
          <el-form-item label="项目名称" prop="projectName">
            <el-input v-model="form.projectName" placeholder="请输入项目名称" />
          </el-form-item>
          <el-form-item label="负责人" prop="projectManager">
            <el-input v-model="form.projectManager" placeholder="请输入负责人" />
          </el-form-item>
          <el-form-item label="项目阶段" prop="projectStatus">
            <el-select v-model="form.projectStatus" placeholder="请选择项目阶段" style="width: 100%">
              <el-option
                v-for="item in stageOptions"
                :key="item.value"
                :label="item.label"
                :value="item.value"
              />
            </el-select>
          </el-form-item>
          <el-form-item label="计划完成日期" prop="dueDate">
            <el-date-picker
              v-model="form.dueDate"
              class="project-date-picker"
              type="date"
              value-format="yyyy-MM-dd"
              placeholder="年 / 月 / 日"
              style="width: 100%"
            />
          </el-form-item>
          <el-form-item label="项目概述" prop="remark">
            <el-input
              v-model="form.remark"
              type="textarea"
              :rows="4"
              placeholder="描述投资背景、资料来源、已识别风险点"
            />
          </el-form-item>
        </el-form>
        <div slot="footer" class="dialog-footer">
          <el-button @click="formOpen = false">取消</el-button>
          <el-button @click="handleFormReset">清空</el-button>
          <el-button type="primary" @click="submitForm">{{ submitButtonText }}</el-button>
        </div>
      </el-dialog>

      <el-dialog
        title="项目详情"
        :visible.sync="detailOpen"
        width="980px"
        top="4vh"
        append-to-body
        custom-class="project-detail-dialog"
      >
        <div v-if="detailProject" class="detail-content">
          <div class="detail-field">
            <span class="detail-field__label">项目编号</span>
            <span class="detail-field__value">{{ detailProject.projectCode }}</span>
          </div>
          <div class="detail-field">
            <span class="detail-field__label">项目名称</span>
            <span class="detail-field__value">{{ detailProject.projectName }}</span>
          </div>
          <div class="detail-field">
            <span class="detail-field__label">负责人</span>
            <span class="detail-field__value">{{ detailProject.projectManager || '--' }}</span>
          </div>
          <div class="detail-field">
            <span class="detail-field__label">截止时间</span>
            <span class="detail-field__value">{{ detailProject.dueDate || '--' }}</span>
          </div>
          <div class="detail-field">
            <span class="detail-field__label">当前阶段</span>
            <span class="detail-field__value">
              <el-tag class="stage-tag" :class="stageToneClass(detailProject.projectStatus)" effect="plain" size="small">
                {{ stageLabel(detailProject.projectStatus) }}
              </el-tag>
            </span>
          </div>
          <div class="detail-field">
            <span class="detail-field__label">风险状态</span>
            <span class="detail-field__value">{{ riskText(detailProject.riskLevel) }}</span>
          </div>
          <div class="detail-field detail-field--block">
            <span class="detail-field__label">项目概述</span>
            <span class="detail-field__value">{{ detailProject.remark || '暂无项目概述' }}</span>
          </div>

          <div class="detail-section">
            <div class="detail-section__title">资料概况</div>
            <el-table :data="detailMaterials" border>
              <el-table-column label="资料类型" prop="materialType" min-width="160" />
              <el-table-column label="已上传/应上传" prop="uploadText" min-width="160" />
              <el-table-column label="完成率" prop="completion" min-width="120" />
            </el-table>
          </div>

          <div class="detail-section">
            <div class="detail-section__title">任务概况</div>
            <el-table :data="detailTasks" border>
              <el-table-column label="评估项" prop="taskName" min-width="180" />
              <el-table-column label="评估师" prop="owner" min-width="160" />
              <el-table-column label="状态" prop="status" min-width="120" />
              <el-table-column label="评分" prop="score" min-width="100" />
            </el-table>
          </div>
        </div>
        <div slot="footer" class="dialog-footer">
          <el-button @click="detailOpen = false">关闭</el-button>
          <el-button type="primary" @click="openEditFromDetail" v-hasPermi="['risk:project:edit']">编辑项目</el-button>
        </div>
      </el-dialog>
    </div>
  </module-page-shell>
</template>

<script>
import ModulePageShell from '@/components/ModulePageShell'
import { parseTime } from '@/utils/ruoyi'
import { addProject, getProject, listProject, updateProject } from '@/api/risk/project'
import { RISK_LEVEL_OPTIONS, findOptionLabel } from '@/views/risk/config'

const FETCH_LIMIT = 1000

const STAGE_OPTIONS = [
  { value: '0', label: '项目发起' },
  { value: '1', label: '任务下发' },
  { value: '2', label: '资料收集' },
  { value: '3', label: '结果汇总' },
  { value: '4', label: '报告产出' }
]

const MATERIAL_TEMPLATES = [
  { materialType: '行业资料', total: 5, offset: 0.00 },
  { materialType: '财务资料', total: 4, offset: 0.18 },
  { materialType: '法务资料', total: 4, offset: -0.08 },
  { materialType: '担保品资料', total: 3, offset: -0.03 },
  { materialType: '其他资料', total: 2, offset: -0.12 }
]

const TASK_TEMPLATES = [
  { taskName: '行业风险评估', startStage: 1 },
  { taskName: '财务合规审查', startStage: 2 },
  { taskName: '综合风险结论', startStage: 3 }
]

export default {
  name: 'RiskProjectOverview',
  components: {
    ModulePageShell
  },
  data() {
    return {
      loading: false,
      stageOptions: STAGE_OPTIONS,
      riskLevelOptions: RISK_LEVEL_OPTIONS,
      allProjects: [],
      queryParams: {
        pageNum: 1,
        pageSize: 10,
        keyword: '',
        projectStatus: '',
        dueDate: ''
      },
      formOpen: false,
      detailOpen: false,
      formMode: 'add',
      formSeed: {},
      form: {},
      detailProject: null,
      rules: {
        projectCode: [{ required: true, message: '项目编号不能为空', trigger: 'blur' }],
        projectName: [{ required: true, message: '项目名称不能为空', trigger: 'blur' }],
        projectManager: [{ required: true, message: '负责人不能为空', trigger: 'blur' }],
        projectStatus: [{ required: true, message: '项目阶段不能为空', trigger: 'change' }]
      }
    }
  },
  computed: {
    summaryCards() {
      const total = this.allProjects.length
      const active = this.allProjects.filter(item => ['1', '2', '3'].includes(item.projectStatus)).length
      const completed = this.allProjects.filter(item => item.projectStatus === '4').length
      const highRisk = this.allProjects.filter(item => item.riskLevel === '3').length
      return [
        { label: '项目总数', value: total, hint: '全部项目' },
        { label: '进行中项目', value: active, hint: '阶段：任务下发-结果汇总' },
        { label: '已完成项目', value: completed, hint: '阶段：报告产出' },
        { label: '高风险项目', value: highRisk, hint: '需优先关注' }
      ]
    },
    filteredProjects() {
      const keyword = (this.queryParams.keyword || '').trim().toLowerCase()
      const projectStatus = this.queryParams.projectStatus
      const dueDate = this.queryParams.dueDate

      return this.allProjects.filter(item => {
        const matchKeyword = !keyword || [
          item.projectCode,
          item.projectName,
          item.projectManager
        ].some(field => `${field || ''}`.toLowerCase().includes(keyword))

        const matchStatus = !projectStatus || `${item.projectStatus}` === `${projectStatus}`
        const matchDate = !dueDate || item.dueDate === dueDate
        return matchKeyword && matchStatus && matchDate
      })
    },
    filteredTotal() {
      return this.filteredProjects.length
    },
    pagedProjects() {
      const start = (this.queryParams.pageNum - 1) * this.queryParams.pageSize
      const end = start + this.queryParams.pageSize
      return this.filteredProjects.slice(start, end)
    },
    formTitle() {
      return this.formMode === 'edit' ? '编辑项目' : '新建项目'
    },
    submitButtonText() {
      return this.formMode === 'edit' ? '保存修改' : '新建项目'
    },
    detailMaterials() {
      return this.detailProject ? this.buildMaterialRows(this.detailProject) : []
    },
    detailTasks() {
      return this.detailProject ? this.buildTaskRows(this.detailProject) : []
    }
  },
  watch: {
    filteredTotal() {
      this.ensurePageWithinRange()
    }
  },
  created() {
    this.fetchProjects()
  },
  methods: {
    fetchProjects() {
      this.loading = true
      listProject({ pageNum: 1, pageSize: FETCH_LIMIT }).then(response => {
        const rows = response.rows || []
        this.allProjects = rows.map(item => this.normalizeProject(item))
        this.ensurePageWithinRange()
        this.loading = false
      }).catch(() => {
        this.loading = false
      })
    },
    normalizeProject(project) {
      return {
        projectId: project.projectId,
        projectCode: project.projectCode || '',
        projectName: project.projectName || '',
        projectType: `${project.projectType || '1'}`,
        orgName: project.orgName || '',
        clientName: project.clientName || '',
        projectManager: project.projectManager || '',
        assessor: project.assessor || '',
        riskLevel: `${project.riskLevel || '2'}`,
        projectStatus: `${project.projectStatus || '0'}`,
        dueDate: this.normalizeDate(project.dueDate),
        remark: project.remark || ''
      }
    },
    normalizeDate(value) {
      if (!value) {
        return ''
      }
      if (typeof value === 'string') {
        return value.slice(0, 10).replace(/\//g, '-')
      }
      return parseTime(value, '{y}-{m}-{d}')
    },
    cloneProject(project) {
      return JSON.parse(JSON.stringify(project))
    },
    buildNextProjectCode() {
      const year = new Date().getFullYear()
      const suffixes = this.allProjects.map(item => {
        const match = `${item.projectCode || ''}`.match(/(\d{3,4})$/)
        return match ? Number(match[1]) : 0
      })
      const nextNumber = Math.max(401, ...suffixes) + 1
      return `PJT-${year}-${String(nextNumber).padStart(4, '0')}`
    },
    createDefaultForm() {
      return {
        projectId: undefined,
        projectCode: this.buildNextProjectCode(),
        projectName: '',
        projectManager: '',
        projectStatus: '0',
        dueDate: '',
        remark: '',
        projectType: '1',
        orgName: '',
        clientName: '',
        assessor: '',
        riskLevel: '2'
      }
    },
    handleQuery() {
      this.queryParams.pageNum = 1
    },
    handlePagination() {
      this.ensurePageWithinRange()
    },
    resetQuery() {
      this.queryParams = {
        pageNum: 1,
        pageSize: 10,
        keyword: '',
        projectStatus: '',
        dueDate: ''
      }
    },
    ensurePageWithinRange() {
      const maxPage = Math.max(1, Math.ceil(this.filteredTotal / this.queryParams.pageSize) || 1)
      if (this.queryParams.pageNum > maxPage) {
        this.queryParams.pageNum = maxPage
      }
    },
    stageLabel(value) {
      return findOptionLabel(this.stageOptions, value)
    },
    riskText(value) {
      const label = findOptionLabel(this.riskLevelOptions, value)
      return label === '--' ? '待评估' : `${label}风险`
    },
    stageToneClass(value) {
      return `stage-tag--${value}`
    },
    buildMaterialRows(project) {
      const projectId = Number(project.projectId || 0)
      const stageIndex = Math.min(Number(project.projectStatus || 0), 4)
      const progressBase = [0.12, 0.34, 0.67, 0.88, 1][stageIndex]
      return MATERIAL_TEMPLATES.map((item, index) => {
        const wave = ((projectId + index) % 3 - 1) * 0.04
        const ratio = Math.max(0, Math.min(1, progressBase + item.offset + wave))
        let uploaded = Math.round(item.total * ratio)
        if (stageIndex > 0) {
          uploaded = Math.max(1, uploaded)
        }
        uploaded = Math.min(item.total, uploaded)
        const percent = item.total ? Math.round((uploaded / item.total) * 100) : 0
        return {
          materialType: item.materialType,
          uploadText: `${uploaded}/${item.total}`,
          completion: `${percent}%`,
          uploaded,
          total: item.total
        }
      })
    },
    buildTaskRows(project) {
      const projectId = Number(project.projectId || 0)
      const stageIndex = Math.min(Number(project.projectStatus || 0), 4)
      const primaryOwner = project.assessor || project.projectManager || '评估师A'
      const fallbackOwners = [primaryOwner, '风控复核组', '报告专员']

      return TASK_TEMPLATES.map((item, index) => {
        let status = '待启动'
        if (stageIndex >= item.startStage) {
          status = stageIndex > item.startStage || stageIndex === 4 ? '已完成' : '进行中'
        }
        return {
          taskName: item.taskName,
          owner: fallbackOwners[index],
          status,
          score: status === '已完成' ? `${82 + ((projectId + index) % 11)}` : '-'
        }
      })
    },
    buildProgressSnapshot(project) {
      const materialRows = this.buildMaterialRows(project)
      const taskRows = this.buildTaskRows(project)
      const uploaded = materialRows.reduce((sum, item) => sum + item.uploaded, 0)
      const total = materialRows.reduce((sum, item) => sum + item.total, 0)
      const materialPercent = total ? Math.round((uploaded / total) * 100) : 0
      const completedTasks = taskRows.filter(item => item.status === '已完成').length
      return {
        materialText: `${uploaded}/${total} (${materialPercent}%)`,
        taskText: `${completedTasks}/${taskRows.length}`
      }
    },
    handleAdd() {
      this.formMode = 'add'
      this.formSeed = this.createDefaultForm()
      this.form = this.cloneProject(this.formSeed)
      this.formOpen = true
      this.$nextTick(() => {
        if (this.$refs.projectForm) {
          this.$refs.projectForm.clearValidate()
        }
      })
    },
    handleFormReset() {
      this.form = this.cloneProject(this.formSeed)
      this.$nextTick(() => {
        if (this.$refs.projectForm) {
          this.$refs.projectForm.clearValidate()
        }
      })
    },
    handleDetail(row) {
      getProject(row.projectId).then(response => {
        this.detailProject = this.normalizeProject(response.data || {})
        this.detailOpen = true
      })
    },
    handleEdit(row) {
      getProject(row.projectId).then(response => {
        this.formMode = 'edit'
        this.formSeed = this.normalizeProject(response.data || {})
        this.form = this.cloneProject(this.formSeed)
        this.formOpen = true
        this.$nextTick(() => {
          if (this.$refs.projectForm) {
            this.$refs.projectForm.clearValidate()
          }
        })
      })
    },
    openEditFromDetail() {
      if (!this.detailProject) {
        return
      }
      this.detailOpen = false
      this.handleEdit(this.detailProject)
    },
    goToProjectModule(row, module) {
      const routeMap = {
        material: '/project/material',
        task: '/project/task',
        progress: '/project/progress',
        score: '/project/score',
        report: '/project/report'
      }
      const path = routeMap[module]
      if (!path) {
        return
      }
      this.$router.push({
        path,
        query: {
          projectName: row.projectName || ''
        }
      })
    },
    buildSubmitPayload() {
      const payload = this.cloneProject(this.form)
      payload.projectCode = (payload.projectCode || '').trim()
      payload.projectName = (payload.projectName || '').trim()
      payload.projectManager = (payload.projectManager || '').trim()
      payload.projectStatus = `${payload.projectStatus || '0'}`
      payload.projectType = payload.projectType || '1'
      payload.riskLevel = payload.riskLevel || '2'
      payload.orgName = payload.orgName || '项目管理部'
      payload.clientName = payload.clientName || payload.projectName
      payload.assessor = payload.assessor || '评估组'
      payload.remark = (payload.remark || '').trim()
      return payload
    },
    submitForm() {
      this.$refs.projectForm.validate(valid => {
        if (!valid) {
          return
        }
        const payload = this.buildSubmitPayload()
        const request = payload.projectId ? updateProject(payload) : addProject(payload)
        request.then(() => {
          this.$message.success(payload.projectId ? '项目修改成功' : '项目新建成功')
          this.formOpen = false
          this.fetchProjects()
        })
      })
    }
  }
}
</script>

<style lang="scss" scoped>
@import "~@/styles/project-filter-bar.scss";
@import "~@/styles/query-list-panel.scss";

.project-overview {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.stats-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 14px;
}

.stats-card,
.overview-panel {
  border: 1px solid #e4e8ef;
  border-radius: 8px;
  background: #fff;
}

.stats-card {
  padding: 18px 20px 14px;
}

.stats-card__label {
  color: #667085;
  font-size: 14px;
}

.stats-card__value {
  margin-top: 8px;
  font-size: 42px;
  line-height: 1;
  font-weight: 700;
  color: #1f2937;
}

.stats-card__hint {
  margin-top: 8px;
  color: #98a2b3;
  font-size: 13px;
}

.overview-panel {
  padding: 14px 16px 16px;
}

.overview-panel__header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 16px;
  margin-bottom: 14px;
}

.overview-panel__header h3 {
  margin: 0;
  font-size: 16px;
  color: #2f3542;
}

.overview-panel__header p {
  margin: 8px 0 0;
  font-size: 13px;
  color: #98a2b3;
}

.create-button {
  min-width: 88px;
}

.project-overview .project-filter-bar__field--keyword {
  flex: 0 1 300px;
  max-width: 340px;
  min-width: 220px;
}

.overview-table {
  margin-bottom: 12px;
}

.operation-group {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  justify-content: center;
}

.stage-tag {
  border-radius: 999px;
  padding: 0 10px;
}

.stage-tag--0 {
  color: #6b7280;
  border-color: #d1d5db;
  background: #f3f4f6;
}

.stage-tag--1 {
  color: #1677ff;
  border-color: #bfdbfe;
  background: #eff6ff;
}

.stage-tag--2 {
  color: #0f766e;
  border-color: #99f6e4;
  background: #ecfeff;
}

.stage-tag--3 {
  color: #16a34a;
  border-color: #bbf7d0;
  background: #f0fdf4;
}

.stage-tag--4 {
  color: #ca8a04;
  border-color: #fde68a;
  background: #fffbeb;
}

.dialog-title {
  font-size: 16px;
  font-weight: 700;
  color: #1f2937;
}

.project-form ::v-deep .el-form-item {
  margin-bottom: 14px;
}

.detail-content {
  display: flex;
  flex-direction: column;
  gap: 10px;
  max-height: 70vh;
  overflow-y: auto;
  padding-right: 4px;
}

.detail-field,
.detail-section {
  border: 1px solid #e4e8ef;
  border-radius: 6px;
  background: #fff;
}

.detail-field {
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 42px;
  padding: 10px 14px;
}

.detail-field--block {
  align-items: flex-start;
}

.detail-field__label {
  min-width: 84px;
  color: #111827;
  font-weight: 600;
}

.detail-field__value {
  color: #374151;
  line-height: 1.6;
}

.detail-section {
  padding: 12px;
}

.detail-section__title {
  margin-bottom: 10px;
  font-weight: 600;
  color: #111827;
}

@media screen and (max-width: 1280px) {
  .stats-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media screen and (max-width: 768px) {
  .stats-grid {
    grid-template-columns: 1fr;
  }

  .overview-panel__header {
    flex-direction: column;
    align-items: stretch;
  }

  .create-button {
    width: 100%;
  }
}
</style>
