package com.zksy.dispatch.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zksy.common.exception.ServiceException;
import com.zksy.common.utils.SecurityUtils;
import com.zksy.dispatch.domain.DisEvent;
import com.zksy.dispatch.domain.DisEventAssess;
import com.zksy.dispatch.dto.DisEventAssessSaveDTO;
import com.zksy.dispatch.mapper.DisEventAssessMapper;
import com.zksy.dispatch.mapper.DisEventMapper;
import com.zksy.dispatch.service.DisEventAssessService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.Collections;
import java.util.List;

/**
 * 事件事后评估 Service 实现
 */
@Slf4j
@Service
public class DisEventAssessServiceImpl extends ServiceImpl<DisEventAssessMapper, DisEventAssess>
        implements DisEventAssessService {

    @Autowired
    private DisEventMapper eventMapper;

    @Override
    public DisEventAssess findByEventId(Long eventId) {
        if (eventId == null) {
            return null;
        }
        List<DisEventAssess> list = list(new LambdaQueryWrapper<DisEventAssess>()
                .eq(DisEventAssess::getRelEventId, eventId)
                .orderByDesc(DisEventAssess::getId));
        return CollectionUtils.isEmpty(list) ? null : list.get(0);
    }

    @Override
    public List<DisEventAssess> listByEventIds(List<Long> eventIds) {
        if (CollectionUtils.isEmpty(eventIds)) {
            return Collections.emptyList();
        }
        return list(new LambdaQueryWrapper<DisEventAssess>()
                .in(DisEventAssess::getRelEventId, eventIds)
                .orderByDesc(DisEventAssess::getId));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public DisEventAssess saveAssess(DisEventAssessSaveDTO dto) {
        if (dto.getEventId() == null) {
            throw new ServiceException("事件ID不能为空");
        }
        DisEvent event = eventMapper.selectById(dto.getEventId());
        if (event == null) {
            throw new ServiceException("事件不存在：" + dto.getEventId());
        }
        LocalDateTime now = LocalDateTime.now();
        DisEventAssess db = findByEventId(dto.getEventId());
        boolean hasScore = dto.getOrgScore() != null || dto.getCapScore() != null
                || dto.getEffectScore() != null || dto.getLossScore() != null;
        if (db == null) {
            db = new DisEventAssess();
            db.setRelEventId(event.getId());
            db.setEventNo(event.getEventNo());
            db.setCreateTime(now);
            db.setCreateBy(currentUser());
            db.setDelFlag("0");
        }
        // 评分/评语非空才更新（录入案例库场景不覆盖已有评估）
        if (dto.getOrgScore() != null) {
            db.setOrgScore(dto.getOrgScore());
        }
        if (dto.getOrgComment() != null) {
            db.setOrgComment(dto.getOrgComment());
        }
        if (dto.getCapScore() != null) {
            db.setCapScore(dto.getCapScore());
        }
        if (dto.getCapComment() != null) {
            db.setCapComment(dto.getCapComment());
        }
        if (dto.getEffectScore() != null) {
            db.setEffectScore(dto.getEffectScore());
        }
        if (dto.getEffectComment() != null) {
            db.setEffectComment(dto.getEffectComment());
        }
        if (dto.getLossScore() != null) {
            db.setLossScore(dto.getLossScore());
        }
        if (dto.getLossComment() != null) {
            db.setLossComment(dto.getLossComment());
        }
        if (dto.getCaseFlag() != null) {
            db.setCaseFlag(dto.getCaseFlag());
        }
        // 有评分时计算综合分与等级
        if (hasScore) {
            BigDecimal total = calcTotal(db.getOrgScore(), db.getCapScore(),
                    db.getEffectScore(), db.getLossScore());
            db.setTotalScore(total);
            db.setGrade(calcGrade(total));
            db.setAssessor(currentUser());
            db.setAssessTime(now);
        }
        db.setUpdateTime(now);
        db.setUpdateBy(currentUser());
        saveOrUpdate(db);
        return db;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteByEventId(Long eventId) {
        if (eventId == null) {
            throw new ServiceException("事件ID不能为空");
        }
        DisEventAssess db = findByEventId(eventId);
        if (db != null) {
            removeById(db.getId());
        }
    }

    /**
     * 综合评分：四维平均，保留 1 位小数
     */
    private BigDecimal calcTotal(BigDecimal org, BigDecimal cap, BigDecimal effect, BigDecimal loss) {
        BigDecimal sum = nvl(org).add(nvl(cap)).add(nvl(effect)).add(nvl(loss));
        return sum.divide(BigDecimal.valueOf(4), 1, RoundingMode.HALF_UP);
    }

    private BigDecimal nvl(BigDecimal v) {
        return v == null ? BigDecimal.ZERO : v;
    }

    /**
     * 评价等级：>=4.5 优秀，>=3.5 良好，>=2.5 一般，其余较差
     */
    private String calcGrade(BigDecimal total) {
        if (total.compareTo(new BigDecimal("4.5")) >= 0) {
            return "优秀";
        }
        if (total.compareTo(new BigDecimal("3.5")) >= 0) {
            return "良好";
        }
        if (total.compareTo(new BigDecimal("2.5")) >= 0) {
            return "一般";
        }
        return "较差";
    }

    /**
     * 当前登录用户（未登录时返回系统）
     */
    private String currentUser() {
        try {
            return SecurityUtils.getUsername();
        } catch (Exception e) {
            return "system";
        }
    }
}
