package com.fs.hisStore.service.impl;

import cn.hutool.core.lang.Assert;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fs.common.core.domain.BaseEntity;
import com.fs.common.core.domain.R;
import com.fs.common.exception.ServiceException;
import com.fs.common.utils.DateUtils;
import com.fs.course.dto.FsStoreVerifyCodeDTO;
import com.fs.hisStore.domain.FsStoreProductScrm;
import com.fs.hisStore.domain.FsStoreVerifyCodeScrm;
import com.fs.hisStore.mapper.FsStoreProductScrmMapper;
import com.fs.hisStore.mapper.FsStoreVerifyCodeScrmMapper;
import com.fs.hisStore.service.IFsStoreVerifyCodeScrmService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;


/**
 * 核销码Service业务层处理
 *
 * @author fs
 * @date 2025-11-27
 */
@Slf4j
@Service
public class FsStoreVerifyCodeScrmServiceImpl extends ServiceImpl<FsStoreVerifyCodeScrmMapper, FsStoreVerifyCodeScrm> implements IFsStoreVerifyCodeScrmService {
    private static final Long NOT_DELETED = 0L;
    private static final Long DELETED = 1L;
    private static final Long STATUS_ENABLE = 1L;
    //出库状态
    private static final Long OUTBOUND_STATUS_UNDO = 0L;
    //核销状态
    private static final Long VERIFY_STATUS_WRITEOFF = 1L;
    private static final int BATCH_SIZE = 500;

    @Autowired
    private FsStoreProductScrmMapper fsStoreProductScrmMapper;

    @Autowired
    private IFsStoreVerifyCodeScrmService fsStoreVerifyCodeScrmService;

    /**
     * 查询核销码
     *
     * @param id 核销码主键
     * @return 核销码
     */
    @Override
    public FsStoreVerifyCodeScrm selectFsStoreVerifyCodeScrmById(String id) {
        return baseMapper.selectFsStoreVerifyCodeScrmById(id);
    }

    /**
     * 查询核销码列表
     *
     * @param fsStoreVerifyCodeScrm 核销码
     * @return 核销码
     */
    @Override
    public List<FsStoreVerifyCodeScrm> selectFsStoreVerifyCodeScrmList(FsStoreVerifyCodeScrm fsStoreVerifyCodeScrm) {
        fsStoreVerifyCodeScrm.setIsDel(0L);
        return baseMapper.selectFsStoreVerifyCodeScrmList(fsStoreVerifyCodeScrm);
    }

    /**
     * 新增核销码
     *
     * @param fsStoreVerifyCodeScrm 核销码
     * @return 结果
     */
    @Override
    public int insertFsStoreVerifyCodeScrm(FsStoreVerifyCodeScrm fsStoreVerifyCodeScrm) {
        //验证核销码是否存在
        if (baseMapper.selectCount(new LambdaQueryWrapper<FsStoreVerifyCodeScrm>().eq(FsStoreVerifyCodeScrm::getVerifyCode, fsStoreVerifyCodeScrm.getVerifyCode())) > 0) {
            throw new ServiceException("操作失败，核销码：" + fsStoreVerifyCodeScrm.getVerifyCode() + "已存在");
        }
        //获取商品信息
        FsStoreProductScrm product = fsStoreProductScrmMapper.selectFsStoreProductById(fsStoreVerifyCodeScrm.getProductId());
        if(product == null){
            throw new ServiceException("操作失败，商品不存在");
        }

        fsStoreVerifyCodeScrm.setStoreId(product.getStoreId());//获取店铺id
        fsStoreVerifyCodeScrm.setCreateTime(DateUtils.getNowDate());
        return baseMapper.insertFsStoreVerifyCodeScrm(fsStoreVerifyCodeScrm);
    }

    /**
     * 修改核销码
     *
     * @param fsStoreVerifyCodeScrm 核销码
     * @return 结果
     */
    @Override
    public int updateFsStoreVerifyCodeScrm(FsStoreVerifyCodeScrm fsStoreVerifyCodeScrm) {
        if (baseMapper.selectCount(new LambdaQueryWrapper<FsStoreVerifyCodeScrm>().eq(FsStoreVerifyCodeScrm::getVerifyCode, fsStoreVerifyCodeScrm.getVerifyCode()).eq(FsStoreVerifyCodeScrm::getIsDel, 0L)) > 0 && !fsStoreVerifyCodeScrm.getId().equals(fsStoreVerifyCodeScrm.getId())) {
            throw new ServiceException("操作失败，核销码：" + fsStoreVerifyCodeScrm.getVerifyCode() + "已存在");
        }
        fsStoreVerifyCodeScrm.setUpdateTime(DateUtils.getNowDate());
        return baseMapper.updateById(fsStoreVerifyCodeScrm);
    }

    /**
     * 批量删除核销码
     *
     * @param ids 需要删除的核销码主键
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class) // 声明事务，确保批量操作原子性
    public int deleteFsStoreVerifyCodeScrmByIds(Long[] ids, Long userId) {
        Assert.notNull(ids, "核销码ID数组不能为空！");
        if (ids.length == 0) {
            log.warn("核销码ID数组为空，无需执行删除操作");
            return 0;
        }

        LambdaQueryWrapper<FsStoreVerifyCodeScrm> queryWrapper = new LambdaQueryWrapper<FsStoreVerifyCodeScrm>()
                .in(FsStoreVerifyCodeScrm::getId, ids)
                .eq(FsStoreVerifyCodeScrm::getIsDel, NOT_DELETED);
        List<FsStoreVerifyCodeScrm> list = baseMapper.selectList(queryWrapper);


        if (list.size() != ids.length) {
            log.error("核销码删除失败，数据不一致！入参ID数量：{}，有效数据数量：{}", ids.length, list.size());
            throw new ServiceException("操作失败，数据不一致！");
        }

        boolean hasInvalidData = list.stream()
                .anyMatch(scrm -> STATUS_ENABLE.equals(scrm.getOutboundStatus())
                        || STATUS_ENABLE.equals(scrm.getVerifyStatus()));
        if (hasInvalidData) {
            log.error("核销码删除失败，存在已出库或已核销的核销码！ID列表：{}", Arrays.toString(ids));
            throw new ServiceException("操作失败，存在出库或者核销的核销码！");
        }

        if (!list.isEmpty()) {
            LambdaUpdateWrapper<FsStoreVerifyCodeScrm> updateWrapper = new LambdaUpdateWrapper<FsStoreVerifyCodeScrm>()
                    .in(FsStoreVerifyCodeScrm::getId, ids)
                    .set(FsStoreVerifyCodeScrm::getIsDel, DELETED)
                    .set(BaseEntity::getUpdateBy, userId)
                    .set(BaseEntity::getUpdateTime, new Date());
            int updateCount = baseMapper.update(null, updateWrapper);
            log.info("核销码批量删除成功，更新数量：{}，ID列表：{}", updateCount, Arrays.toString(ids));
            return updateCount;
        }

        return 0;
    }

    /**
     * 删除核销码信息
     *
     * @param id 核销码主键
     * @return 结果
     */
    @Override
    public int deleteFsStoreVerifyCodeScrmById(String id) {
        return baseMapper.deleteFsStoreVerifyCodeScrmById(id);
    }


    /**
     * 核销码导入实现类
     *
     * @param verifyCodeDTOS 数据
     * @param userId         用户id
     * @return R
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public R importExpress(List<FsStoreVerifyCodeDTO> verifyCodeDTOS, String userId, Long productId) {
        if (CollectionUtils.isEmpty(verifyCodeDTOS)) {
            return R.ok("导入成功！无待导入数据");
        }

        List<String> verifyCodes = verifyCodeDTOS.stream()
                .map(FsStoreVerifyCodeDTO::getVerifyCode)
                .filter(Objects::nonNull)
                .collect(Collectors.toList());

        StringBuilder errorMsg = new StringBuilder();
        long emptyCodeCount = verifyCodeDTOS.stream()
                .filter(dto -> dto.getVerifyCode() == null || dto.getVerifyCode().trim().isEmpty())
                .count();

//        Long[] productIds = verifyCodeDTOS.stream()
//                .map(FsStoreVerifyCodeDTO::getProductId)
//                .filter(Objects::nonNull)
//                .toArray(Long[]::new);

        if (emptyCodeCount > 0) {
            errorMsg.append("发现").append(emptyCodeCount).append("条核销码为空的数据\n");
        }

        Map<String, Long> existVerifyCodeMap = new HashMap<>();
        if (!CollectionUtils.isEmpty(verifyCodes)) {
            List<FsStoreVerifyCodeScrm> existList = baseMapper.selectList(
                    new LambdaQueryWrapper<FsStoreVerifyCodeScrm>()
                            .in(FsStoreVerifyCodeScrm::getVerifyCode, verifyCodes)
                            .eq(FsStoreVerifyCodeScrm::getIsDel, 0)
            );
            if (!CollectionUtils.isEmpty(existList)) {
                existVerifyCodeMap = existList.stream()
                        .collect(Collectors.toMap(
                                FsStoreVerifyCodeScrm::getVerifyCode,
                                FsStoreVerifyCodeScrm::getId,
                                (k1, k2) -> k1
                        ));
            }
        }

        FsStoreProductScrm productScrm = null;
        //获取商品信息
        try {
            productScrm = fsStoreProductScrmMapper.selectFsStoreProductById(productId);
            if (productScrm == null) {
                throw new ServiceException("操作失败，商品信息不存在！");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
//        //获取商品
//        Map<Long, Long> existProductrMap = new HashMap<>();
//        if (!CollectionUtils.isEmpty(Arrays.asList(productIds))) {
//            List<FsStoreProductScrm> productScrmList = fsStoreProductScrmMapper.selectProductByIds(productIds);
//
//            if (!CollectionUtils.isEmpty(productScrmList)) {
//                existProductrMap = productScrmList.stream()
//                        .collect(Collectors.toMap(FsStoreProductScrm::getProductId, FsStoreProductScrm::getProductId));
//            }
//        }

        List<FsStoreVerifyCodeScrm> insertList = new ArrayList<>();
        for (FsStoreVerifyCodeDTO dto : verifyCodeDTOS) {
            String verifyCode = dto.getVerifyCode();

            if (verifyCode == null || verifyCode.trim().isEmpty()) {
                continue;
            }

            // 检查是否重复
            if (existVerifyCodeMap.containsKey(verifyCode)) {
                errorMsg.append("核销码：").append(verifyCode)
                        .append("（商品：").append(productScrm.getProductName()).append("）已存在，重复新增\n");
                continue;
            }

            FsStoreVerifyCodeScrm entity = new FsStoreVerifyCodeScrm();
            entity.setVerifyCode(verifyCode);
            entity.setProductId(productId);
            entity.setStoreId(productScrm.getStoreId());
            entity.setOutboundStatus(0L);
            entity.setVerifyStatus(0L);
            entity.setStatus(1L);
            entity.setIsDel(0L);
            Date now = new Date();
            entity.setCreateTime(now);
            // 创建人
            entity.setCreateBy(userId != null ? userId : "0");
            insertList.add(entity);
            existVerifyCodeMap.put(verifyCode, 0L);
        }

        //批量插入
        if (!CollectionUtils.isEmpty(insertList)) {
            try {
                for (int i = 0; i < insertList.size(); i += BATCH_SIZE) {
                    int end = Math.min(i + BATCH_SIZE, insertList.size());
                    List<FsStoreVerifyCodeScrm> batchList = insertList.subList(i, end);
                    baseMapper.batchInsertVerifyCode(batchList);
                }
            } catch (Exception e) {
                log.error("核销码批量插入失败", e);
                return R.error("导入失败：" + e.getMessage());
            }
        }

        String resultMsg = errorMsg.length() > 0
                ? "部分数据导入成功，错误信息：\n" + errorMsg.toString()
                : "导入成功！共导入" + insertList.size() + "条核销码";
        return R.ok(resultMsg);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R writeOff(Long[] ids, String userId) {
        if (userId == null || userId.trim().isEmpty()) {
            log.warn("溯源码核销失败：操作人ID为空，核销ids={}", Arrays.toString(ids));
            return R.error("操作失败，操作人ID不能为空！");
        }

        LambdaQueryWrapper<FsStoreVerifyCodeScrm> queryWrapper = new LambdaQueryWrapper<FsStoreVerifyCodeScrm>()
                .in(FsStoreVerifyCodeScrm::getId, ids)
                .eq(FsStoreVerifyCodeScrm::getIsDel, NOT_DELETED);
        List<FsStoreVerifyCodeScrm> dbList = baseMapper.selectList(queryWrapper);

        if (CollectionUtils.isEmpty(dbList)) {
            log.warn("溯源码核销失败：指定ID的核销数据不存在，核销ids={}，userId={}", Arrays.toString(ids), userId);
            return R.error("操作失败，核销数据不存在！");
        }

        Set<Long> inputIdSet = new HashSet<>(Arrays.asList(ids));
        Set<Long> dbIdSet = dbList.stream().map(FsStoreVerifyCodeScrm::getId).collect(Collectors.toSet());
        inputIdSet.removeAll(dbIdSet);
        String notExistIds = inputIdSet.isEmpty() ? "" : inputIdSet.stream().map(String::valueOf).collect(Collectors.joining(","));

        List<FsStoreVerifyCodeScrm> hasWriteOffList = dbList.stream()
                .filter(l -> VERIFY_STATUS_WRITEOFF.equals(l.getVerifyStatus()))
                .collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(hasWriteOffList)) {
            String hasWriteOffCodes = hasWriteOffList.stream()
                    .filter(l -> l.getVerifyCode() != null && !l.getVerifyCode().trim().isEmpty())
                    .map(FsStoreVerifyCodeScrm::getVerifyCode)
                    .collect(Collectors.joining(","));
            log.warn("溯源码核销失败：部分数据已核销，已核销核销码={}，userId={}", hasWriteOffCodes, userId);
            return R.error("操作失败，核销码【" + hasWriteOffCodes + "】已核销，禁止重复核销！");
        }

        List<FsStoreVerifyCodeScrm> unOutboundList = dbList.stream()
                .filter(l -> OUTBOUND_STATUS_UNDO.equals(l.getOutboundStatus()))
                .filter(l -> l.getVerifyCode() != null && !l.getVerifyCode().trim().isEmpty())
                .collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(unOutboundList)) {
            String unOutboundCodes = unOutboundList.stream()
                    .map(FsStoreVerifyCodeScrm::getVerifyCode)
                    .collect(Collectors.joining(","));
            log.warn("溯源码核销失败：部分核销码未出库，未出库核销码={}，userId={}", unOutboundCodes, userId);
            return R.error("操作失败，核销码【" + unOutboundCodes + "】未出库，禁止核销！");
        }

        Date updateTime = new Date();
        dbList.forEach(l -> {
            l.setVerifyStatus(VERIFY_STATUS_WRITEOFF);
            l.setUpdateTime(updateTime);
            l.setUpdateBy(userId.trim());
        });

        boolean updateResult = this.updateBatchById(dbList);
        if (!updateResult) {
            log.error("溯源码核销失败：批量更新数据库失败，核销ids={}，userId={}", Arrays.toString(ids), userId);
            throw new RuntimeException("核销数据更新失败，请重试！");
        }

        R successR = R.ok("核销成功，共处理" + dbList.size() + "条数据");
        if (!notExistIds.isEmpty()) {
            successR.put("notExistIds", notExistIds);
            log.warn("溯源码核销提示：部分ID不存在，不存在的ids={}，userId={}", notExistIds, userId);
        }
        return successR;
    }
}
