/*
 * Author: wangjian
 * 生成ServiceImpl
 */
package com.tofly.stocks.service.impl;

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.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.haiqiu.tools.excel.utils.ExcelUtils;
import com.tofly.common.core.util.StringUtil;
import com.tofly.common.oauth.util.SecurityUtils;
import com.tofly.common.service.IFileInfoService;
import com.tofly.stocks.dto.DrugUseInfoDto;
import com.tofly.stocks.dto.DrugUseInfoQuery;
import com.tofly.stocks.dto.DrugUseReportQuery;
import com.tofly.stocks.entity.*;
import com.tofly.stocks.service.DrugUseDetailService;
import com.tofly.stocks.service.DrugUseInfoService;
import com.tofly.stocks.service.StockInfoService;
import com.tofly.stocks.vo.DrugUseDetailVo;
import com.tofly.stocks.vo.DrugUseInfoVo;
import com.tofly.stocks.vo.DrugUseReportVo;
import org.apache.commons.lang.time.DateFormatUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import com.tofly.stocks.mapper.DrugUseInfoMapper;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 药品使用信息表
 *
 * @author admin
 * @date Fri Nov 25 00:00:00 CST 2022
 */
@Service("drugUseInfoService")
public class DrugUseInfoServiceImpl extends ServiceImpl<DrugUseInfoMapper, DrugUseInfo> implements DrugUseInfoService {

    @Autowired
    private IFileInfoService fileInfoService;

    @Autowired
    private DrugUseDetailService drugUseDetailService;

    @Value("${flow.ftp.stocks.druguse}")
    private String path;


    @Autowired
    private StockInfoService stockInfoService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveDrugUseInfo(DrugUseInfoDto drugUseInfoDto, List<MultipartFile> files) {
        boolean flag;
        if (CollectionUtils.isEmpty(drugUseInfoDto.getDrugUseDetails())) {
            throw new RuntimeException("使用明细单数据不能为空");
        }
        String baseNo="YPSY";

        Date now = new Date(); // 创建一个Date对象，获取当前时间
        String strDateFormat = "yyyyMM";
        String start_no = baseNo + DateFormatUtils.format(now, strDateFormat);
        //获取当天最大的采样编号
        String Sample_No = this.baseMapper.getUsestockMaxNo(start_no);

        int firstNum = 1;
        if (Sample_No.length() == 14) {
            firstNum = Integer.parseInt(Sample_No.substring(11)) + 1;
        }

        String end_no = String.format("%04d", firstNum); //补全数字，不足用0补位

        String usestockNo = start_no + end_no;

        DrugUseInfo data = new DrugUseInfo();
        BeanUtils.copyProperties(drugUseInfoDto, data);
        data.setUsestockNo(usestockNo); //赋值单号

        if(data.getRecordUserId()==null || data.getRecordUserId()==0){
            data.setRecordUserId(SecurityUtils.getUserId()); //默认入库人为当前登录人

        }
        if(data.getDrugUseDpt()==null || data.getDrugUseDpt()==0){
            data.setDrugUseDpt(SecurityUtils.getUserDeptId()); //默认入库人为当前登录人

        }
     if(data.getRecordTime()==null){
         data.setRecordTime(now);

     }
        //附件
        data.setAnnex(fileInfoService.uploadFiles(files,data.getAnnex()
                ,data.getAnnex(),path,"TF_STOCKS_DRUG_USE_INFO"));

        flag = this.save(data);
        //保存入库明细数据
        for (DrugUseDetail drugUseDetail : drugUseInfoDto.getDrugUseDetails()
        ) {
            drugUseDetail.setDrugUseId(data.getId());

            drugUseDetailService.save(drugUseDetail);
        }
        if(data.getUsestockStatus()==2){ //已确认的
            AddStockInfo(drugUseInfoDto.getDrugUseDetails()); //加入库存
        }
        return flag;
    }



    /**
     * 使用
     * @param drugUseDetailVos
     */
    private  void  AddStockInfo(List<DrugUseDetailVo> drugUseDetailVos){

        for (DrugUseDetail detail: drugUseDetailVos) {
            StockInfo existStockInfo = stockInfoService.getById(detail.getStockInfoId());
            if(null == existStockInfo) {
                throw new RuntimeException("所选药品【"+detail.getDeviceName()+"】没有对应的库存，不能使用");
            }
            if(existStockInfo.getStockNum()<detail.getDrugUseNum()){
                throw new RuntimeException("所选药品【"+detail.getDeviceName()+"】使用数量:"+detail.getDrugUseNum()+"，不能大于当前库存总数:"+existStockInfo.getStockNum());

            }
            StockInfo stockInfo=new StockInfo();
            stockInfo.setId(existStockInfo.getId());
            stockInfo.setUsestockTotalNum(existStockInfo.getUsestockTotalNum()+detail.getDrugUseNum());
            stockInfo.setStockNum(existStockInfo.getStockNum()-detail.getDrugUseNum());
            stockInfoService.updateById(stockInfo);
        }

    }




    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean editDrugUseInfo(DrugUseInfoDto drugUseInfoDto, List<MultipartFile> files) {
        boolean flag;
        DrugUseInfo drugUseInfo = this.getById(drugUseInfoDto.getId());
        if (drugUseInfo == null) {
            throw new RuntimeException("修改，参数Id错误");
        }
        if (drugUseInfo.getUsestockStatus()==2) {
            throw new RuntimeException("已确认使用的数据不能修改");
        }
        if (!drugUseInfoDto.getRecordUserId().equals(SecurityUtils.getUserId())) {
            throw new RuntimeException("只能修改自己创建的数据");
        }
        drugUseInfoDto.setUsestockNo(drugUseInfo.getUsestockNo());
        DrugUseInfo data = new DrugUseInfo();
        BeanUtils.copyProperties(drugUseInfoDto, data);

        data.setAnnex(fileInfoService.uploadFiles(files,data.getAnnex()
                ,drugUseInfo.getAnnex(),path,"TF_STOCKS_DRUG_USE_INFO"));

        flag = this.updateById(data);

        drugUseDetailService.remove(Wrappers.<DrugUseDetail>lambdaQuery()
                .eq(DrugUseDetail::getDrugUseId,data.getId()));

        for (DrugUseDetail drugUseDetail : drugUseInfoDto.getDrugUseDetails()
        ) {
            drugUseDetail.setDrugUseId(data.getId());
           drugUseDetailService.save(drugUseDetail);
        }
        if(data.getUsestockStatus()==2){ //已确认的
            AddStockInfo(drugUseInfoDto.getDrugUseDetails()); //加入库存
        }
        return flag;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteByIds(String ids) {

        List<String> lstIds = Arrays.asList(ids.split(","));

        Integer count= this.count(Wrappers.<DrugUseInfo>lambdaQuery()
                .in(DrugUseInfo::getId,lstIds)
                 .and(a->a.eq(DrugUseInfo::getUsestockStatus,2)
                  .or().ne(DrugUseInfo::getRecordUserId,SecurityUtils.getUserId()))

        );

        if(count>0){
            throw new RuntimeException("只能删除自己创建的并且没有确认使用的数据");
        }


        //删除明细
        drugUseDetailService.remove(Wrappers.<DrugUseDetail>lambdaQuery()
                .in(DrugUseDetail::getDrugUseId,lstIds));

        //删除主表
        return this.removeByIds(lstIds);


    }

    @Override
    public Page<DrugUseReportVo> getReportList(Page page,DrugUseReportQuery druguseReportQuery) {
       return getList(page,druguseReportQuery);
    }

    @Override
    public void export(DrugUseReportQuery druguseReportQuery) {
        Page page=new Page();
        page.setSize(10000L);
        page.setCurrent(1L);
        Page<DrugUseReportVo> list=getList(page,druguseReportQuery);
        //导出数据
        ExcelUtils.getListToExcel(DrugUseReportVo.class, list.getRecords(), "水厂药耗分析报表");
    }

    @Override
    public Page<DrugUseInfoVo> getDataPage(Page page, DrugUseInfoQuery drugUseInfoQuery) {

        QueryWrapper<DrugUseInfo> queryWrapper = getDrugUseInfoQueryWrapper(drugUseInfoQuery);

        return super.page(page,queryWrapper);

    }

    /**
     * 查询条件
     * @param drugUseInfoQuery
     * @return
     */
    private  QueryWrapper<DrugUseInfo> getDrugUseInfoQueryWrapper(DrugUseInfoQuery drugUseInfoQuery) {
        QueryWrapper<DrugUseInfo> queryWrapper=new QueryWrapper<>();
        if(drugUseInfoQuery.getDrugUseTimeStart()!=null){

            queryWrapper.ge("DRUG_USE_TIME", drugUseInfoQuery.getDrugUseTimeStart());
        }
        if(drugUseInfoQuery.getDrugUseTimeEnd()!=null){

            queryWrapper.le("DRUG_USE_TIME", drugUseInfoQuery.getDrugUseTimeEnd());
        }

        if(drugUseInfoQuery.getStoreId()!=null && drugUseInfoQuery.getStoreId()>0){

            queryWrapper.eq("STORE_ID", drugUseInfoQuery.getStoreId());
        }

        if(drugUseInfoQuery.getWaterworksId()!=null && drugUseInfoQuery.getWaterworksId()>0){

            queryWrapper.eq("WATERWORKS_ID", drugUseInfoQuery.getWaterworksId());
        }

        if(drugUseInfoQuery.getUsestockStatus()!=null && drugUseInfoQuery.getUsestockStatus()>0){

            queryWrapper.eq("USESTOCK_STATUS", drugUseInfoQuery.getUsestockStatus());
        }

        if(StringUtil.isNotEmpty(drugUseInfoQuery.getUsestockNo())){

            queryWrapper.like("USESTOCK_NO", drugUseInfoQuery.getUsestockNo());
        }
        queryWrapper.orderByDesc("RECORD_TIME");
        return queryWrapper;
    }


    private  Page<DrugUseReportVo> getList(Page page,DrugUseReportQuery drugUseReportQuery){
        String formatTime= getFormatTime(drugUseReportQuery);
        Page<DrugUseReportVo> list=this.baseMapper.getDrugUseReport(page,drugUseReportQuery.getWaterInfoId(),
                formatTime,drugUseReportQuery.getStartTime(),drugUseReportQuery.getEndTime());
        if(list.getRecords().size()>0){
            for (DrugUseReportVo drugUseReportVo: list.getRecords()
            ) {
                Double drugTonTotal=0D;
                Double drugTotal=drugUseReportVo.getDrugTotal();
                double waterTotal=drugUseReportVo.getWaterTotal();
                if(waterTotal==0){
                    waterTotal=1D;
                }
                //保留4位有效数字
                drugTonTotal = (double) Math.round(drugTotal/waterTotal* 10000) / 10000;

                drugUseReportVo.setDrugTonTotal(drugTonTotal);
                drugUseReportVo.setDrugKilotonTotal(drugTonTotal*1000);
            }

        }
        return list;
    }
    private String getFormatTime(DrugUseReportQuery drugUseReportQuery) {
        String formatTime="";
        switch (drugUseReportQuery.getReportType()){
            case "1":
                formatTime="yyyy-mm-dd";
                break;
            case "2":
                formatTime="yyyy-mm";
                break;
            case "3":
                formatTime="yyyy-q";
                break;
            case "4":
                formatTime="yyyy";
                break;
            default:
                break;
        }
        if(StringUtil.isEmpty(formatTime)){
            throw new RuntimeException("报告类型参数错误");
        }
        return formatTime;
    }
}
