package com.hys.app.service.erp.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hys.app.converter.erp.GoodsConverter;
import com.hys.app.converter.erp.GoodsSnConverter;
import com.hys.app.converter.erp.ProductConverter;
import com.hys.app.framework.context.user.AdminUserContext;
import com.hys.app.framework.database.WebPage;
import com.hys.app.framework.database.mybatisplus.base.BaseServiceImpl;
import com.hys.app.framework.exception.ServiceException;
import com.hys.app.mapper.goods.GoodsSnMapper;
import com.hys.app.model.erp.dos.GoodsSnDO;
import com.hys.app.model.erp.dos.ProductDO;
import com.hys.app.model.erp.dos.WarehouseOutDO;
import com.hys.app.model.erp.dto.GoodsSnCreateDTO;
import com.hys.app.model.erp.dto.GoodsSnDTO;
import com.hys.app.model.erp.dto.GoodsSnQueryParams;
import com.hys.app.model.erp.vo.GoodsSnVO;
import com.hys.app.model.erp.vo.GoodsVO;
import com.hys.app.model.erp.vo.ProductVO;
import com.hys.app.model.goods.enums.GoodsSnStatusEnums;
import com.hys.app.service.erp.GoodsManager;
import com.hys.app.service.erp.GoodsSnManager;
import com.hys.app.service.erp.ProductManager;
import com.hys.app.util.ValidateUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.*;

/**
 * 商品业务层实现
 *
 * @author 张崧
 * 2023-12-26 15:56:58
 */
@Service
public class GoodsSnManagerImpl extends BaseServiceImpl<GoodsSnMapper, GoodsSnDO> implements GoodsSnManager {

    @Autowired
    private GoodsSnConverter converter;

    @Autowired
    private GoodsManager goodsManager;
    @Autowired
    private ProductManager productManager;

    @Autowired
    private ProductConverter productConverter;

    @Override
    public WebPage<GoodsSnVO> searchCount(GoodsSnQueryParams queryParams) {
        List<GoodsSnDO> goodsSnDOS = baseMapper.getGoodsSnCount(queryParams);

        Long totalQty = baseMapper.getGoodsSnCountQty(queryParams);
        List<GoodsSnVO> goodsSnVOS = converter.convert(goodsSnDOS);

        for (GoodsSnVO item : goodsSnVOS) {
            GoodsVO goodsVO = goodsManager.getInfo(item.getGoodsId());
            item.setGoodsVO(goodsVO);
            GoodsSnQueryParams temp = new GoodsSnQueryParams();
        }

        WebPage<GoodsSnVO> webPage1 = new WebPage<>();
        webPage1.setData(goodsSnVOS);
        webPage1.setPageNo(queryParams.getPageNo());
        webPage1.setDataTotal(totalQty);
        webPage1.setPageSize(queryParams.getPageSize());

        return webPage1;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void add(GoodsSnDTO goodsSnDTO) {
        // 保存GoodsDO
        GoodsSnDO goodsSnDO = converter.convert(goodsSnDTO);
        super.save(goodsSnDO);

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void createMore(GoodsSnCreateDTO request) {
        // 保存GoodsDO
        GoodsVO goodsVO = goodsManager.getDetail(request.getGoodsId());
        if (Objects.isNull(goodsVO)) {
            throw new ServiceException("商品信息不存在");
        }
        List<GoodsSnDO> list = new ArrayList<>();
        for (int i = 0; i < request.getQty(); i++) {
            GoodsSnDO goodsSnDO = new GoodsSnDO();
            goodsSnDO.setGoodsId(goodsVO.getId());
            goodsSnDO.setSnCode(createGoodsSnCode(goodsVO));
            list.add(goodsSnDO);
        }
        super.saveBatch(list);
    }

    /**
     * 生成规则：序号号=商品编号+当前生成时间+4位自然序号
     * 注意：单次生成数量不得超过9999
     * 这个规则要改成：序号号=商品编号+规格编码（4位）+当前生成时间+4位自然序号
     *
     * @param goodsVO
     * @return
     */
    private static String createGoodsSnCode(GoodsVO goodsVO) {
        SimpleDateFormat sf = new SimpleDateFormat("yyyyMMddHHmmss");
        Date date = new Date();
        Random random = new Random();
        return goodsVO.getSn() + sf.format(date) + (random.nextInt(9000) + 1000);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void edit(GoodsSnDTO goodsSnDTO) {
        // 参数校验


        // 更新商品
        GoodsSnDO goodsSnDO = converter.convert(goodsSnDTO);
        super.updateById(goodsSnDO);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(Long id) {
        // 删除商品
        removeById(id);
    }

    @Override
    public Page<ProductVO> getSnProduct(GoodsSnQueryParams queryParams) {
        Page<ProductDO> page = productManager.page(new Page<>(queryParams.getPageNo(), queryParams.getPageSize()), new LambdaQueryWrapper<ProductDO>()
                .eq(ProductDO::getHaveSn, true)
                .like(StrUtil.isNotBlank(queryParams.getSku()), ProductDO::getSku, queryParams.getSku()));

        Page<ProductVO> convert = productConverter.convert(page);
        for (ProductVO record : convert.getRecords()) {
            record.setGoodsVo(BeanUtil.copyProperties(goodsManager.getById(record.getGoodsId()), GoodsVO.class));
        }
        return convert;
    }

    @Override
    public void createSnCode(GoodsSnDTO goodsDTO) {
        ProductDO byId = productManager.getById(goodsDTO.getProductId());
        if (ObjectUtil.isNull(byId)) {
            throw new ServiceException("sku不存在");
        }
        List<GoodsSnDO> list = new ArrayList<>();
        for (Integer num = goodsDTO.getNum(); num > 0; num--) {
            GoodsSnDO aDo = new GoodsSnDO();
            aDo.setGoodsId(byId.getGoodsId());
            aDo.setSku(byId.getSku());
            aDo.setProductId(goodsDTO.getProductId());
            aDo.setSnCode(byId.getSku() + DateUtil.format(LocalDateTime.now(), "yyyyMMddHHmmss") + String.format("%04d", num));
            list.add(aDo);
        }
        saveBatch(list);
    }

    @Override
    public void updateSnCode(Long id, String snCode) {
        GoodsSnDO snDO = ValidateUtil.getOne(baseMapper, GoodsSnDO::getId, id, "序列号");
        AdminUserContext.compareCompany(snDO.getCompanyId());
        long count = count(new LambdaQueryWrapper<GoodsSnDO>().eq(GoodsSnDO::getSnCode, snCode).ne(GoodsSnDO::getId, id));
        if (count > 0) {
            throw new ServiceException("序列号重复：" + snCode);
        }
        snDO.setSnCode(snCode);
        updateById(snDO);
    }

    @Override
    public GoodsSnVO getDetail(Long id) {
        GoodsSnDO goodsSnDO = getById(id);
        GoodsSnVO goodsSnVO = converter.convert(goodsSnDO);
        goodsSnVO.setGoodsVO(goodsManager.getById(goodsSnDO.getGoodsId()));
        goodsSnVO.setProductVO(productManager.getById(goodsSnDO.getProductId()));
        return goodsSnVO;
    }

    @Override
    public WebPage<GoodsSnVO> list(GoodsSnQueryParams queryParams) {
        WebPage<GoodsSnDO> webPage = baseMapper.selectPage(queryParams);
        WebPage<GoodsSnVO> webPage1 = converter.convert(webPage);
        for (GoodsSnVO goodsSnVO : webPage1.getData()) {
            goodsSnVO.setGoodsVO(goodsManager.getById(goodsSnVO.getGoodsId()));
            goodsSnVO.setProductVO(productManager.getById(goodsSnVO.getProductId()));
        }

        return webPage1;
    }
}

