<template>
    <div class="contradiction-div">
        <div class="search-div">
            <Row type="flex">
                <Col span="4">
                    <span>计划名称：</span>
                    <Input v-model="filters.plan_name" clearable placeholder="请输入" style="width: 55%" />
                </Col>
                <Col span="4">
                    <span>风险等级：</span>
                    <Select v-model="filters.rating_type" clearable style="width: 55%" placeholder="请选择">
                        <Option v-for="opt in ratingTypeOptions" :key="opt.value" :value="opt.value">{{ opt.label }}</Option>
                    </Select>
                </Col>
                <Col span="4">
                    <span>部门类型：</span>
                    <Select v-model="filters.sys_type_office_value" clearable style="width: 55%" placeholder="请选择">
                        <Option v-for="opt in officeTypeOptions" :key="opt.value" :value="opt.value">{{ opt.label }}</Option>
                    </Select>
                </Col>
                <Col span="4">
                    <span>启用状态：</span>
                    <Select v-model="filters.status" clearable style="width: 55%" placeholder="请选择">
                        <Option v-for="opt in statusOptions" :key="opt.value" :value="opt.value">{{ opt.label }}</Option>
                    </Select>
                </Col>
                <Col style="text-align: right">
                    <Button type="primary" @click="search" style="margin-right: 10px">搜索</Button>
                    <Button type="primary" style="margin-right: 10px" @click="openAddModal">新增</Button>
                    <Button type="primary" @click="reset">重置</Button>
                </Col>
            </Row>
        </div>

        <Table border :loading="tableLoading" :columns="tableColumns" :data="tableData">
                <template slot-scope="{ row }" slot="rating_dict_type">
                    <span>{{ renderRatingDictType(row.rating_dict_type) }}</span>
                </template>
                <template slot-scope="{ row }" slot="sys_type_office_label">
                    <span>{{ row.sys_type_office_label || '-' }}</span>
                </template>
                <template slot-scope="{ row }" slot="rating_type">
                    <span>{{ renderRatingType(row.rating_type) }}</span>
                </template>
                <template slot-scope="{ row }" slot="status">
                    <span :style="{color: row.status==='1' ? '#19be6b' : '#ed4014'}">{{ renderStatus(row.status) }}</span>
                </template>
                <template slot-scope="{ row }" slot="visit_range">
                    <span>{{ (row.visit_start_day || '-') + '天 至 ' + (row.visit_end_day || '-') + '天' }}</span>
                </template>
                <template slot-scope="{ row }" slot="action">
                    <Button type="info" size="small" style="margin-right: 6px" @click="openEditModal(row)">修改</Button>
                    <Button v-if="row.status==='2'" type="success" size="small" style="margin-right: 6px" @click="toggleStatus(row, '1')">启用</Button>
                    <Button v-if="row.status==='1'" type="warning" size="small" style="margin-right: 6px" @click="toggleStatus(row, '2')">停用</Button>
                </template>
            </Table>
            <Page
                class="page_style"
                :total="params.totalRecord"
                :current="params.pageNo"
                :page-size="params.pageSize"
                show-total
                show-sizer
                @on-change="changePageNo"
                @on-page-size-change="size"
            />

        <Modal v-model="planModal.visible" :title="planModal.title" width="520" @on-visible-change="handleModalVisibleChange">
            <Form :model="planModel" ref="planForm" :rules="planRules" :label-width="100">
                <FormItem label="重点人员类别" prop="rating_dict_type">
                    <Input :value="renderRatingDictType(planModel.rating_dict_type)" disabled />
                </FormItem>
                <FormItem label="部门类型" prop="sys_type_office_value">
                    <Select v-model="planModel.sys_type_office_value" placeholder="请选择部门类型" @on-change="handleOfficeTypeChange">
                        <Option v-for="opt in officeTypeOptions" :key="opt.value" :value="opt.value">{{ opt.label }}</Option>
                    </Select>
                </FormItem>
                <FormItem label="计划名称" prop="plan_name">
                    <Input v-model="planModel.plan_name" placeholder="请输入计划名称" />
                </FormItem>
                <FormItem label="计划类别">
                    <Input v-model="planModel.plan_type" placeholder="请输入计划类别" />
                </FormItem>
                <FormItem label="风险等级" prop="rating_type">
                    <Select v-model="planModel.rating_type" placeholder="请选择">
                        <Option v-for="opt in ratingTypeOptions" :key="opt.value" :value="opt.value">{{ opt.label }}</Option>
                    </Select>
                </FormItem>
                <FormItem label="启用状态" prop="status">
                    <Select v-model="planModel.status" placeholder="请选择">
                        <Option v-for="opt in statusOptions" :key="opt.value" :value="opt.value">{{ opt.label }}</Option>
                    </Select>
                </FormItem>
                <FormItem label="循环天数" prop="visit_range" required>
                    <div style="display:flex; align-items:center; gap:8px;">
                        <InputNumber :min="1" v-model="planModel.visit_start_day" style="width: 100px" placeholder="起始天数" />
                        <span>天</span>
                        <span>至</span>
                        <InputNumber :min="1" v-model="planModel.visit_end_day" style="width: 100px" placeholder="结束天数" />
                        <span>天 回访一次</span>
                    </div>
                </FormItem>
                <FormItem label="临期预警天数" prop="overdue_warning_day" required>
                    <div style="display:flex; align-items:center; gap:8px;">
                        <span>距离截止日期剩余</span>
                        <InputNumber :min="1" v-model="planModel.overdue_warning_day" style="width: 100px" placeholder="请输入" />
                        <span>天，进行临期提醒</span>
                    </div>
                </FormItem>
            </Form>
            <div slot="footer">
                <Button @click="planModal.visible=false">取消</Button>
                <Button type="primary" :loading="planModal.submitting" @click="submitPlan">保存</Button>
            </div>
        </Modal>
    </div>
</template>
<script>
import {
  findPersonVisitList,
  saveKeyPersonVisit,
  updatePersonVisitStatus
} from '@/api/key-person'
import { getDictList } from '@/api/common'
export default {
  name: 'index',
  props: { category: { type: String, default: '' } },
  data () {
    return {
      tableLoading: false,
      tableData: [],
      ratingDictTypeOptions: [
        { label: '刑满释放人员', value: '2' },
        { label: '严重精神障碍患者', value: '3' },
        { label: '重点未成年人', value: '6' }
      ],
      ratingDictTypeMap: {},
      ratingTypeOptions: [],
      officeTypeOptions: [],
      statusOptions: [
        { label: '启用', value: '1' },
        { label: '停用', value: '2' }
      ],
      filters: {
        rating_dict_type: '',
        plan_name: '',
        rating_type: '',
        sys_type_office_value: '',
        status: ''
      },
      params: {
        pageNo: 1,
        pageSize: 10,
        totalRecord: 0
      },
      tableColumns: [
        { type: 'index', title: '序号', align: 'center', width: 80 },
        { title: '重点人员类别', slot: 'rating_dict_type', align: 'center' },
        { title: '部门类型', slot: 'sys_type_office_label', align: 'center', width: 120 },
        { title: '计划名称', key: 'plan_name', align: 'center' },
        { title: '计划类别', key: 'plan_type', align: 'center' },
        { title: '风险等级', slot: 'rating_type', align: 'center', width: 120 },
        { title: '启用状态', slot: 'status', align: 'center', width: 120 },
        { title: '循环天数', slot: 'visit_range', align: 'center', width: 220 },
        { title: '临期预警天数', key: 'overdue_warning_day', align: 'center', width: 140 },
        { title: '操作', slot: 'action', align: 'center', width: 220 }
      ],
      planModal: {
        visible: false,
        title: '新增回访计划',
        submitting: false
      },
      planModel: {
        id: '',
        rating_dict_type: '',
        sys_type_office_label: '',
        sys_type_office_value: '',
        plan_name: '',
        plan_type: '',
        rating_type: '',
        status: '2',
        visit_start_day: null,
        visit_end_day: null,
        overdue_warning_day: null
      },
      planRules: {
        rating_dict_type: [{ required: true, message: '请选择重点人员类别', trigger: 'change' }],
        sys_type_office_value: [{ required: true, message: '请选择部门类型', trigger: 'change' }],
        plan_name: [{ required: true, message: '请输入计划名称', trigger: 'blur' }],
        rating_type: [{ required: true, message: '请选择风险等级', trigger: 'change' }],
        status: [{ required: true, message: '请选择状态', trigger: 'change' }],
        visit_range: [
          { validator: (rule, value, callback) => {
            const s = this.planModel.visit_start_day
            const e = this.planModel.visit_end_day
            if (!s || !e) return callback(new Error('请填写起止天数'))
            if (!Number.isInteger(s) || s <= 0) return callback(new Error('起始天数需为正整数'))
            if (!Number.isInteger(e) || e <= 0) return callback(new Error('结束天数需为正整数'))
            if (s > e) return callback(new Error('起始天数不能大于结束天数'))
            callback()
          },
          trigger: 'change' }
        ],

        overdue_warning_day: [
          { validator: (rule, value, callback) => {
            const o = this.planModel.overdue_warning_day
            if (o == null || o === '') return callback(new Error('请输入临期预警天数'))
            if (!Number.isInteger(o) || o <= 0) return callback(new Error('临期预警天数需为正整数'))
            callback()
          },
          trigger: 'change' }
        ]
      }
    }
  },
  computed: {
    currentCategory () {
      const route = this.$route || {}
      const q = (route.query || {})
      const p = (route.params || {})
      const fromRoute = q.category || q.rating_dict_type || p.category || p.rating_dict_type || ''
      const fromProp = this.category || ''
      return String(fromProp || fromRoute || '')
    }
  },
  created () {
    this.filters.rating_dict_type = this.currentCategory || ''
    this.loadRatingLevelDict()
    this.loadOfficeTypeDict()
    this.init()
  },
  watch: {
    category () {
      this.applyDefaultCategory(true)
    },
    '$route.query.category' () {
      this.applyDefaultCategory(true)
    },
    '$route.query.rating_dict_type' () {
      this.applyDefaultCategory(true)
    }
  },
  methods: {
    applyDefaultCategory (triggerInit) {
      const cat = this.currentCategory || ''
      this.filters.rating_dict_type = cat
      this.planModel.rating_dict_type = cat
      if (triggerInit) this.changePageNo(1)
    },
    init () {
      this.tableLoading = true
      const enforcedFilters = Object.assign({}, this.filters, { rating_dict_type: this.currentCategory || this.filters.rating_dict_type || '' })
      const query = Object.assign({ params: enforcedFilters }, this.params)
      findPersonVisitList(query).then((ret) => {
        if (ret.data.errcode === 0) {
          this.params.totalRecord = ret.data.data.totalRecord
          this.tableData = ret.data.data.results
        } else {
          this.$Notice.error({ title: '查询失败！', desc: ret.data.errmsg })
        }
      }).finally(() => {
        this.tableLoading = false
      })
    },
    loadRatingLevelDict () {
      getDictList({ type: 'rating_level' }).then((ret) => {
        if (ret.data && ret.data.errcode === 0) {
          const results = ret.data.data && ret.data.data.results ? ret.data.data.results : []
          // ensure structure: [{ label, value }]
          this.ratingTypeOptions = results.map(it => ({ label: it.label || it.name, value: it.value || it.dictValue }))
        } else {
          this.$Notice.error({ title: '加载风险等级失败！', desc: (ret.data && ret.data.errmsg) || '' })
        }
      })
    },
    loadOfficeTypeDict () {
      getDictList({ type: 'sys_type_office' }).then((ret) => {
        if (ret.data && ret.data.errcode === 0) {
          const results = ret.data.data && ret.data.data.results ? ret.data.data.results : []
          // ensure structure: [{ label, value }]
          this.officeTypeOptions = results.map(it => ({ label: it.label || it.name, value: it.value || it.dictValue }))
        } else {
          this.$Notice.error({ title: '加载部门类型失败！', desc: (ret.data && ret.data.errmsg) || '' })
        }
      })
    },
    handleOfficeTypeChange (value) {
      const selected = this.officeTypeOptions.find(it => it.value === value)
      if (selected) {
        this.planModel.sys_type_office_label = selected.label
      } else {
        this.planModel.sys_type_office_label = ''
      }
    },
    search () {
      this.changePageNo(1)
    },
    reset () {
      this.filters.rating_dict_type = this.currentCategory || ''
      this.filters.plan_name = ''
      this.filters.rating_type = ''
      this.filters.sys_type_office_value = ''
      this.filters.status = ''
      this.changePageNo(1)
    },
    size (pageSize) {
      this.params.pageSize = pageSize
      this.changePageNo(1)
    },
    changePageNo (pageNo) {
      this.params.pageNo = pageNo
      this.init()
    },
    renderRatingDictType (val) {
      const found = this.ratingDictTypeOptions.find(it => String(it.value) === String(val))
      return found ? found.label : val || '-'
    },
    renderRatingType (val) {
      const found = this.ratingTypeOptions.find(it => it.value === val)
      return found ? found.label : val || '-'
    },
    renderStatus (val) {
      const found = this.statusOptions.find(it => it.value === val)
      return found ? found.label : val || '-'
    },
    handleModalVisibleChange (visible) {
      if (visible) {
        // 弹窗打开时，清除所有验证状态（字段值已在 openAddModal/openEditModal 中设置）
        this.$nextTick(() => {
          if (this.$refs.planForm && typeof this.$refs.planForm.resetFields === 'function') {
            // iView Form 的 resetFields 会清除验证状态，但会重置字段值
            // 为了不影响编辑模式的数据，这里只清除验证提示（通过移除错误类）
            const formItems = this.$refs.planForm.$el.querySelectorAll('.ivu-form-item-error')
            formItems.forEach(item => {
              item.classList.remove('ivu-form-item-error')
            })
          }
        })
      }
    },
    openAddModal () {
      this.planModal.title = '新增回访计划'
      // 确保从路由参数或props中获取最新的类别值（重新计算以确保获取最新值）
      const route = this.$route || {}
      const q = (route.query || {})
      const p = (route.params || {})
      const fromRoute = q.category || q.rating_dict_type || p.category || p.rating_dict_type || ''
      const fromProp = this.category || ''
      const category = String(fromProp || fromRoute || '')
      // 先重置表单数据，确保重点人员类别有值
      this.planModel = { id: '', rating_dict_type: category, sys_type_office_label: '', sys_type_office_value: '', plan_name: '', plan_type: '', rating_type: '', status: '2', visit_start_day: null, visit_end_day: null, overdue_warning_day: null }
      // 打开弹窗
      this.planModal.visible = true
      // 打开弹窗后清除验证，但保留重点人员类别值
      this.$nextTick(() => {
        if (this.$refs.planForm && typeof this.$refs.planForm.resetFields === 'function') {
          // 保存当前的重点人员类别值
          const savedCategory = this.planModel.rating_dict_type
          // 清除验证状态（resetFields 会重置字段值，所以需要重新设置）
          this.$refs.planForm.resetFields()
          // 重新设置重点人员类别，确保显示正确
          this.planModel.rating_dict_type = savedCategory || category
        }
      })
    },
    openEditModal (row) {
      this.planModal.title = '修改回访计划'
      // 先设置表单数据
      this.planModel = {
        id: row.id,
        rating_dict_type: row.rating_dict_type,
        sys_type_office_label: row.sys_type_office_label || '',
        sys_type_office_value: row.sys_type_office_value || '',
        plan_name: row.plan_name,
        plan_type: row.plan_type,
        rating_type: row.rating_type,
        status: row.status,
        visit_start_day: row.visit_start_day,
        visit_end_day: row.visit_end_day,
        overdue_warning_day: row.overdue_warning_day
      }
      // 打开弹窗前先清除验证（编辑模式不清除字段值，只清除验证状态）
      this.$nextTick(() => {
        if (this.$refs.planForm && this.$refs.planForm.$el) {
          // 手动清除验证提示（移除错误类）
          const formItems = this.$refs.planForm.$el.querySelectorAll('.ivu-form-item-error')
          if (formItems && formItems.length > 0) {
            formItems.forEach(item => {
              item.classList.remove('ivu-form-item-error')
            })
          }
        }
      })
      this.planModal.visible = true
    },
    submitPlan () {
      this.$refs['planForm'].validate((valid) => {
        if (!valid) return
        const doSave = () => {
          this.planModal.submitting = true
          const payload = Object.assign({}, this.planModel)
          saveKeyPersonVisit(payload).then((ret) => {
            if (ret.data.errcode === 0) {
              this.$Notice.success({ title: '保存成功' })
              this.planModal.visible = false
              this.init()
            } else {
              this.$Notice.error({ title: '保存失败！', desc: ret.data.errmsg })
            }
          }).finally(() => {
            this.planModal.submitting = false
          })
        }
        // 若设置为启用，需保证同一部门、同一类别、同一风险等级仅存在一个启用配置
        // 注意：允许同一组合存在多条记录，但只能有一条启用状态
        if (String(this.planModel.status) === '1') {
          const enabledParams = {
            params: {
              rating_dict_type: this.planModel.rating_dict_type || this.currentCategory || '',
              rating_type: this.planModel.rating_type,
              sys_type_office_value: this.planModel.sys_type_office_value,
              status: '1'
            },
            pageNo: 1,
            pageSize: 1
          }
          findPersonVisitList(enabledParams).then((ret2) => {
            if (ret2 && ret2.data && ret2.data.errcode === 0) {
              const enabledList = (ret2.data.data && ret2.data.data.results) || []
              const enabledExist = enabledList.find(it => String(it.id) !== String(this.planModel.id))
              if (enabledExist) {
                this.$Notice.error({ title: '保存失败！', desc: '同一部门、同一类别、同一风险等级已存在启用的回访计划，请先停用后再新增/启用。' })
                return
              }
              doSave()
            } else {
              doSave()
            }
          }).catch(() => { doSave() })
        } else {
          doSave()
        }
      })
    },
    toggleStatus (row, status) {
      // 若要启用，需确保同一部门、同一类别、同一风险等级没有其他启用项
      if (String(status) === '1') {
        const params = {
          params: {
            rating_dict_type: row.rating_dict_type,
            rating_type: row.rating_type,
            sys_type_office_value: row.sys_type_office_value,
            status: '1'
          },
          pageNo: 1,
          pageSize: 1
        }
        findPersonVisitList(params).then((ret) => {
          if (ret && ret.data && ret.data.errcode === 0) {
            const list = (ret.data.data && ret.data.data.results) || []
            const exist = list.find(it => String(it.id) !== String(row.id))
            if (exist) {
              this.$Notice.error({ title: '操作失败！', desc: '同一部门、同一类别、同一风险等级只能存在一个启用配置，请先停用已启用项。' })
              return
            }
            const payload = { id: row.id, status, rating_dict_type: row.rating_dict_type, rating_type: row.rating_type, sys_type_office_value: row.sys_type_office_value }
            updatePersonVisitStatus(payload).then((ret2) => {
              if (ret2.data.errcode === 0) {
                this.$Notice.success({ title: '操作成功' })
                this.init()
              } else {
                this.$Notice.error({ title: '操作失败！', desc: ret2.data.errmsg })
              }
            })
          } else {
            // 查询失败，兜底直接尝试操作（后端仍应校验）
            const payload = { id: row.id, status, rating_dict_type: row.rating_dict_type, rating_type: row.rating_type, sys_type_office_value: row.sys_type_office_value }
            updatePersonVisitStatus(payload).then((ret2) => {
              if (ret2.data.errcode === 0) {
                this.$Notice.success({ title: '操作成功' })
                this.init()
              } else {
                this.$Notice.error({ title: '操作失败！', desc: ret2.data.errmsg })
              }
            })
          }
        }).catch(() => {
          const payload = { id: row.id, status, rating_dict_type: row.rating_dict_type, rating_type: row.rating_type, sys_type_office_value: row.sys_type_office_value }
          updatePersonVisitStatus(payload).then((ret2) => {
            if (ret2.data.errcode === 0) {
              this.$Notice.success({ title: '操作成功' })
              this.init()
            } else {
              this.$Notice.error({ title: '操作失败！', desc: ret2.data.errmsg })
            }
          })
        })
        return
      }
      const payload = { id: row.id, status, rating_dict_type: row.rating_dict_type, rating_type: row.rating_type, sys_type_office_value: row.sys_type_office_value }
      updatePersonVisitStatus(payload).then((ret) => {
        if (ret.data.errcode === 0) {
          this.$Notice.success({ title: '操作成功' })
          this.init()
        } else {
          this.$Notice.error({ title: '操作失败！', desc: ret.data.errmsg })
        }
      })
    }
  }
}
</script>
<style scoped>
.contradiction-div {
  padding: 10px;
}
.contradiction-div .search-div { width: 100%; padding: 15px; border: 1px solid skyblue; background-color: azure; margin-bottom: 15px; }
.page_style {
  margin-top: 10px;
  text-align: right;
}

</style>
