package com.kingdee.eas.custom.integration.perf.service.impl;

import com.kingdee.bos.BOSException;
import com.kingdee.bos.Context;
import com.kingdee.bos.dao.ormapping.ObjectUuidPK;
import com.kingdee.eas.basedata.person.IPerson;
import com.kingdee.eas.basedata.person.PersonFactory;
import com.kingdee.eas.basedata.person.PersonInfo;
import com.kingdee.eas.common.EASBizException;
import com.kingdee.eas.custom.compensation.PerfEvalSyncCollection;
import com.kingdee.eas.custom.compensation.PerfEvalSyncFactory;
import com.kingdee.eas.custom.compensation.PerfEvalSyncInfo;
import com.kingdee.eas.custom.compensation.IPerfEvalSync;
import com.kingdee.eas.custom.compensation.bizEnum.SyncStatusEnum;
import com.kingdee.eas.custom.integration.base.util.SHRApiUtils;
import com.kingdee.eas.custom.integration.beisen.dto.FailDetail;
import com.kingdee.eas.custom.integration.perf.dto.BatchPerfEvalSyncRequest;
import com.kingdee.eas.custom.integration.perf.dto.PerfEvalSyncRequest;
import com.kingdee.eas.custom.integration.perf.dto.PerfEvalSyncResponse;
import com.kingdee.eas.custom.integration.perf.exception.PerfErrorCodes;
import com.kingdee.eas.custom.integration.perf.exception.PerfIntegrationException;
import com.kingdee.eas.custom.integration.perf.service.PerfEvalSyncService;
import com.kingdee.eas.custom.integration.perf.validator.PerfEvalSyncValidator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 绩效考评结果同步服务实现。
 * 以工号+年月为唯一键写入 PerfEvalSync 实体，存在且状态为暂存则更新，不存在则新增。
 * 已审批状态的数据不允许更新。并发安全依赖数据库层 number 唯一约束。
 */
@Service
public class PerfEvalSyncServiceImpl implements PerfEvalSyncService {

    private static final Logger logger = LoggerFactory.getLogger(PerfEvalSyncServiceImpl.class);

    @Override
    public PerfEvalSyncResponse writePerfEvalSync(BatchPerfEvalSyncRequest request) {
        List<PerfEvalSyncRequest> records = request.getRecords();
        logger.info("开始处理绩效考评结果同步 - 记录数: {}", records != null ? records.size() : 0);
        PerfEvalSyncResponse response = new PerfEvalSyncResponse();

        if (records == null || records.isEmpty()) {
            logger.warn("绩效考评结果同步 - 记录列表为空");
            return response;
        }

        Context ctx;
        try {
            ctx = SHRApiUtils.getContext();
        } catch (Exception e) {
            logger.error("无法获取 BOS Context", e);
            response.setTotalCount(records.size()); response.setFailCount(records.size());
            for (PerfEvalSyncRequest r : records)
                response.addFailDetail(new FailDetail(r.getPersonNumber() + "_" + r.getYearMonth(), "无法获取 BOS Context"));
            return response;
        }

        try {
            IPerson iPerson = PersonFactory.getLocalInstance(ctx);
            IPerfEvalSync iPerf = PerfEvalSyncFactory.getLocalInstance(ctx);
            Map<String, PerfEvalSyncInfo> existingMap = loadExistingMap(iPerf);

            int totalCount = records.size(), successCount = 0, failCount = 0;

            for (PerfEvalSyncRequest record : records) {
                String bizId = record.getPersonNumber() + "_" + record.getYearMonth();
                try {
                    String err = PerfEvalSyncValidator.validateAndGetError(record);
                    if (err != null) { failCount++; response.addFailDetail(new FailDetail(bizId, "校验失败: " + err)); continue; }

                    PersonInfo person = iPerson.getPersonByStr("number", record.getPersonNumber());
                    if (person == null) { failCount++; response.addFailDetail(new FailDetail(bizId, "sHR系统中不存在工号为" + record.getPersonNumber() + "的人员")); continue; }

                    PerfEvalSyncInfo existing = existingMap.get(bizId);
                    if (existing != null) {
                        if (existing.getState() != SyncStatusEnum.SAVED) {
                            failCount++; response.addFailDetail(new FailDetail(bizId, "数据状态为" + existing.getState().getAlias() + "，仅暂存状态可更新")); continue;
                        }
                        applyUpdate(existing, record, person);
                        iPerf.update(new ObjectUuidPK(existing.getId()), existing);
                        existingMap.put(bizId, existing); successCount++;
                        logger.info("绩效考评更新成功 - bizId: {}", bizId);
                    } else {
                        PerfEvalSyncInfo info = new PerfEvalSyncInfo(); info.setNumber(bizId);
                        applyUpdate(info, record, person); info.setState(SyncStatusEnum.SAVED);
                        tryAddnewOrUpdate(iPerf, existingMap, bizId, info, record, person);
                        successCount++;
                        logger.info("绩效考评新增成功 - bizId: {}", bizId);
                    }
                } catch (Exception e) {
                    failCount++; response.addFailDetail(new FailDetail(bizId, e.getMessage() != null ? e.getMessage() : "未知错误"));
                }
            }
            response.setTotalCount(totalCount); response.setSuccessCount(successCount); response.setFailCount(failCount);
            logger.info("绩效考评同步完成 - 总数: {}, 成功: {}, 失败: {}", totalCount, successCount, failCount);
        } catch (BOSException e) {
            throw new PerfIntegrationException(PerfErrorCodes.SAVE_ERROR, "数据保存失败: " + e.getMessage(), e);
        }
        return response;
    }

    private Map<String, PerfEvalSyncInfo> loadExistingMap(IPerfEvalSync iPerf) throws BOSException {
        Map<String, PerfEvalSyncInfo> map = new HashMap<>();
        PerfEvalSyncCollection col = iPerf.getPerfEvalSyncCollection();
        if (col != null) for (int i = 0; i < col.size(); i++) {
            PerfEvalSyncInfo info = col.get(i);
            if (info.getNumber() != null) map.put(info.getNumber(), info);
        }
        return map;
    }

    private void tryAddnewOrUpdate(IPerfEvalSync iPerf, Map<String, PerfEvalSyncInfo> existingMap,
                                    String bizId, PerfEvalSyncInfo info, PerfEvalSyncRequest record,
                                    PersonInfo person) throws BOSException, EASBizException {
        try {
            iPerf.addnew(info); existingMap.put(bizId, info);
        } catch (BOSException | EASBizException e) {
            PerfEvalSyncInfo existing = findByNumber(iPerf, bizId);
            if (existing != null) {
                if (existing.getState() != SyncStatusEnum.SAVED)
                    throw new PerfIntegrationException(PerfErrorCodes.UPDATE_NOT_ALLOWED, "数据状态非暂存，不可更新: " + bizId);
                applyUpdate(existing, record, person);
                iPerf.update(new ObjectUuidPK(existing.getId()), existing);
                existingMap.put(bizId, existing);
                logger.info("并发回退更新 - bizId: {}", bizId);
            } else { throw e; }
        }
    }

    private PerfEvalSyncInfo findByNumber(IPerfEvalSync iPerf, String number) throws BOSException {
        PerfEvalSyncCollection col = iPerf.getPerfEvalSyncCollection("where number = '" + number.replace("'", "''") + "'");
        return (col != null && !col.isEmpty()) ? col.get(0) : null;
    }

    private void applyUpdate(PerfEvalSyncInfo info, PerfEvalSyncRequest record, PersonInfo person) {
        info.setPerson(person);
        info.setYearMonth(record.getYearMonth());
        info.setComplaintFineAmount(record.getPerfCoeff());
    }
}
