package vip.xiaonuo.warehouse.service.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import vip.xiaonuo.warehouse.entity.*;

import vip.xiaonuo.warehouse.entity.vo.WarehouseStockSecondVo;
import vip.xiaonuo.warehouse.mapper.*;
import vip.xiaonuo.warehouse.param.WarehouseStockParam;
import vip.xiaonuo.warehouse.param.WarehouseStockSecondParam;
import vip.xiaonuo.warehouse.param.WarehouseStockTailParam;
import vip.xiaonuo.warehouse.service.IWarehouseStockService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 仓库库存变化 服务实现类
 * </p>
 *
 * @author author
 * @since 2024-11-28
 */
@Service
public class WarehouseStockServiceImpl extends ServiceImpl<WarehouseStockMapper, WarehouseStock> implements IWarehouseStockService {

    @Autowired
    private WarehouseStockMapper stockMapper;
    @Autowired
    private WarehouseIncomStockMapper incomStockMapper;
    @Autowired
    private WarehouseOutStockMapper outStockMapper;
    @Autowired
    private WarehouseStockSecondMapper secondMapper;
    @Autowired
    private WarehouseStockDetailMapper detailMapper;

    @Override
    public WarehouseStockVo getOneTail(WarehouseStockTailParam stockParam) {
        String orgId = stockParam.getOrgId();
        DateTime day = DateUtil.beginOfDay(new Date());
        QueryWrapper<WarehouseStock> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(StringUtils.isNotBlank(orgId), "org_id", orgId);
        if ("".equals(stockParam.getTime()) || null == stockParam.getTime()) {
            queryWrapper.ge("create_time", day);
        } else {
            queryWrapper.between("create_time", stockParam.getTime()+"-01 00:00:00",stockParam.getTime()+"-01 23:59:59");
        }
        queryWrapper.select(" IFNULL(sum(lanolin),'0') lanolin,IFNULL(sum(fish_oil),'0') fishOil");
        WarehouseStock warehouseStock = stockMapper.selectOne(queryWrapper);
        QueryWrapper<WarehouseIncomStock> incomQueryWrapper = new QueryWrapper<>();
        incomQueryWrapper.eq(StringUtils.isNotBlank(orgId), "org_id", orgId);
        if ("".equals(stockParam.getTime()) || null == stockParam.getTime()) {
            incomQueryWrapper.ge("create_time", day);
        } else {
            incomQueryWrapper.between("create_time", stockParam.getTime()+"-01 00:00:00",stockParam.getTime()+"-01 23:59:59");
        }
        incomQueryWrapper.select(" IFNULL(sum(material),'0') material,IFNULL(sum(finish_produce),'0') finishProduce,IFNULL(sum(half_produce),'0') halfProduce" +
                ",IFNULL(sum(low_value),'0') lowValue,IFNULL(sum(package_material),'0') packageMaterial,IFNULL(sum(lanolin),'0') lanolin" +
                ",IFNULL(sum(fish_oil),'0') fishOil");
        WarehouseIncomStock incomeStock = incomStockMapper.selectOne(incomQueryWrapper);
        QueryWrapper<WarehouseOutStock> outQueryWrapper = new QueryWrapper<>();
        outQueryWrapper.eq(StringUtils.isNotBlank(orgId), "org_id", orgId);
        if ("".equals(stockParam.getTime()) || null == stockParam.getTime()) {
            outQueryWrapper.ge("create_time", day);
        } else {
            outQueryWrapper.between("create_time", stockParam.getTime()+"-01 00:00:00",stockParam.getTime()+"-01 23:59:59");
        }
        outQueryWrapper.select(" IFNULL(sum(material),'0') material,IFNULL(sum(finish_produce),'0') finishProduce,IFNULL(sum(half_produce),'0') halfProduce" +
                ",IFNULL(sum(low_value),'0') lowValue,IFNULL(sum(package_material),'0') packageMaterial,IFNULL(sum(lanolin),'0') lanolin" +
                ",IFNULL(sum(fish_oil),'0') fishOil");
        WarehouseOutStock outStock = outStockMapper.selectOne(outQueryWrapper);
        WarehouseStockVo vo = new WarehouseStockVo();
        if (ObjectUtil.isNotEmpty(warehouseStock)) {
            vo.setLanolin(warehouseStock.getLanolin());
            vo.setFishOil(warehouseStock.getFishOil());
        } else {
            vo.setFishOil("0");
            vo.setLanolin("0");
        }
        if (ObjectUtil.isNotEmpty(incomeStock)) {
            vo.setMaterialIncome(incomeStock.getMaterial());
            vo.setFinishProduceIncome(incomeStock.getFinishProduce());
            vo.setHalfProduceIncome(incomeStock.getHalfProduce());
            vo.setLowValueIncome(incomeStock.getLowValue());
            vo.setPackageMaterialIncome(incomeStock.getPackageMaterial());
            vo.setLanolinIncome(incomeStock.getLanolin());
            vo.setFishOilIncome(incomeStock.getFishOil());
        }else {
            vo.setMaterialIncome("0");
            vo.setFinishProduceIncome("0");
            vo.setHalfProduceIncome("0");
            vo.setLowValueIncome("0");
            vo.setPackageMaterialIncome("0");
            vo.setLanolinIncome("0");
            vo.setFishOilIncome("0");
        }
        if (ObjectUtil.isNotEmpty(outStock)) {
            vo.setMaterialOut(outStock.getMaterial());
            vo.setFinishProduceOut(outStock.getFinishProduce());
            vo.setHalfProduceOut(outStock.getHalfProduce());
            vo.setLowValueOut(outStock.getLowValue());
            vo.setPackageMaterialOut(outStock.getPackageMaterial());
            vo.setLanolinOut(outStock.getLanolin());
            vo.setFishOilOut(outStock.getFishOil());
        }else {
            vo.setMaterialOut("0");
            vo.setFinishProduceOut("0");
            vo.setHalfProduceOut("0");
            vo.setLowValueOut("0");
            vo.setPackageMaterialOut("0");
            vo.setLanolinOut("0");
            vo.setFishOilOut("0");
        }
        DateTime month = DateUtil.beginOfMonth(new Date());
        incomQueryWrapper.clear();
        incomQueryWrapper.eq(StringUtils.isNotBlank(orgId), "org_id", orgId);
        incomQueryWrapper.groupBy("lanolin_supplier");
        List<WarehouseIncomStock> incomStocks = incomStockMapper.selectList(incomQueryWrapper);

        incomQueryWrapper.clear();
        incomQueryWrapper.eq(StringUtils.isNotBlank(orgId), "org_id", orgId);
        incomQueryWrapper.groupBy("fish_oil_supplier");
        List<WarehouseIncomStock> incomStocks1 = incomStockMapper.selectList(incomQueryWrapper);

        vo.setLanolinSupplier(incomStocks.size());

        vo.setFishOilSupplier(incomStocks1.size());


        incomQueryWrapper.clear();
        outQueryWrapper.clear();
        incomQueryWrapper.eq(StringUtils.isNotBlank(orgId), "org_id", orgId);
        incomQueryWrapper.select(" IFNULL(sum(lanolin),'0') lanolin,IFNULL(sum(fish_oil),'0') fishOil");
        if ("".equals(stockParam.getTime()) || null == stockParam.getTime()) {
            incomQueryWrapper.ge("create_time", month);
        } else {
            incomQueryWrapper.between("create_time", stockParam.getTime()+"-01 00:00:00",stockParam.getTime()+"-31 23:59:59");
        }
        outQueryWrapper.eq(StringUtils.isNotBlank(orgId), "org_id", orgId);
        outQueryWrapper.select(" IFNULL(sum(lanolin),'0') lanolin,IFNULL(sum(fish_oil),'0') fishOil");
        if ("".equals(stockParam.getTime()) || null == stockParam.getTime()) {
            outQueryWrapper.ge("create_time", month);
        } else {
            outQueryWrapper.between("create_time", stockParam.getTime()+"-01 00:00:00",stockParam.getTime()+"-31 23:59:59");
        }
        WarehouseIncomStock stock = incomStockMapper.selectOne(incomQueryWrapper);
        WarehouseOutStock outStock1 = outStockMapper.selectOne(outQueryWrapper);
        if (ObjectUtil.isNotEmpty(stock)) {
            vo.setLanolinIncomeMonth(stock.getLanolin());
            vo.setFishOilIncomeMonth(stock.getFishOil());
        }else {
            vo.setLanolinIncomeMonth("0");
            vo.setFishOilIncomeMonth("0");
        }
        if (ObjectUtil.isNotEmpty(outStock1)) {
            vo.setLanolinOutMonth(outStock1.getLanolin());
            vo.setFishOilOutMonth(outStock1.getFishOil());
        }else {
            vo.setLanolinOutMonth("0");
            vo.setFishOilOutMonth("0");
        }
        return vo;
    }

    @Override
    public List<WarehouseStock> listStockChange(WarehouseStockParam stockParam) {
        String orgId = stockParam.getOrgId();
        QueryWrapper<WarehouseStock> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(StringUtils.isNotBlank(orgId), "org_id", orgId);
        queryWrapper.select(" CONVERT(IFNULL(sum(material),'0'),decimal(10,2)) material,CONVERT(IFNULL(sum(finish_produce),'0'),decimal(10,2)) finishProduce" +
                ",CONVERT(IFNULL(sum(half_produce),'0'),decimal(10,2)) halfProduce,CONVERT(IFNULL(sum(low_value),'0'),decimal(10,2)) lowValue" +
                ",CONVERT(IFNULL(sum(package_material),'0'),decimal(10,2)) packageMaterial,create_time createTime");
        queryWrapper.groupBy("DATE_FORMAT(create_time,'%Y-%m')");
        queryWrapper.orderByAsc("create_time");
        return stockMapper.selectList(queryWrapper);
    }

    @Override
    public List<WarehouseOutStock> listStockOut(WarehouseStockParam stockParam) {
        String orgId = stockParam.getOrgId();
        QueryWrapper<WarehouseOutStock> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(StringUtils.isNotBlank(orgId), "org_id", orgId);
        queryWrapper.select(" CONVERT(IFNULL(sum(material),'0'),decimal(10,2)) material,CONVERT(IFNULL(sum(finish_produce),'0'),decimal(10,2)) finishProduce" +
                ",CONVERT(IFNULL(sum(half_produce),'0'),decimal(10,2)) halfProduce,CONVERT(IFNULL(sum(low_value),'0'),decimal(10,2)) lowValue" +
                ",CONVERT(IFNULL(sum(package_material),'0'),decimal(10,2)) packageMaterial,create_time createTime");
        queryWrapper.groupBy("DATE_FORMAT(create_time,'%Y-%m')");
        queryWrapper.orderByAsc("create_time");
        return outStockMapper.selectList(queryWrapper);
    }

    @Override
    public WarehouseStockSecondVo getSecond(WarehouseStockSecondParam param) {
        String orgId = param.getOrgId();
        String time = param.getTime();
        Integer materialName = param.getMaterialType();
        QueryWrapper<WarehouseStockSecond> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(StringUtils.isNotBlank(orgId), "org_id", orgId);
        queryWrapper.eq("material_type", materialName);
        queryWrapper.between("create_time", time + "-01 00:00:00", time + "-31 23:59:59");
        queryWrapper.select(" IFNULL(sum(income_money),'0') incomeMoney,IFNULL(stock,'0') stock,IFNULL(sum(income_number),'0') incomeNumber");
        WarehouseStockSecond stockSecond = secondMapper.selectOne(queryWrapper);
        queryWrapper.clear();
        queryWrapper.eq(StringUtils.isNotBlank(orgId), "org_id", orgId);
        queryWrapper.eq("material_type", materialName);
        queryWrapper.le("create_time", time + "-31 23:59:59");
        queryWrapper.select(" IFNULL(sum(income_money),'0') incomeMoney");
        WarehouseStockSecond second = secondMapper.selectOne(queryWrapper);

        WarehouseStockSecondVo vo = new WarehouseStockSecondVo();
        BigDecimal math = new BigDecimal("10000");
        BigDecimal bg = new BigDecimal(stockSecond.getIncomeMoney());
        vo.setIncomeMoney(bg.divide(math, 2, RoundingMode.HALF_UP).toString());
        vo.setIncomeNumber(stockSecond.getIncomeNumber());

        BigDecimal bg1 = new BigDecimal(second.getIncomeMoney());
        vo.setMoneyCount(bg1.divide(math, 2, RoundingMode.HALF_UP).toString());

        QueryWrapper<WarehouseStockDetail> queryWrapper1 = new QueryWrapper<>();
        queryWrapper1.eq(StringUtils.isNotBlank(orgId), "org_id", orgId);
        queryWrapper1.eq("material_code", materialName);
        queryWrapper.le("create_time", time + "-31 23:59:59");
        queryWrapper1.select(" CONVERT(IFNULL(sum(material_number),'0'),decimal(10,2)) materialNumber");
        WarehouseStockDetail stockDetail = detailMapper.selectOne(queryWrapper1);
        if (ObjectUtil.isNotEmpty(stockDetail)) {
            vo.setStock(stockDetail.getMaterialNumber());
        } else {
            vo.setStock("0");
        }


        return vo;
    }

}
