package com.cyksj.web.controller.manage.stock;

import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.cyksj.common.annotation.Log;
import com.cyksj.common.exception.BusinessRuntimeException;
import com.cyksj.dto.Result;
import com.cyksj.enums.BusinessType;
import com.cyksj.enums.GatewayResponse;
import com.cyksj.mapper.manage.cms.CmsUserMapper;
import com.cyksj.mapper.stock.GoodsSkuStockRelateMapper;
import com.cyksj.model.entity.CmsUser;
import com.cyksj.model.entity.GoodsDonStock;
import com.cyksj.model.entity.GoodsDonStockRecord;
import com.cyksj.model.entity.GoodsSkuStockRelate;
import com.cyksj.model.request.StockUpReq;
import com.cyksj.service.mange.stock.GoodsDonStockService;
import com.ejlchina.searcher.BeanSearcher;
import com.ejlchina.searcher.SearchResult;
import com.ejlchina.searcher.util.MapUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;

/**
 * @author chan
 * @date 2022/12/6 4:14 PM
 */
@RequestMapping("/manage/stock")
@RestController
@RequiredArgsConstructor
@Slf4j
public class StockController {

    private final HttpServletRequest request;

    private final BeanSearcher beanSearcher;

    private final GoodsDonStockService stockService;

    private final CmsUserMapper cmsUserMapper;

    private final GoodsSkuStockRelateMapper skuStockRelateMapper;

    @GetMapping
    public Result<SearchResult<GoodsDonStock>> get(){
        SearchResult<GoodsDonStock> search = beanSearcher.search(GoodsDonStock.class, MapUtils.flatBuilder(request.getParameterMap()).build());
        search.getDataList().forEach(data->{
            data.setRelateList(skuStockRelateMapper.selectList(Wrappers.lambdaQuery(GoodsSkuStockRelate.class)
                    .eq(GoodsSkuStockRelate::getStockId, data.getId())));
        });
        return GatewayResponse.SUCCESS.newBuilder().toResult(search);
    }

    /**
     * 新增库存
     */
    @PostMapping("/incr")
    @Log(module = "库存管理/增加库存", businessType = BusinessType.POST, isSaveRequestData = true)
    public Result<String> incr(@RequestBody StockUpReq stock){
        if (stock.getNum() <= 0) {
            throw BusinessRuntimeException.getInstance("新增库存数量不能为负数");
        }
        if (stock.getPrice() == null) {
            throw BusinessRuntimeException.getInstance("请填写进价");
        }
        if(StringUtils.isBlank(stock.getVoucher())){
            throw BusinessRuntimeException.getInstance("请添加凭证");
        }
        stockService.incr(stock);
        return GatewayResponse.SUCCESS.newBuilder().toResult();
    }

    /**
     * 扣减库存
     */
    @PostMapping("/sub")
    @Log(module = "库存管理/扣减库存", businessType = BusinessType.PUT, isSaveRequestData = true)
    public Result<String> sub(@RequestBody StockUpReq stock){
        stockService.sub(stock);
        return GatewayResponse.SUCCESS.newBuilder().toResult();
    }

    /**
     * 撤销库存变动操作
     */
    @PutMapping("/undo/change/{recordId}")
    public Result<String> undoChangeSku(@PathVariable Long recordId) {
        stockService.undoChange(recordId);
        return GatewayResponse.SUCCESS.newBuilder().toResult();
    }


    /**
     * 编辑不可用
     */
    @PutMapping("/put/unavailable")
    @Deprecated
    public Result<String> upUnavailable(@RequestBody StockUpReq stock){
        if(StringUtils.isBlank(stock.getRemark())){
            throw BusinessRuntimeException.getInstance("请填写备注");
        }
        stockService.upUnavailable(stock);
        return GatewayResponse.SUCCESS.newBuilder().toResult();
    }

    /**
     * 编辑已刷机
     */
    @PutMapping("/put/upgrade")
    @Deprecated
    public Result<String> upgrade(@RequestBody StockUpReq stock){
        stockService.upgrade(stock);
        return GatewayResponse.SUCCESS.newBuilder().toResult();
    }

    /**
     * 新建库存
     */
    @PostMapping
    public Result<String> save(@RequestBody GoodsDonStock stock){
        if (stock.getRelateList().size() == 0) {
            throw BusinessRuntimeException.getInstance("缺少关联商品");
        }
        if (stock.getRecord() == null) {
            throw BusinessRuntimeException.getInstance("缺少明细凭证等信息");
        }
        stockService.save(stock);
        return GatewayResponse.SUCCESS.newBuilder().toResult();
    }

    /**
     * 编辑库存商品绑定实物商品
     */
    @PutMapping("/update/bindGoods")
    public Result<String> updateBindGoods(@RequestBody GoodsDonStock stock) {
        long adminId = StpUtil.getLoginIdAsLong();
        Long id = stock.getId();
        if (id == null) {
            throw BusinessRuntimeException.getInstance("库存id不存在");
        }
        if (stock.getRelateList().size() == 0) {
            throw BusinessRuntimeException.getInstance("缺少关联商品");
        }
        CmsUser cmsUser = cmsUserMapper.selectById(adminId);
        stock.setOperator(cmsUser.getNickname());
        stockService.updateBindGoods(stock);
        return GatewayResponse.SUCCESS.newBuilder().toResult();
    }

    /*
    库存明细
    ------------------------------------------------------------------
    */

    /**
     * 库存列表
     */
    @GetMapping("/get/record")
    public Result<SearchResult<GoodsDonStockRecord>> getRecord(){
        SearchResult<GoodsDonStockRecord> search = beanSearcher.search(GoodsDonStockRecord.class, MapUtils.flatBuilder(request.getParameterMap()).build());
        search.getDataList().forEach((record)->{
            record.setPrice(record.getPrice().multiply(BigDecimal.valueOf(record.getNum())));
        });
        return GatewayResponse.SUCCESS.newBuilder().toResult(search);
    }

    /**
     * 编辑备注
     */
    @PutMapping("/put/record")
    public Result<String> upRecord(@RequestBody GoodsDonStockRecord record){
        if (record.getId() == null) {
            throw BusinessRuntimeException.getInstance("缺少必填参数.");
        }
        stockService.upRecord(record);
        return GatewayResponse.SUCCESS.newBuilder().toResult();
    }

    @DeleteMapping("/del/{stockId}")
    public Result<String> del(@PathVariable Long stockId){
        stockService.del(stockId);
        return GatewayResponse.SUCCESS.newBuilder().toResult();
    }


}
