package com.ruoyi.web.v2.v1.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.app.model.EntranceBatch;
import com.ruoyi.app.model.Purchaser;
import com.ruoyi.app.mapper.EntranceBatchMapper;
import com.ruoyi.app.mapper.PigpenMapper;
import com.ruoyi.app.mapper.ProductCategoryMapper;
import com.ruoyi.app.mapper.PurchaserMapper;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.uuid.UUID;
import com.ruoyi.web.v2.v1.model.*;
import com.ruoyi.web.v2.v1.model.vo.ProductionVo;
import com.ruoyi.web.v2.v1.mapper.*;
import com.ruoyi.web.v2.v1.service.IJsDistributionService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.web.v2.v1.utils.PaginationUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.nio.ByteBuffer;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

import static com.ruoyi.common.core.domain.AjaxResult.success;

/**
 * <p>
 * v2.0分销登记 服务实现类
 * </p>
 *
 * @author author
 * @since 2025-05-26
 */
@Service
public class JsDistributionServiceImpl extends ServiceImpl<JsDistributionMapper, JsDistribution> implements IJsDistributionService {

    @Autowired
    private JsDistributionMapper distributionMapper;
    @Autowired
    private JsDivideCircleMapper circleMapper;
    @Autowired
    private PigpenMapper pigpenMapper;
    @Autowired
    private EntranceBatchMapper entranceBatchMapper;
    @Autowired
    private PurchaserMapper purchaserMapper;
    @Autowired
    private ProductCategoryMapper categoryMapper;
    @Autowired
    private JsProduceCodeMapper produceCodeMapper;

    @Transactional
    @Override
    public AjaxResult add(JsDistribution distribution) {
        Integer supplierId = distribution.getSupplierId();
//        QueryWrapper<JsDivideCircle> queryWrapper = new QueryWrapper<>();
//        queryWrapper.eq("supplier_id", supplierId);
//        List<JsDivideCircle> divideCircles = circleMapper.selectList(queryWrapper);
//        for (JsDivideCircle divideCircle : divideCircles) {
//            Pigpen pigpen = pigpenMapper.selectPigpenById(divideCircle.getPigpenId().longValue());
//            pigpen.setIsUse(0);
//            pigpenMapper.updatePigpen(pigpen);
//        }
        UUID uuid = UUID.randomUUID();
        ByteBuffer bb = ByteBuffer.wrap(new byte[16]);
        bb.putLong(uuid.getMostSignificantBits());
        bb.putLong(uuid.getLeastSignificantBits());
        String shortUUID = Base64.getUrlEncoder().withoutPadding().encodeToString(bb.array());
        JsProduceCode jsProduceCode = new JsProduceCode();
        jsProduceCode.setCreateTime(new Date());
        jsProduceCode.setOneCode(shortUUID);
        distribution.setOneCode(shortUUID);
        produceCodeMapper.insert(jsProduceCode);
        distribution.setSeriesNoGroup(genSeriesNoGroup(distribution));
        distributionMapper.insert(distribution);
        return success();
    }

    private String genSeriesNoGroup(JsDistribution distribution) {
        if(ObjectUtil.isNotEmpty(distribution.getSeriesNoGroup())) {
            //如果提交的表单直接带有分圈后的批次序列号集，那么做一次存在性检测，检测成功直接采用，否则置空
            String[] seriesNoGroup = distribution.getSeriesNoGroup().split(",");
            List<JsDivideCircle> circles = circleMapper.selectList(
                    Wrappers.<JsDivideCircle>lambdaQuery().in(JsDivideCircle::getSeriesNo, seriesNoGroup));
            return circles.size() > 0 ? distribution.getSeriesNoGroup() : "";
        }else {
            //如果提交的表单未带有分圈的批次序列号，那么根据入场id或者检疫证号查分圈批次序列号集，进行设置
            if(ObjectUtil.isNotEmpty(distribution.getEntranceBatchId())) {
                //查询进场数据
                EntranceBatch entranceBatch = entranceBatchMapper.selectEntranceBatchById(distribution.getEntranceBatchId().longValue());
                //查询分圈数据
                List<JsDivideCircle> circles = circleMapper.selectList(
                        Wrappers.<JsDivideCircle>lambdaQuery()
                                .eq(JsDivideCircle::getEntranceBatchId, distribution.getEntranceBatchId()));
                if(entranceBatch != null && circles.size() > 0) {
                    //返回本条生产数据关联的分圈批次序列号集合
                    return circles.stream().map(
                            item -> entranceBatch.getAnimalCertNo() +
                                    item.getPigpenId() +
                                    entranceBatch.getEntranceTime().format(DateTimeFormatter.ofPattern("yyyyMMdd")))
                            .collect(Collectors.joining(","));
                }
            }
        }
        return "";
    }

    @Override
    public AjaxResult edit(JsDistribution distribution) {
        distributionMapper.updateById(distribution);
        return success();
    }

    @Override
    public AjaxResult delete(String ids) {
        String[] split = ids.split(",");
        for (String s : split) {
            JsDistribution jsDistribution = distributionMapper.selectById(s);
            QueryWrapper<JsProduceCode> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("one_code", jsDistribution.getOneCode());
            produceCodeMapper.delete(queryWrapper);
            distributionMapper.deleteById(s);
        }
        return success();
    }

    @Override
    public AjaxResult page(Integer pageNum, Integer pageSize, String startTime, String endTime, String supplierName, String purchaserName, String animalCertNo) {
        Page<JsDistribution> page = new Page<>(pageNum, pageSize);
        QueryWrapper<JsDistribution> queryWrapper = new QueryWrapper<>();
        if ("".equals(startTime) || null == startTime) {

        } else {
            queryWrapper.between("distribution_time", startTime + " 00:00:00", endTime + " 23:59:59");
        }

        queryWrapper.like(StringUtils.isNotEmpty(supplierName), "supplier_name", supplierName);
        queryWrapper.eq(StringUtils.isNotEmpty(purchaserName), "purchaser_name", purchaserName);

        if (StringUtils.isNotEmpty(animalCertNo)) {
            queryWrapper.eq("animal_cert_no", animalCertNo);
        }
        queryWrapper.orderByDesc("distribution_time");
        return success(distributionMapper.selectPage(page, queryWrapper));
    }

    @Override
    public AjaxResult listAll() {
        return success(distributionMapper.selectList(null));
    }

    @Override
    public PaginationUtil.PageResult<JsProduction> productionPage(Integer pageNum, Integer pageSize, String startTime, String endTime, String animalCertNo) {
        QueryWrapper<JsDistribution> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(StringUtils.isNotEmpty(animalCertNo), "animal_cert_no", animalCertNo)
                .groupBy("supplier_name,purchaser_name,DATE(distribution_time)")
                .orderByDesc("distribution_time");
        if ("".equals(startTime) || null == startTime) {

        } else {
            queryWrapper.between("distribution_time", startTime + " 00:00:00", endTime + " 23:59:59");
        }
        queryWrapper.orderByDesc("distribution_time");
        List<JsDistribution> jsDistributions = distributionMapper.selectList(queryWrapper);
        List<JsProduction> productions = new ArrayList<>();
        for (JsDistribution jsDistribution : jsDistributions) {
            JsProduction jsProduction = new JsProduction();
            jsProduction.setOneCode(jsDistribution.getOneCode());
            jsProduction.setCreateTime(jsDistribution.getDistributionTime());
            jsProduction.setSupplierName(jsDistribution.getSupplierName());
            jsProduction.setPurchaserName(jsDistribution.getPurchaserName());
            jsProduction.setAnimalCertNo(jsDistribution.getAnimalCertNo());
            QueryWrapper<JsProduceCode> queryWrapper1 = new QueryWrapper<>();
            queryWrapper1.eq("one_code", jsDistribution.getOneCode());
            JsProduceCode jsProduceCode = produceCodeMapper.selectOne(queryWrapper1);
            if (ObjectUtil.isNotEmpty(jsProduceCode)) {
                jsProduction.setAnimalCert(jsProduceCode.getAnimalCert());
                jsProduction.setMeatCert(jsProduceCode.getMeatCert());
            }
            Purchaser purchaser = purchaserMapper.selectPurchaserById((long) jsDistribution.getPurchaserId());
            jsProduction.setSalePlace(purchaser.getSalePlace());
            EntranceBatch entranceBatch = entranceBatchMapper.selectEntranceBatchById(jsDistribution.getEntranceBatchId().longValue());
            if (ObjectUtil.isNotEmpty(entranceBatch)) {
                jsProduction.setAmount(entranceBatch.getAmount());
                jsProduction.setVariety(entranceBatch.getVariety());
            }
            List<ProductionVo> list = new ArrayList<>();
            if ("".equals(startTime) || null == startTime) {
                list = distributionMapper.getAllList1(jsDistribution.getPurchaserName(), null, null,jsDistribution.getSupplierName());
            } else {
                list = distributionMapper.getAllList1(jsDistribution.getPurchaserName(), startTime + " 00:00:00", endTime + " 23:59:59",jsDistribution.getSupplierName());
            }
            jsProduction.setProductionVos(list);
            productions.add(jsProduction);
        }
        return PaginationUtil.paginate(productions, pageNum, pageSize);
    }

    @Override
    public AjaxResult editProduce(JsProduceCode jsProduceCode) {
        QueryWrapper<JsProduceCode> queryWrapper1 = new QueryWrapper<>();
        queryWrapper1.eq("purchaser_name",jsProduceCode.getPurchaserName()).eq("supplier_name",jsProduceCode.getSupplierName());
        List<JsProduceCode> jsProduceCodes = produceCodeMapper.selectList(queryWrapper1);
        for (JsProduceCode produceCode : jsProduceCodes) {
            if ("".equals(produceCode.getAnimalCert()) || null == produceCode.getAnimalCert()) {

            } else {
                produceCode.setAnimalCert(jsProduceCode.getAnimalCert());
                produceCode.setMeatCert(jsProduceCode.getMeatCert());
                produceCodeMapper.updateById(produceCode);
            }

        }
        return success();
    }
}
