package cn.iocoder.yudao.module.identity.service.code;

import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.identity.controller.admin.code.vo.CodeCreateReqVO;
import cn.iocoder.yudao.module.identity.controller.admin.code.vo.CodeExportReqVO;
import cn.iocoder.yudao.module.identity.controller.admin.code.vo.CodePageReqVO;
import cn.iocoder.yudao.module.identity.controller.admin.code.vo.CodeUpdateReqVO;
import cn.iocoder.yudao.module.identity.convert.code.CodeConvert;
import cn.iocoder.yudao.module.identity.dal.dataobject.code.CodeDO;
import cn.iocoder.yudao.module.identity.dal.dataobject.generatebatch.GenerateBatchDO;
import cn.iocoder.yudao.module.identity.dal.dataobject.generaterecord.GenerateRecordDO;
import cn.iocoder.yudao.module.identity.dal.mysql.code.CodeMapper;
import cn.iocoder.yudao.module.identity.qrcode.QRCodeProperties;
import cn.iocoder.yudao.module.identity.service.generatebatch.GenerateBatchService;
import cn.iocoder.yudao.module.identity.service.generaterecord.GenerateRecordService;
import cn.iocoder.yudao.module.infra.api.file.FileApi;
import cn.iocoder.yudao.module.product.api.harvestbatch.HarvestBatchApi;
import cn.iocoder.yudao.module.product.api.harvestbatch.dto.HarvestBatchDTO;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.identity.enums.ErrorCodeConstants.CODE_NOT_EXISTS;

/**
 * 标识码 Service 实现类
 *
 * @author 芋道源码
 */
@Service
@Validated
public class CodeServiceImpl implements CodeService {

    @Resource
    private CodeMapper codeMapper;

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Resource
    private GenerateRecordService generateRecordService;

    @Resource
    private FileApi fileApi;

    @Resource
    private HarvestBatchApi harvestBatchApi;

    @Resource
    private GenerateBatchService generateBatchService;

    @Resource
    private QRCodeProperties qrCodeProperties;

    /**
     * 创建标识码组实现
     *
     * @param createReqVO 创建信息
     * @return 编号
     */
    @Override
    public Long[] createCode(CodeCreateReqVO createReqVO) {
        GenerateRecordDO recordByRecordId = generateRecordService.getGenerateRecordByRecordId(createReqVO.getGenerateRecordId());
        //判断记录编码是否存在
        if (recordByRecordId == null){
            throw exception(CODE_NOT_EXISTS);
        }
        //根据码生成记录ID获取码生成记录与批次关联记录数据信息
        GenerateBatchDO generateBatchByRecordId = generateBatchService.getGenerateBatchByRecordId(recordByRecordId.getGenerateRecordId());
        //根据采收批次ID获取采收批次信息
        CommonResult<HarvestBatchDTO> harvestBatchById = harvestBatchApi.getHarvestBatchById(generateBatchByRecordId.getBatchId());
        HarvestBatchDTO dtos = harvestBatchById.getData();
        List<CodeDO> codeDOS = new ArrayList<>();
            CodeDO codeDO = new CodeDO();
            codeDO.setId(null);
            codeDO.setGenerateRecordId(recordByRecordId.getGenerateRecordId());
//            codeDO.setIdentityCode(str);
//            codeDO.setVerfiyCode(Arrays.stream(verificationCodeStrings).findFirst().orElse(null));
            codeDO.setRuleId(recordByRecordId.getRuleId());
            codeDO.setCodeRuleFormat(recordByRecordId.getCodeRuleFormat());
            codeDO.setCodeType(recordByRecordId.getCodeType());
            codeDO.setCharLength(recordByRecordId.getCharLength());
            codeDO.setCharType(recordByRecordId.getCharType());
            codeDO.setBatchType(generateBatchByRecordId.getBatchType());
            codeDO.setGoodsId(dtos.getGoodsId());
            codeDO.setGoodsName(dtos.getGoodsName());
            codeDO.setBatchId(recordByRecordId.getBatchId());
            codeDO.setBelongBusinessId(recordByRecordId.getBelongBusinessId());
            codeDO.setBelongBusinessName(recordByRecordId.getBelongBusinessName());
            codeDOS.add(codeDO);

        //新增标识码表
        codeMapper.insertBatch(codeDOS);
        //对象转流操作取属性数组
        return codeDOS.stream().map(CodeDO::getId).toArray(Long[]::new);
    }

    /**
     * 更新标识码实现
     *
     * @param updateReqVO 更新信息
     */
    @Override
    public void updateCode(CodeUpdateReqVO updateReqVO) {
        // 校验存在
        validateCodeExists(updateReqVO.getId());
        // 更新
        CodeDO updateObj = CodeConvert.INSTANCE.convert(updateReqVO);
        codeMapper.updateById(updateObj);
    }

    /**
     * 删除标识码实现
     *
     * @param id 编号
     */
    @Override
    public void deleteCode(Long id) {
        // 校验存在
        validateCodeExists(id);
        // 删除
        codeMapper.deleteById(id);
    }

    private void validateCodeExists(Long id) {
        if (codeMapper.selectById(id) == null) {
            throw exception(CODE_NOT_EXISTS);
        }
    }

    /**
     * 获得标识码实现
     *
     * @param id 编号
     * @return 标识码
     */
    @Override
    public CodeDO getCode(Long id) {
        CodeDO codeDO = codeMapper.selectById(id);
        if (codeDO != null) {
            // 拼接identityCode字段数据与qrCodeProperties.getUrl()
            codeDO.setIdentityCode(qrCodeProperties.getUrl() + codeDO.getIdentityCode());
        }
        return codeDO;
    }

    /**
     * 获得标识码分页实现
     *
     * @param pageReqVO 分页查询
     * @return 标识码分页
     */
    @Override
    public PageResult<CodeDO> getCodePage(CodePageReqVO pageReqVO) {
        // 查询原始数据
        PageResult<CodeDO> pageResult = codeMapper.selectPage(pageReqVO);
        // 使用HashSet进行去重操作
        Set<String> uniqueRecordIds = new HashSet<>();
        List<CodeDO> distinctList = new ArrayList<>();

        for (CodeDO code : pageResult.getList()) {
            String generateRecordId = code.getGenerateRecordId();
            if ( !generateRecordId.isEmpty() && !uniqueRecordIds.contains(generateRecordId)) {
                uniqueRecordIds.add(generateRecordId);
                // 拼接identityCode字段数据与qrCodeProperties.getUrl()
                code.setIdentityCode(qrCodeProperties.getUrl()+ code.getIdentityCode());
                distinctList.add(code);
            }
        }
        // 更新去重后的数据到分页结果对象中
        pageResult.setList(distinctList);
        return pageResult;
    }

    /**
     * 获得标识码列表, 用于 Excel 导出实现
     *
     * @param exportReqVO 查询条件
     * @return 标识码列表
     */
    @Override
    public List<CodeDO> getCodeList(CodeExportReqVO exportReqVO) {
        return codeMapper.selectList(exportReqVO);
    }

    /**
     * 查询所有标识码列表
     *
     * @return
     */
    @Override
    public List<CodeDO> getCodeList() {
        //查询所有标识码列表
        LambdaQueryWrapper<CodeDO> wrapper = new LambdaQueryWrapper<>();
        return codeMapper.selectList(wrapper);
    }

    /**
     * 根据指定的generateRecordId获取所有标识码列表
     *
     * @param generateRecordId
     * @return
     */
    @Override
    public List<CodeDO> getCodesByGenerateRecordId(String generateRecordId) {
        // 调用数据访问层的方法，根据商户id查询标识码列表
        QueryWrapper<CodeDO> queryWrapper  = new QueryWrapper<>();
        // 查询指定商户ID的标识码列表信息
        queryWrapper.eq("generate_record_id", generateRecordId);
        // 执行查询并返回结果列表
        return codeMapper.selectList(queryWrapper);

    }

    /**
     * 根据generateRecordId和identityCode查询对应的标识码信息
     *
     * @param identityCode
     * @return
     */
    @Override
    public List<CodeDO> getCodeByGenerateRecordIdAndIdentityCode(String generateRecordId, String identityCode) {
        //判断参数不为空的情况下  进行条件查询
        if (identityCode != null && !identityCode.isEmpty()) {
            //调用数据访问层的方法，根据商户id和identituCode 查询标识码列
            QueryWrapper<CodeDO> codeDoqueryWrapper = new QueryWrapper<>();
            codeDoqueryWrapper.eq( "generate_record_id", generateRecordId);
            codeDoqueryWrapper.eq( "identity_code",identityCode); // 查询指定的identityCodecodeDo
            codeDoqueryWrapper.select();
            return codeMapper.selectList(codeDoqueryWrapper);
        }
        // 如果identityCode没有输入值，则返回所有标识码列表
        return getCodesByGenerateRecordId(generateRecordId);
        }

    @Override
    public CodeDO getCodeForApp(String identityCode) {
        return codeMapper.selectOne(new LambdaQueryWrapperX<CodeDO>().eq(CodeDO::getIdentityCode, identityCode));
    }

    @Override
    public CodeDO getCodeDOInfoByGenerateRecordId(String generateRecordId) {
        // 构建查询条件
        QueryWrapper<CodeDO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("generate_record_id", generateRecordId);

        // 执行查询
        List<CodeDO> codes = codeMapper.selectList(queryWrapper);

        // 查询结果为空，返回空列表
        if (codes.isEmpty()) {
            return null;
        }
        // 获取第一个CodeDO对象
        CodeDO code = codes.get(0);

        // 构建返回结果对象
        CodeDO codeDO = new CodeDO();
        codeDO.setBatchId(code.getBatchId());
        codeDO.setGoodsName(code.getGoodsName());

        return codeDO;
    }
}
