package com.sy.coinage.workshop.controller;

import com.sy.coinage.core.annotation.LoginNotRequired;
import com.sy.coinage.core.req.IdReq;
import com.sy.coinage.core.util.Arith;
import com.sy.coinage.sys.service.IDictService;
import com.sy.coinage.workshop.service.IBaseInfoService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import com.sy.coinage.core.annotation.ActiveFastJsonProfile;
import com.sy.coinage.core.annotation.CurrentUser;
import com.sy.coinage.core.controller.BaseController;
import com.sy.coinage.core.vo.*;

import com.sy.coinage.workshop.model.*;
import com.sy.coinage.workshop.service.IStockService;
import com.sy.coinage.workshop.vo.*;
import com.sy.coinage.workshop.req.*;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;

import javax.validation.Valid;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * -实时库存表Controller
 */
@Api(value = "实时库存表接口", tags = {"实时库存表接口"})
@RestController
@RequestMapping(value = "/stock")
public class StockController extends BaseController {

    @Autowired
    private IStockService stockService;

    @Autowired
    private IDictService dictService;

    @Autowired
    private IBaseInfoService baseInfoService;

    @ApiOperation(value = "实时库存表头")
    @GetMapping("/header")
    public List<StockHeaderVO> header(@CurrentUser CacheUserVO user) {
        List<OptVO> wareOpt = this.dictService.opt("wareOpt", -1);
        List<StockHeaderVO> data = new ArrayList<>();
        data.add(new StockHeaderVO("序号", "no", 50));
        data.add(new StockHeaderVO("品名", "securities", 100));
        for (OptVO vo : wareOpt) {
            data.add(new StockHeaderVO(vo.getName(), vo.getVal(), null));
        }
        data.add(new StockHeaderVO("品种合计", "total", null));
        return data;
    }

    /**
     * 实时库存表分页列表
     */
    @ApiOperation(value = "实时库存表分页列表")
    @PostMapping("/list")
    @ActiveFastJsonProfile(groups = "list", clazz = Stock.class)
    public List<Stock> list(@RequestBody StockListReq req, @CurrentUser CacheUserVO user) {
        List<Stock> data = new ArrayList<>();
        List<OptVO> wareOpt = this.dictService.opt("wareOpt", -1);
        List<String> collect = wareOpt.stream().map(item -> item.getVal()).collect(Collectors.toList());
        LambdaQueryWrapper<Stock> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(Stock::getWareId, collect);
        List<Stock> list = this.stockService.list(queryWrapper);
        List<Stock> collect1 = list.stream()
                .collect(Collectors.collectingAndThen(
                        Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(item -> item.getSecuritiesId()))),
                        ArrayList::new)
                );
        Integer ttt1 = 0;
        Integer ttt2 = 0;
        for (Stock stock : collect1) {
            Stock t = new Stock();
            t.setId(stock.getId());
            t.setSecurities(stock.getSecurities());
            Map<String, StockVO> m = new HashMap<>();
            Integer tt1 = 0;
            Integer tt2 = 0;
            for (OptVO optVO : wareOpt) {
                List<Stock> collect2 = list.stream().filter(item -> item.getSecuritiesId().equals(stock.getSecuritiesId()) && String.valueOf(item.getWareId()).equals(optVO.getVal())).collect(Collectors.toList());
                Integer t1 = collect2.stream().mapToInt(s -> Objects.isNull(s.getRacketNum()) ? 0 : s.getRacketNum()).sum();
                Integer t2 = collect2.stream().mapToInt(s -> Objects.isNull(s.getBoxNum()) ? 0 : s.getBoxNum()).sum();
                m.put(optVO.getVal(), new StockVO(t1, t2));
                tt1 = tt1 + t1;
                tt2 = tt2 + t2;
            }
            m.put("total", new StockVO(tt1, tt2));
            t.setMap(m);
            data.add(t);
        }
        List<OptVO> wareRatioOpt = this.dictService.opt("wareRatioOpt", -1);
        Stock to2 = new Stock();
        to2.setSecurities("库合计");
        Map<String, StockVO> m = new HashMap<>();
        Integer tt1 = 0;
        Integer tt2 = 0;
        Map<String, StockVO> m3 = new HashMap<>();
        Integer totalRatio = 0;
        for (OptVO optVO : wareOpt) {
            List<Stock> collect2 = list.stream()
                    .filter(item -> String.valueOf(item.getWareId()).equals(optVO.getVal()))
                    .collect(Collectors.toList());
            Integer t1 = collect2.stream()
                    .mapToInt(s -> Objects.isNull(s.getRacketNum()) ? 0 : s.getRacketNum()).sum();
            Integer t2 = collect2.stream()
                    .mapToInt(s -> Objects.isNull(s.getBoxNum()) ? 0 : s.getBoxNum()).sum();
            m.put(optVO.getVal(), new StockVO(t1, t2));
            tt1 = tt1 + t1;
            tt2 = tt2 + t2;
            // 字典库占比
            OptVO wareRatio = wareRatioOpt.stream()
                    .filter(item -> item.getName().equals(optVO.getName())).findFirst().get();
            // 库占比
            Integer total = t1 + t2;
            totalRatio = totalRatio + Integer.parseInt(wareRatio.getVal());
            Double b = 0.0;
            if (total > 0) {
                BigDecimal d1 = new BigDecimal(total * 100);
                BigDecimal d2 = new BigDecimal(totalRatio);
                b = d1.divide(d2, 2, RoundingMode.HALF_UP).doubleValue();
            }
            m3.put(optVO.getVal(), new StockVO(Arith.round(b, 2), 0));
        }
        ttt1 = ttt1 + tt1;
        ttt2 = ttt2 + tt2;
        m.put("total", new StockVO(ttt1, ttt2));
        to2.setMap(m);
        data.add(to2);
        Stock to3 = new Stock();
        to3.setSecurities("库占比");
        // 库占比
        Integer total = ttt1 + ttt2;
        Double b = 0.0;
        if (total > 0) {
            BigDecimal d1 = new BigDecimal(total * 100);
            BigDecimal d2 = new BigDecimal(totalRatio);
            b = d1.divide(d2, 2, RoundingMode.HALF_UP).doubleValue();
        }
        m3.put("total", new StockVO(b, 0));
        to3.setMap(m3);
        data.add(to3);
        return data;
    }


    @ApiOperation(value = "临时库库位状态")
    @LoginNotRequired
    @PostMapping("/getShopWare")
    public ShopWareStatusVO getShopWare(@RequestBody @Valid IdReq req) {
        ShopWareStatusVO data = new ShopWareStatusVO();
        LambdaQueryWrapper<Stock> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Stock::getWareId, req.getId());
        queryWrapper.orderByDesc(Stock::getId);
        List<Stock> list = this.stockService.list(queryWrapper);
        for (Stock stock : list) {
            if (stock.getAreaId().intValue() == 1) {
                data.setProdWare(stock);
                data.setDetailList(this.getDetailList(req.getId(), stock.getSecuritiesId()));
            } else if (stock.getAreaId().intValue() == 2) {
                data.setEliminateWare(stock);
            }
        }
        return data;
    }

    @ApiOperation(value = "主库库位状态")
    @LoginNotRequired
    @GetMapping("/getWare/{wareId}")
    public List<WareStatusVO> getWare(@PathVariable Integer wareId) {
        List<WareStatusVO> data = new ArrayList<>();
        LambdaQueryWrapper<Stock> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Stock::getWareId, wareId);
        List<Stock> list = this.stockService.list(queryWrapper);
        List<OptVO> areaList = this.dictService.opt(String.valueOf(wareId), null);
        for (OptVO optVO : areaList) {
            WareStatusVO vo = new WareStatusVO();
            vo.setAreaId(Integer.parseInt(optVO.getVal()));
            List<Stock> collect = list.stream().filter(item -> item.getAreaId().intValue() == vo.getAreaId().intValue()).collect(Collectors.toList());
            List<Stock> collect1 = collect.stream().filter(item -> (item.getRacketNum() + item.getBoxNum() + item.getPiecesTotal() + item.getCheckBoxNum()) > 0).collect(Collectors.toList());
            vo.setDetailList(collect1);
            data.add(vo);
        }
        return data;
    }

    private List<BaseInfo> getDetailList(Integer selfWareId, Integer securitiesId) {
        LambdaQueryWrapper<BaseInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(BaseInfo::getSecuritiesId, securitiesId);
        queryWrapper.eq(BaseInfo::getLocWareId, selfWareId);
        queryWrapper.eq(BaseInfo::getLocAreaId, 1);
        queryWrapper.eq(BaseInfo::getStatus, 2);
        //<modify by hliu date=20241116>
        //<comment>绑定rfid数据的来源类型： 1:封包线整拍数据 2.封包线非整拍数据 ，
        // 原始非整拍数据也应该显示到页面上,因此条件是小于3的都可以显示</comment>
       //<old>
//        queryWrapper.eq(BaseInfo::getOriginType, 1);
        //</old>
        //<new>
        queryWrapper.lt(BaseInfo::getOriginType, 3);
        //</new>
//        queryWrapper.and(
//                qw -> qw.eq(BaseInfo::getUnpackageStatus, 1).or().isNull(BaseInfo::getUnpackageStatus));
//        queryWrapper.ne(BaseInfo::getUnpackageStatus, 2);
//        queryWrapper.ne(BaseInfo::getReturnCheckStatus, 2);
        List<BaseInfo> data = this.baseInfoService.list(queryWrapper);
        return data;
    }

}
