/*
 * Copyright [2022] [https://www.xiaonuo.vip]
 *
 * Snowy采用APACHE LICENSE 2.0开源协议，您在使用过程中，需要注意以下几点：
 *
 * 1.请不要删除和修改根目录下的LICENSE文件。
 * 2.请不要删除和修改Snowy源码头部的版权声明。
 * 3.本项目代码可免费商业使用，商业使用请保留源码和相关描述文件的项目出处，作者声明等。
 * 4.分发源码时候，请注明软件出处 https://www.xiaonuo.vip
 * 5.不可二次分发开源参与同类竞品，如有想法可联系团队xiaonuobase@qq.com商议合作。
 * 6.若您的项目无法满足以上几点，需要更多功能代码，获取Snowy商业授权许可，请在官网购买授权，地址为 https://www.xiaonuo.vip
 */
package vip.xiaonuo.biz.modular.bizinventory.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollStreamUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.PhoneUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import vip.xiaonuo.biz.modular.bizinventory.param.*;
import vip.xiaonuo.biz.modular.utils.CommonExportUtil;
import vip.xiaonuo.common.exception.CommonException;
import vip.xiaonuo.common.page.CommonPageRequest;
import vip.xiaonuo.biz.modular.bizinventory.entity.BizInventory;
import vip.xiaonuo.biz.modular.bizinventory.mapper.BizInventoryMapper;
import vip.xiaonuo.biz.modular.bizinventory.service.BizInventoryService;
import vip.xiaonuo.dev.api.DevFileApi;
import vip.xiaonuo.dev.modular.file.entity.DevFile;
import vip.xiaonuo.dev.modular.file.service.DevFileService;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * 出入库管理Service接口实现类
 *
 * @author fanzherong
 * @date  2025/02/20 10:02
 **/
@Service
public class BizInventoryServiceImpl extends ServiceImpl<BizInventoryMapper, BizInventory> implements BizInventoryService {

    @Resource
    private DevFileService devFileService;
    @Resource
    DevFileApi devFileApi;

    @Override
    public Page<BizInventory> page(BizInventoryPageParam bizInventoryPageParam) {
        QueryWrapper<BizInventory> queryWrapper = this.getQuerWrapper(bizInventoryPageParam);
        return this.page(CommonPageRequest.defaultPage(), queryWrapper);
    }

    public QueryWrapper<BizInventory> getQuerWrapper(BizInventoryPageParam bizInventoryPageParam){
        QueryWrapper<BizInventory> queryWrapper = new QueryWrapper<>();
        if(ObjectUtil.isNotEmpty(bizInventoryPageParam.getLicenseNumber())){
            queryWrapper.lambda().like(BizInventory::getLicenseNumber,bizInventoryPageParam.getLicenseNumber());
        }
        if(ObjectUtil.isNotEmpty(bizInventoryPageParam.getDriverName())){
            queryWrapper.lambda().like(BizInventory::getDriverName,bizInventoryPageParam.getDriverName());
        }
        if(ObjectUtil.isNotEmpty(bizInventoryPageParam.getInventoryType())){
            queryWrapper.lambda().eq(BizInventory::getInventoryType,bizInventoryPageParam.getInventoryType());
        }
        if(ObjectUtil.isNotEmpty(bizInventoryPageParam.getProductName())){
            queryWrapper.lambda().like(BizInventory::getProductName,bizInventoryPageParam.getProductName());
        }
        if(ObjectUtil.isNotEmpty(bizInventoryPageParam.getInventoryTimeBegin()) && ObjectUtil.isNotEmpty(bizInventoryPageParam.getInventoryTimeEnd())){
            queryWrapper.lambda().between(BizInventory::getInventoryTime,bizInventoryPageParam.getInventoryTimeBegin()+" 00:00:00",bizInventoryPageParam.getInventoryTimeEnd()+" 23:59:59");
        }
        queryWrapper.lambda().orderByDesc(BizInventory::getInventoryTime);
        return queryWrapper;
    }

    @Override
    public void add(BizInventoryAddParam bizInventoryAddParam) {
        checkParam(bizInventoryAddParam.getDriverPhone(),bizInventoryAddParam.getLicenseNumber());
        BizInventory bizInventory = BeanUtil.toBean(bizInventoryAddParam, BizInventory.class);
        if(ObjectUtil.isNotEmpty(bizInventoryAddParam.getFileIdList())){
            StringBuffer nameBuffer = new StringBuffer();
            StringBuffer pathBuffer = new StringBuffer();
            StringBuffer idBuffer = new StringBuffer();
            for(String id : bizInventoryAddParam.getFileIdList()){
                DevFile devFile = devFileService.getById(id);
                nameBuffer.append(devFile.getName()+",");
                pathBuffer.append(devFileApi.storageFilePathReturnUrlById(id)+",");
                idBuffer.append(id+",");
            }
            bizInventory.setFileName(nameBuffer.substring(0,nameBuffer.length()-1));
            bizInventory.setFilePath(pathBuffer.substring(0,pathBuffer.length()-1));
            bizInventory.setFileId(idBuffer.substring(0,idBuffer.length()-1));
        }
        this.save(bizInventory);
    }

    public void checkParam(String phone,String lincenseNumber){
        //车牌号验证
        if(!isCarNumber(lincenseNumber)){
            throw new CommonException("车牌号：{}格式错误",lincenseNumber);
        }
        //手机号验证
        if(ObjectUtil.isNotEmpty(phone)){
            if(!PhoneUtil.isMobile(phone)){
                throw new CommonException("司机电话：{}格式错误", phone);
            }
        }

    }

    /**
     * 车牌号校验
     * @param carNumber
     * @return
     */
    public boolean isCarNumber(String carNumber){
        String carNumberPattern = "([京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼]{1}(([A-HJ-Z]{1}[A-HJ-NP-Z0-9]{5})|([A-HJ-Z]{1}(([DF]{1}[A-HJ-NP-Z0-9]{1}[0-9]{4})|([0-9]{5}[DF]{1})))|([A-HJ-Z]{1}[A-D0-9]{1}[0-9]{3}警)))|([0-9]{6}使)|((([沪粤川云桂鄂陕蒙藏黑辽渝]{1}A)|鲁B|闽D|蒙E|蒙H)[0-9]{4}领)|(WJ[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼·•]{1}[0-9]{4}[TDSHBXJ0-9]{1})|([VKHBSLJNGCE]{1}[A-DJ-PR-TVY]{1}[0-9]{5})";
        return Pattern.matches(carNumberPattern, carNumber);
    }

    @Override
    public void edit(BizInventoryEditParam bizInventoryEditParam) {
        checkParam(bizInventoryEditParam.getDriverPhone(),bizInventoryEditParam.getLicenseNumber());
        BizInventory bizInventory = this.queryEntity(bizInventoryEditParam.getId());
        BeanUtil.copyProperties(bizInventoryEditParam, bizInventory);
        if(ObjectUtil.isNotEmpty(bizInventoryEditParam.getFileIdList())){
            StringBuffer nameBuffer = new StringBuffer();
            StringBuffer pathBuffer = new StringBuffer();
            StringBuffer idBuffer = new StringBuffer();
            for(String id : bizInventoryEditParam.getFileIdList()){
                DevFile devFile = devFileService.getById(id);
                nameBuffer.append(devFile.getName()+",");
                pathBuffer.append(devFileApi.storageFilePathReturnUrlById(id)+",");
                idBuffer.append(id+",");
            }
            bizInventory.setFileName(nameBuffer.substring(0,nameBuffer.length()-1));
            bizInventory.setFilePath(pathBuffer.substring(0,pathBuffer.length()-1));
            bizInventory.setFileId(idBuffer.substring(0,idBuffer.length()-1));
        }
        this.updateById(bizInventory);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void delete(List<BizInventoryIdParam> bizInventoryIdParamList) {
        // 执行删除
        this.removeBatchByIds(CollStreamUtil.toList(bizInventoryIdParamList, BizInventoryIdParam::getId));
    }

    @Override
    public BizInventory detail(BizInventoryIdParam bizInventoryIdParam) {
        return this.queryEntity(bizInventoryIdParam.getId());
    }

    @Override
    public BizInventory queryEntity(String id) {
        BizInventory bizInventory = this.getById(id);
        if(ObjectUtil.isEmpty(bizInventory)) {
            throw new CommonException("出入库管理不存在，id值为：{}", id);
        }
        return bizInventory;
    }

    @Override
    public Map<String, Object> getTotal(BizInventoryPageParam bizInventoryPageParam) {
        QueryWrapper<BizInventory> out = this.getQuerWrapper(bizInventoryPageParam);
        out.lambda().eq(BizInventory::getInventoryType,"出库");
        QueryWrapper<BizInventory> in = this.getQuerWrapper(bizInventoryPageParam);
        in.lambda().eq(BizInventory::getInventoryType,"入库");
        Map<String,Object> map = Maps.newHashMap();
        map.put("out",this.getBaseMapper().getTotal(out));
        map.put("in",this.getBaseMapper().getTotal(in));
        return map;
    }

    @Override
    public void exportRecord(BizInventoryPageParam bizInventoryPageParam, HttpServletResponse response) throws IOException {
        QueryWrapper<BizInventory> queryWrapper = this.getQuerWrapper(bizInventoryPageParam);
        List<BizInventory> inventoryList = this.list(queryWrapper);
        String fileName = "出入库报表.xlsx";
        List<BizInventoryExport> list = Lists.newArrayList();
        for(BizInventory bizInventory : inventoryList){
            BizInventoryExport bizInventoryExport = new BizInventoryExport();
            BeanUtil.copyProperties(bizInventory,bizInventoryExport);
            list.add(bizInventoryExport);
        }
        CommonExportUtil.export(fileName, BizInventoryExport.class,list,response,"出入库报表");
    }

    @Override
    public List<BizInventoryReport> getReportList(BizInventoryParam bizInventoryParam) {
        Map<String,Object> paramMap = Maps.newHashMap();
        if(ObjectUtil.isNotEmpty(bizInventoryParam)){
            if(ObjectUtil.isNotEmpty(bizInventoryParam.getGrossTimeBegin()) && ObjectUtil.isNotEmpty(bizInventoryParam.getGrossTimeEnd())){
                paramMap.put("beginTime",bizInventoryParam.getGrossTimeBegin()+" 00:00:00");
                paramMap.put("endTime",bizInventoryParam.getGrossTimeEnd()+" 23:59:59");
            }else{
                Date date = new Date();
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
                String format = simpleDateFormat.format(date);
                paramMap.put("beginTime",format+" 00:00:00");
                paramMap.put("endTime",format+" 23:59:59");
            }
        }
        List<BizInventoryReport> reportList =  getReportList(paramMap,bizInventoryParam);
        return reportList;
    }

    @Override
    public void exportReport(BizInventoryParam bizInventoryParam, HttpServletResponse response) throws IOException {
        List<BizInventoryReport> reportList = getReportList(bizInventoryParam);
        if(ObjectUtil.isNotEmpty(bizInventoryParam)){
            if(StringUtils.equals(bizInventoryParam.getQueryFlag(),"1")){
                //车辆日报表
                String fileName = "车辆报表.xlsx";
                List<BizInventoryCarExport> exportResultList = reportList.stream().map(order -> {
                    BizInventoryCarExport purchaseOrderExportResult = new BizInventoryCarExport();
                    BeanUtil.copyProperties(order, purchaseOrderExportResult);
                    return purchaseOrderExportResult;
                }).collect(Collectors.toList());
                CommonExportUtil.export(fileName,BizInventoryCarExport.class,exportResultList,response,"车辆报表");
            }
            if(StringUtils.equals(bizInventoryParam.getQueryFlag(),"2")){
                //车辆日报表
                String fileName = "品名报表.xlsx";
                List<BizInventoryGoodsExport> exportResultList = reportList.stream().map(order -> {
                    BizInventoryGoodsExport purchaseOrderExportResult = new BizInventoryGoodsExport();
                    BeanUtil.copyProperties(order, purchaseOrderExportResult);
                    return purchaseOrderExportResult;
                }).collect(Collectors.toList());
                CommonExportUtil.export(fileName,BizInventoryGoodsExport.class,exportResultList,response,"品名报表");
            }
        }
    }

    public List<BizInventoryReport> getReportList(Map<String,Object> paramMap,BizInventoryParam bizInventoryParam){
        List<BizInventoryReport> reportList = null;
        if(ObjectUtil.isNotEmpty(bizInventoryParam)){
            if(StringUtils.equals(bizInventoryParam.getQueryFlag(),"1")){
                //车辆
                reportList = this.getBaseMapper().getLicenseNumber(paramMap);
            }
            if(StringUtils.equals(bizInventoryParam.getQueryFlag(),"2")){
                //品名
                reportList = this.getBaseMapper().getProductName(paramMap);
            }
        }

        //总车次
        int totalCarCount = 0;
        //总出库
        BigDecimal outWeightTotal = new BigDecimal(0);
        //总入库
        BigDecimal inWeightTotal = new BigDecimal(0);
        if(ObjectUtil.isNotEmpty(reportList)){
            for(int i = 0;i<reportList.size();i++){
                reportList.get(i).setNumber(i+1);
                totalCarCount += reportList.get(i).getCarCount();
                outWeightTotal = reportList.get(i).getOutWeight().add(outWeightTotal);
                inWeightTotal = reportList.get(i).getInWeight().add(inWeightTotal);
            }
            BizInventoryReport reportDay = new BizInventoryReport();
            reportDay.setLicensePlate("合计");
            reportDay.setCarCount(totalCarCount);
            reportDay.setOutWeight(outWeightTotal);
            reportDay.setInWeight(inWeightTotal);
            reportList.add(reportDay);
        }
        return reportList;
    }
}
