package com.zehong.system.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.zehong.common.constant.RoboticArmConstans;
import com.zehong.common.core.domain.AjaxResult;
import com.zehong.common.utils.DateUtils;
import com.zehong.common.utils.StringUtils;
import com.zehong.common.utils.http.HttpUtils;
import com.zehong.system.domain.MesDeviceDomain;
import com.zehong.system.domain.PalletDeviceBinding;
import com.zehong.system.domain.PalletDeviceUploadFailure;
import com.zehong.system.domain.PalletDeviceUploadHistory;
import com.zehong.system.mapper.PalletDeviceUploadFailureMapper;
import com.zehong.system.service.IPalletDeviceUploadFailureService;
import com.zehong.system.service.ISysConfigService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 上传失败历史记录Service业务层处理
 *
 * @author zehong
 * @date 2026-01-16
 */
@Service
public class PalletDeviceUploadFailureServiceImpl implements IPalletDeviceUploadFailureService
{
    @Resource
    private PalletDeviceUploadFailureMapper palletDeviceUploadFailureMapper;

    @Resource
    private ISysConfigService sysConfigService;
    /**
     * 查询上传失败历史记录
     *
     * @param id 上传失败历史记录ID
     * @return 上传失败历史记录
     */
    @Override
    public PalletDeviceUploadFailure selectPalletDeviceUploadFailureById(Long id)
    {
        return palletDeviceUploadFailureMapper.selectPalletDeviceUploadFailureById(id);
    }

    /**
     * 查询上传失败历史记录列表
     *
     * @param palletDeviceUploadFailure 上传失败历史记录
     * @return 上传失败历史记录
     */
    @Override
    public List<PalletDeviceUploadFailure> selectPalletDeviceUploadFailureList(PalletDeviceUploadFailure palletDeviceUploadFailure)
    {
        return palletDeviceUploadFailureMapper.selectPalletDeviceUploadFailureList(palletDeviceUploadFailure);
    }

    /**
     * 新增上传失败历史记录
     *
     * @param palletDeviceUploadFailure 上传失败历史记录
     * @return 结果
     */
    @Override
    public int insertPalletDeviceUploadFailure(PalletDeviceUploadFailure palletDeviceUploadFailure)
    {
        palletDeviceUploadFailure.setCreateTime(DateUtils.getNowDate());
        return palletDeviceUploadFailureMapper.insertPalletDeviceUploadFailure(palletDeviceUploadFailure);
    }

    @Override
    public int batchInsert(List<PalletDeviceUploadFailure> palletDeviceUploadFailures) {
        return palletDeviceUploadFailureMapper.batchInsert(palletDeviceUploadFailures);
    }

    /**
     * 批量处理未上传成功的数据
     * @return r
     */
    @Override
    public int batchInsertRealTimeData(List<PalletDeviceBinding> palletDeviceBindings) {
        return palletDeviceUploadFailureMapper.batchInsertRealTimeData(palletDeviceBindings);
    }

    /**
     * 修改上传失败历史记录
     *
     * @param palletDeviceUploadFailure 上传失败历史记录
     * @return 结果
     */
    @Override
    public int updatePalletDeviceUploadFailure(PalletDeviceUploadFailure palletDeviceUploadFailure)
    {
        return palletDeviceUploadFailureMapper.updatePalletDeviceUploadFailure(palletDeviceUploadFailure);
    }

    /**
     * 批量删除上传失败历史记录
     *
     * @param ids 需要删除的上传失败历史记录ID
     * @return 结果
     */
    @Override
    public int deletePalletDeviceUploadFailureByIds(Long[] ids)
    {
        return palletDeviceUploadFailureMapper.deletePalletDeviceUploadFailureByIds(ids);
    }

    /**
     * 删除上传失败历史记录信息
     *
     * @param id 上传失败历史记录ID
     * @return 结果
     */
    @Override
    public int deletePalletDeviceUploadFailureById(Long id)
    {
        return palletDeviceUploadFailureMapper.deletePalletDeviceUploadFailureById(id);
    }


    /**
     * 批量处理未上传成功的数据
     * @return r
     */
    @Override
    public AjaxResult handleReUpload() {

        AjaxResult ajax = AjaxResult.success();
        List<PalletDeviceUploadFailure> palletDeviceUploadFailures = palletDeviceUploadFailureMapper.selectPalletDeviceUploadFailureList(new PalletDeviceUploadFailure());

        if (palletDeviceUploadFailures == null || palletDeviceUploadFailures.isEmpty()) {
            ajax.put("code", 200);
            ajax.put("msg", "上传数据列表不能为空");
            return ajax;
        }

        List<PalletDeviceUploadFailure> palletDeviceUploadHistories = palletDeviceUploadFailures.stream().filter(item -> StringUtils.isNotBlank(item.getMotherboardCode())).collect(Collectors.toList());

        try {
            // 1. 初始化MES数据并上传
            List<PalletDeviceUploadFailure> failedUploads = initMesDataAndUpload(palletDeviceUploadHistories);

            // 2. 处理上传结果
            if (failedUploads.isEmpty()) {
                // 全部成功，删除所有历史数据
                List<Long> successIds = palletDeviceUploadHistories.stream()
                        .map(PalletDeviceUploadFailure::getId)
                        .collect(Collectors.toList());
                if (!successIds.isEmpty()) {
                    int deleteCount = deletePalletDeviceUploadFailureByIds(successIds.toArray(new Long[0]));
                    return AjaxResult.success("所有数据上传成功，已删除 " + deleteCount + " 条历史记录");
                }
            } else {
                // 部分成功，只删除成功的数据
                List<Long> successIds = palletDeviceUploadHistories.stream()
                        .filter(item -> !failedUploads.contains(item))
                        .map(PalletDeviceUploadFailure::getId)
                        .collect(Collectors.toList());

                int successCount = 0;
                if (!successIds.isEmpty()) {
                    successCount = deletePalletDeviceUploadFailureByIds(successIds.toArray(new Long[0]));
                }

                // 构建失败设备列表
                List<String> failedDeviceCodes = failedUploads.stream()
                        .map(PalletDeviceUploadFailure::getMotherboardCode)
                        .collect(Collectors.toList());

                Map<String, Object> result = new HashMap<>();
                result.put("successCount", successCount);
                result.put("failedCount", failedUploads.size());
                result.put("failedDeviceCodes", failedDeviceCodes);

                ajax.put("code", 200);
                ajax.put("msg", "部分数据上传失败，成功 " + successCount + " 条，失败 " + failedUploads.size() + " 条");
                ajax.put("data", result);
                return ajax;
            }

            return AjaxResult.success("数据处理完成");

        } catch (Exception e) {
            ajax.put("code", 200);
            ajax.put("msg", "处理上传数据时发生异常" + e.getMessage());
            return ajax;
        }
    }

    /**
     * 初始化MES数据并上传，返回上传失败的设备列表
     */
    private List<PalletDeviceUploadFailure> initMesDataAndUpload(List<PalletDeviceUploadFailure> palletDeviceUploadFailureList) {

        boolean hasInvalid = palletDeviceUploadFailureList.stream()
                .anyMatch(palletDeviceBinding ->
                        StringUtils.isBlank(palletDeviceBinding.getMotherboardCode()) ||
                                palletDeviceBinding.getCalibrationConcentration() == null ||
                                StringUtils.isBlank(palletDeviceBinding.getCalibrationConcentrationStatus()) ||
                                StringUtils.isBlank(palletDeviceBinding.getConcentration()) ||
                                palletDeviceBinding.getRealTimeAd() == null ||
                                StringUtils.isBlank(palletDeviceBinding.getRealTimeStatus())
                );

        if (hasInvalid) {
            throw new RuntimeException("数据不完整");
        }

        String mesUploadAddress = sysConfigService.directSelectConfigByKey(RoboticArmConstans.UPLOAD_MES_ADDRESS);
        if (StringUtils.isBlank(mesUploadAddress)) {
            throw new RuntimeException("MES上传地址未配置");
        }
        try {
            String result = HttpUtils.sendPost(mesUploadAddress, JSON.toJSONString(palletDeviceUploadFailureList));
            if (StringUtils.isBlank(result)) {
                throw new RuntimeException("MES接口返回为空");
            }

            JSONObject jsonObject = JSON.parseObject(result);
            if (jsonObject.getInteger("code") == 200) {
                // 全部成功，返回空列表
                return new ArrayList<>();
            } else {
                // 部分失败，处理失败的数据
                String data = jsonObject.getString("data");
                if (StringUtils.isNotBlank(data)) {
                    return processPalletDeviceUploadFailure(palletDeviceUploadFailureList, data);
                } else {
                    JSONObject jsonObject1 = JSON.parseObject(data);
                    throw new RuntimeException("调用MES接口失败: " + jsonObject1.get("msg").toString());
                }
            }
        } catch (Exception e) {
            throw new RuntimeException("调用MES接口失败: " + e.getMessage());
        }
    }


    /**
     * 处理托盘设备上传历史数据，返回上传失败的设备列表
     */
    private List<PalletDeviceUploadFailure> processPalletDeviceUploadFailure(List<PalletDeviceUploadFailure> palletDeviceBindings, String data) {
        JSONObject jsonObject = JSON.parseObject(data);

        if (!jsonObject.containsKey("failedCount")) {
            return new ArrayList<>(palletDeviceBindings);
        }

        JSONArray failedCodes = jsonObject.getJSONArray("failedCodes");
        if (failedCodes == null || failedCodes.isEmpty()) {
            return new ArrayList<>();
        }

        // 使用Set提高查找效率
        Set<String> failedCodeSet = failedCodes.stream()
                .map(Object::toString)
                .collect(Collectors.toSet());

        // 返回失败的数据列表
        return palletDeviceBindings.stream()
                .filter(binding -> failedCodeSet.contains(binding.getMotherboardCode()))
                .collect(Collectors.toList());
    }

}
