package com.hxhq.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hxhq.common.EntityConstants;
import com.hxhq.domain.Instrument;
import com.hxhq.domain.InstrumentPush;
import com.hxhq.domain.SyncLog;
import com.hxhq.domain.Yq;
import com.hxhq.dto.InstrumentPushDTO;
import com.hxhq.mapper.InstrumentMapper;
import com.hxhq.service.InstrumentService;
import com.hxhq.service.YqService;
import com.hxhq.util.BeanConvert;
import com.hxhq.util.TimeUtil;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author zhangjing
 * @date 2026/01/28 15:50
 * @description
 */
@Service
public class InstrumentServiceImpl extends ServiceImpl<InstrumentMapper, Instrument> implements InstrumentService {

    @Resource
    YqService yqService;
    @Resource
    SyncLogServiceImpl syncLogService;
    @Resource
    InstrumentPushServiceImpl instrumentPushService;
    @Override
    public void dataPush(InstrumentPushDTO dto) {
        InstrumentPush instrument = BeanConvert.convert(dto, InstrumentPush.class);
        instrumentPushService.save(instrument);
    }

    @Override
    public void dataSync() {
        List<Instrument> list = baseMapper.notSync();
        if (list == null || list.isEmpty()) {
            return ;
        }
        //仪器
        List<Yq> sjList = changeToYq(list);
        //这里sjList 里 yq 里通过bh字段去更新已有数据，如果没有相同的就新增，该怎么处理。

        performUpsertByBh(sjList);
        //日志
        List<SyncLog> syncLogList = getLogList(list);
        saveLogList(syncLogList);
    }
    @Transactional
    public void saveLogList(List<SyncLog> syncLogList) {
        syncLogService.saveBatch(syncLogList);
    }

    /**
     * 核心方法：根据 Yq 对象的 bh 字段执行新增或更新操作
     * @param sjList 待处理的 Yq 对象列表
     */
    @Transactional
    public void performUpsertByBh(List<Yq> sjList) {
        // 1. 提取传入列表中的所有 bh 值
        Set<String> incomingBhSet = sjList.stream()
            .map(Yq::getBh)
            .collect(Collectors.toSet());

        // 2. 查询数据库中已存在的、与传入列表匹配的 Yq 记录
        List<Yq> existingRecordsInDb = yqService.listByBh(incomingBhSet);

        // 3. 提取数据库中已存在的 bh 集合，用于快速判断
        Set<String> existingBhSet = existingRecordsInDb.stream()
            .map(Yq::getBh)
            .collect(Collectors.toSet());

        // 4. 区分新增和更新的记录
        List<Yq> recordsToInsert = new ArrayList<>();
        List<Yq> recordsToUpdate = new ArrayList<>();

        for (Yq incomingRecord : sjList) {
            String bh = incomingRecord.getBh();
            if (existingBhSet.contains(bh)) {
                // 如果数据库中已存在此 bh，则标记为更新
                // 需要将现有记录的 ID 补充到 incomingRecord 上，以便 MP 知道更新哪一行
                Yq existingRecord = existingRecordsInDb.stream()
                    .filter(r -> r.getBh().equals(bh))
                    .findFirst()
                    // 理论上一定能找到，因为 existingBhSet.contains(bh)
                    .orElse(null);

                if (existingRecord != null) {
                    // 补全 ID
                    incomingRecord.setId(existingRecord.getId());
                    recordsToUpdate.add(incomingRecord);
                } else {
                    // 理论上不应该走到这里，除非并发问题。可以记录警告或抛异常。
                    System.err.println("警告：逻辑错误，bh 为 " + bh + " 的记录在 existingBhSet 中，但在 existingRecordsInDb 中未找到。");
                }

            } else {
                // 如果数据库中不存在此 bh，则标记为新增
                recordsToInsert.add(incomingRecord);
            }
        }

        // 5. 执行批量新增和更新操作
        if (!recordsToInsert.isEmpty()) {
            // 批量新增
            yqService.saveList(recordsToInsert);
            System.out.println("批量新增 Yq 记录: " + recordsToInsert.size() + " 条");
        }

        if (!recordsToUpdate.isEmpty()) {
            // 批量更新
            // 使用 updateBatchById，它会根据 ID 进行更新
            yqService.updateList(recordsToUpdate);
            System.out.println("批量更新 Yq 记录: " + recordsToUpdate.size() + " 条");
        }
    }
    private List<SyncLog> getLogList(List<Instrument> list) {
        List<SyncLog> syncLogList = new ArrayList<>();
        LocalDateTime now = LocalDateTime.now();
        list.forEach(item ->{
            SyncLog syncLog = new SyncLog();
            syncLog.setSourceRecordId(item.getInstrumentId());
            syncLog.setTargetSystem(EntityConstants.SYS_HXHQ);
            syncLog.setSourceType(EntityConstants.LOG_INSTRUMENT);
            syncLog.setCreatedAt(now);
            syncLog.setSyncStatus(EntityConstants.SUCCESS);
            syncLogList.add(syncLog);
        });

        return syncLogList;
    }
//
    private List<Yq> changeToYq(List<Instrument> list) {
        List<Yq> yqList = new ArrayList<>();
        list.forEach(item ->{
            Yq sj = new Yq();
            sj.setMc(item.getName());
            sj.setBh(item.getSn());
            sj.setXh(item.getModel());
            //部门名称
            sj.setBmMc(item.getDepartment());
            sj.setJzrq(TimeUtil.getDate(item.getCalibrationDate()));
            //无来源默认为：中间库
            sj.setLy(item.getSource()!=null?item.getSource():EntityConstants.SYS_STAGING_DATABASE);


            sj.setWc(item.getStorageConditions());
            sj.setRemark(item.getRemark());
            if (item.getOperationSign()!=null){
                sj.setDelFlag(item.getOperationSign()==3?"1":"0");
            }

            sj.setRemark(item.getRemark());

            yqList.add(sj);
        });
        return yqList;
    }
}
