package com.zfire.mall.manager.controller.k3;


import cn.hutool.core.lang.TypeReference;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.zfire.mall.manager.annotation.ZfireList;
import com.zfire.mall.manager.bean.ExcelData;
import com.zfire.mall.manager.bean.admin.AdminUserVisitAccBean;
import com.zfire.mall.manager.bean.admin.respDto.AdminUserDto;
import com.zfire.mall.manager.bean.k3.StockPosition;
import com.zfire.mall.manager.bean.k3.StockPositionStock;
import com.zfire.mall.manager.bean.k3.StockPositionStockVO;
import com.zfire.mall.manager.bean.listV2.StockTollVO;
import com.zfire.mall.manager.bean.supplier.KingDeeStockVO;
import com.zfire.mall.manager.bean.supplier.KingDeeSupplierVO;
import com.zfire.mall.manager.constant.Constant;
import com.zfire.mall.manager.exception.RemoteServiceException;
import com.zfire.mall.manager.helper.ResponseHelper;
import com.zfire.mall.manager.logic.k3.K3StockLogic;
import com.zfire.mall.manager.logic.k3.K3SupplierLogic;
import com.zfire.mall.manager.plus.entity.*;
import com.zfire.mall.manager.utils.excel.ExcelUtils;
import com.zfire.mall.manager.zfire.bean.ZfireParamBean;
import com.zfire.mall.manager.zfire.util.FieldUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpRequest;
import org.springframework.integration.redis.util.RedisLockRegistry;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.text.ParseException;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;

/**
 * @author CHANGE
 */
@Slf4j
@RestController
@Api(value = "仓库管理", tags ={"仓库管理"} )
@RequestMapping(value = "/stock", produces = "application/json; charset=utf-8")
public class K3StockController {


    @Autowired
    K3StockLogic k3StockLogic;

    @Autowired
    RedisLockRegistry redisLockRegistry;



    ////////////////////////////////////////仓库预约提货设置////////////////////////////


    @ApiOperation(value = "仓库预约提货设置列表")
    @GetMapping("/listReserve")
    public ResponseHelper<IPage<StockReserve>> listReserve(
            @ApiParam(value = "页号",required = true)@RequestParam(required = true) Integer pageNum,
            @ApiParam(value = "页大小",required = true)@RequestParam(required = true) Integer pageSize
    ) throws Exception {
        IPage<StockReserve> kingDeeSupplier = k3StockLogic.listReserve(pageNum,pageSize);
        return ResponseHelper.success(kingDeeSupplier);
    }


    @PostMapping("/addReserve")
    @ApiOperation("新增仓库预约提货设置")
    public ResponseHelper addReserve(@RequestBody StockReserve stockReserver) throws InterruptedException {
        Lock obtain = redisLockRegistry.obtain(Constant.RedisPrefix.STOCK_RESERVE );
        try {
            if (!obtain.tryLock(5, TimeUnit.SECONDS)) {
                throw new RemoteServiceException("系统繁忙，请稍后再试");
            }
            k3StockLogic.addReserve(stockReserver);
        } finally {
            obtain.unlock();
        }
        return ResponseHelper.success();
    }

    @PostMapping("/updateReserve")
    @ApiOperation("修改仓库预约提货设置")
    public ResponseHelper updateReserve(@RequestBody StockReserve stockReserver) throws InterruptedException {
        Lock obtain = redisLockRegistry.obtain(Constant.RedisPrefix.STOCK_RESERVE +stockReserver.getCorrespondId());
        try {
            if (!obtain.tryLock(5, TimeUnit.SECONDS)) {
                throw new RemoteServiceException("系统繁忙，请稍后再试");
            }
            k3StockLogic.updateReserve(stockReserver);
        } finally {
            obtain.unlock();
        }
        return ResponseHelper.success();
    };

    /////////////////////////仓储费规则配置///////////////////////////////////////


    @ApiOperation(value = "仓储费规则配置列表")
    @GetMapping("/listToll")
    public ResponseHelper<IPage<StockToll>> listToll(
            @ApiParam(value = "免费天数",required = false)@RequestParam(required = false) BigDecimal freeDay,
            @ApiParam(value = "费用",required = false)@RequestParam(required = false) BigDecimal toll,
            @ApiParam(value = "经销商名称",required = false)@RequestParam(required = false) String customerName,
            @ApiParam(value = "页号",required = true)@RequestParam(required = true) Integer pageNum,
            @ApiParam(value = "页大小",required = true)@RequestParam(required = true) Integer pageSize
    ) throws Exception {
        IPage<StockToll> kingDeeSupplier = k3StockLogic.listToll(freeDay,toll,customerName,pageNum,pageSize);
        return ResponseHelper.success(kingDeeSupplier);
    }


    @ZfireList
    @PostMapping("/listTollV2")
    @ApiOperation("仓储费规则配置-列表V2")
    public ResponseHelper<IPage<StockTollVO>> listTollV2(
            @RequestBody ZfireParamBean zfireParamBean
    ) throws RemoteServiceException {
        IPage<StockTollVO> list = k3StockLogic.listTollV2(zfireParamBean);
        return ResponseHelper.success(list, new TypeReference<StockTollVO>() {});
    }

    @PostMapping("/listTollV2/export")
    @ApiOperation("仓储费规则配置-列表V2导出")
    public void listTollV2Export(
            @RequestBody ZfireParamBean zfireParamBean,
            HttpServletRequest request,
            HttpServletResponse response
    ) throws Exception {
        //1.组装查询条件
        ZfireParamBean zfireParam = FieldUtils.supplyParam(zfireParamBean);
        //2.查询要导出的内容
        IPage<StockTollVO> list = k3StockLogic.listTollV2(zfireParamBean);
        //3.导出
        FieldUtils.exportData(list.getRecords(),zfireParam.getExportFields(),request,response);
    }



    @PostMapping("/addToll")
    @ApiOperation("新增仓储费规则配置")
    public ResponseHelper addToll(@RequestBody StockToll stockToll, HttpServletRequest request) throws InterruptedException {
        Lock obtain = redisLockRegistry.obtain(Constant.RedisPrefix.STOCK_RESERVE +stockToll.getCustomerNumber());
        try {
            if (!obtain.tryLock(5, TimeUnit.SECONDS)) {
                throw new RemoteServiceException("系统繁忙，请稍后再试");
            }
            k3StockLogic.addToll(stockToll,request);
        } finally {
            obtain.unlock();
        }

        return ResponseHelper.success();
    }

    @PostMapping("/updateToll")
    @ApiOperation("修改仓储费规则配置")
    public ResponseHelper updateToll(@RequestBody StockToll stockToll, HttpServletRequest request) throws InterruptedException {
        Lock obtain = redisLockRegistry.obtain(Constant.RedisPrefix.STOCK_RESERVE +stockToll.getCustomerNumber());
        try {
            if (!obtain.tryLock(5, TimeUnit.SECONDS)) {
                throw new RemoteServiceException("系统繁忙，请稍后再试");
            }
            k3StockLogic.updateToll(stockToll,request);
        } finally {
            obtain.unlock();
        }
        return ResponseHelper.success();
    }

    @GetMapping("/deleteToll")
    @ApiOperation(value = "仓储费规则配置删除")
    public ResponseHelper deleteToll(
            @ApiParam(required = true, value = "id") @RequestParam(required = true) String id
    ){
        k3StockLogic.deleteToll(id);
        return ResponseHelper.success();
    }

    @ApiOperation(value = "仓储费规则详情")
    @GetMapping("/detailToll")
    public ResponseHelper<StockToll> detailToll(
            @ApiParam(required = true, value = "id") @RequestParam(required = true) String id
    ) throws Exception {
        StockToll stockToll = k3StockLogic.detailToll(id);
        return ResponseHelper.success(stockToll);
    }

    @PostMapping("/importToll")
    @ApiOperation("仓储费规则导入")
    public ResponseHelper<String> importToll(
            @ApiParam(required = true, value = "附件") @RequestPart("file") MultipartFile file,
            HttpServletRequest request
    ) throws RemoteServiceException, IOException, ParseException {
        InputStream inputStream = file.getInputStream();
        k3StockLogic.importToll(inputStream,request);
        return ResponseHelper.success();
    }

    @GetMapping("/exportToll")
    @ApiOperation(value = "商户列表导出")
    public void exportToll(
            @ApiParam(value = "免费天数",required = false)@RequestParam(required = false) BigDecimal freeDay,
            @ApiParam(value = "费用",required = false)@RequestParam(required = false) BigDecimal toll,
            @ApiParam(value = "经销商名称",required = false)@RequestParam(required = false) String customerName,
            HttpServletRequest request,
            HttpServletResponse response
    ) throws Exception {
        IPage<StockToll> kingDeeSupplier = k3StockLogic.listToll(freeDay,toll,customerName,1,-1);
        ExcelData excelData = k3StockLogic.exportToll(kingDeeSupplier.getRecords());
        ExcelUtils.exportExcel(request,response,"商户列表.xlsx",excelData);
    }

    //////////////////////////////////仓库仓位对应关系//////////////////////////////////////////////

    @PostMapping("/addStock")
    @ApiOperation("新增仓库仓位对应关系")
    public ResponseHelper addStock(@RequestBody StockPosition stockPosition, HttpServletRequest request) throws InterruptedException {
        Lock obtain = redisLockRegistry.obtain(Constant.RedisPrefix.STOCK_RESERVE +stockPosition.getName());
        try {
            if (!obtain.tryLock(5, TimeUnit.SECONDS)) {
                throw new RemoteServiceException("系统繁忙，请稍后再试");
            }
            k3StockLogic.addStock(stockPosition,request);
        } finally {
            obtain.unlock();
        }
        return ResponseHelper.success();
    }

    @ApiOperation(value = "仓库仓位对应关系列表")
    @GetMapping("/listStock")
    public ResponseHelper<IPage<StockPositionStock>> listStock(
            @ApiParam(value = "仓库名称",required = false)@RequestParam(required = false) String name,
            @ApiParam(value = "仓位名称",required = false)@RequestParam(required = false) String stockName,
            @ApiParam(value = "页号",required = true)@RequestParam(required = true) Integer pageNum,
            @ApiParam(value = "页大小",required = true)@RequestParam(required = true) Integer pageSize
    ) throws Exception {
        IPage<StockPositionStock> stockIPage = k3StockLogic.listStock(name,stockName,pageNum,pageSize);
        return ResponseHelper.success(stockIPage);
    }



    @ZfireList
    @PostMapping("/listStockV2")
    @ApiOperation("仓库仓位对应关系-列表V2")
    public ResponseHelper<IPage<StockPositionStockVO>> listStockV2(
            @RequestBody ZfireParamBean zfireParamBean
    ) throws RemoteServiceException {
        IPage<StockPositionStockVO> list = k3StockLogic.listStockV2(zfireParamBean);
        return ResponseHelper.success(list, new TypeReference<KingDeeStockVO>() {});
    }

    @PostMapping("/listStockV2/export")
    @ApiOperation("仓库仓位对应关系-列表V2导出")
    public void listStockV2Export(
            @RequestBody ZfireParamBean zfireParamBean,
            HttpServletRequest request,
            HttpServletResponse response
    ) throws Exception {
        //1.组装查询条件
        ZfireParamBean zfireParam = FieldUtils.supplyParam(zfireParamBean);
        //2.查询要导出的内容
        IPage<StockPositionStockVO> list = k3StockLogic.listStockV2(zfireParamBean);
        //3.导出
        FieldUtils.exportData(list.getRecords(),zfireParam.getExportFields(),request,response);
    }


    @ApiOperation(value = "仓库仓位对应关系详情")
    @GetMapping("/detailStock")
    public ResponseHelper<StockPositionStock> detailStock(
            @ApiParam(required = true, value = "id") @RequestParam(required = true) String id
    ) throws Exception {
        StockPositionStock sockPosition = k3StockLogic.detailStock(id);
        return ResponseHelper.success(sockPosition);
    }

    @PostMapping("/updateStock")
    @ApiOperation("修改仓库仓位对应关系")
    public ResponseHelper updateStock(@RequestBody StockPosition stockPosition, HttpServletRequest request) throws InterruptedException {
        Lock obtain = redisLockRegistry.obtain(Constant.RedisPrefix.STOCK_RESERVE +stockPosition.getName());
        try {
            if (!obtain.tryLock(5, TimeUnit.SECONDS)) {
                throw new RemoteServiceException("系统繁忙，请稍后再试");
            }
            k3StockLogic.updateStock(stockPosition,request);
        } finally {
            obtain.unlock();
        }
        return ResponseHelper.success();
    }

    @GetMapping("/deleteStock")
    @ApiOperation(value = "仓库仓位对应关系删除")
    public ResponseHelper deleteStock(
            @ApiParam(required = true, value = "id") @RequestParam(required = true) List<String> id
    ){
        k3StockLogic.deleteStock(id);
        return ResponseHelper.success();
    }


    ///////////////////////////仓库列表///////////////////////////////////


    @ZfireList
    @PostMapping("/listV2")
    @ApiOperation("仓库-列表V2")
    public ResponseHelper<IPage<KingDeeStockVO>> listV2(
            @RequestBody ZfireParamBean zfireParamBean
    ) throws RemoteServiceException {
        IPage<KingDeeStockVO> list = k3StockLogic.listV2(zfireParamBean);
        return ResponseHelper.success(list, new TypeReference<KingDeeStockVO>() {});
    }

    @PostMapping("/listV2/export")
    @ApiOperation("仓库-列表V2导出")
    public void listExport(
            @RequestBody ZfireParamBean zfireParamBean,
            HttpServletRequest request,
            HttpServletResponse response
    ) throws Exception {
        //1.组装查询条件
        ZfireParamBean zfireParam = FieldUtils.supplyParam(zfireParamBean);
        //2.查询要导出的内容
        IPage<KingDeeStockVO> list = k3StockLogic.listV2(zfireParamBean);
        //3.导出
        FieldUtils.exportData(list.getRecords(),zfireParam.getExportFields(),request,response);
    }


    @ApiOperation(value = "仓库列表")
    @GetMapping("/list")
    public ResponseHelper<IPage<KingDeeStock>> list(
            @ApiParam(value = "仓库名称",required = false)@RequestParam(required = false) String name,
            @ApiParam(value = "1允许客户查询  2全部客户查询",required = false)@RequestParam(required = false) Integer Inquire,
            @ApiParam(value = "1虚拟仓 0正常",required = false)@RequestParam(required = false) Integer stockType,
            @ApiParam(value = "页号",required = true)@RequestParam(required = true) Integer pageNum,
            @ApiParam(value = "页大小",required = true)@RequestParam(required = true) Integer pageSize
    ) throws Exception {
        IPage<KingDeeStock> stockIPage = k3StockLogic.list(name,Inquire,stockType,pageNum,pageSize);
        return ResponseHelper.success(stockIPage);
    }

    @ApiOperation(value = "仓库详情")
    @GetMapping("/detail")
    public ResponseHelper<KingDeeStock> detail(
            @ApiParam(required = true, value = "id") @RequestParam(required = true) String id
    ) throws Exception {
        KingDeeStock kingDeeStock = k3StockLogic.detail(id);
        return ResponseHelper.success(kingDeeStock);
    }


    @ApiOperation(value = "修改仓库")
    @GetMapping("/update")
    public ResponseHelper update(
            @ApiParam(required = true, value = "id") @RequestParam(required = true) String id,
            @ApiParam(required = true,value = "1允许客户查询  0不允许") @RequestParam(required = true) Integer inquire,
            @ApiParam(required = true,value = "1虚拟仓 0正常") @RequestParam(required = true) Integer stockType
    ) throws Exception {
         k3StockLogic.update(id,inquire,stockType);
        return ResponseHelper.success();
    }


    @ApiOperation(value = "库存到货访问通知-列表")
    @GetMapping("/visit/list")
    public ResponseHelper<IPage<AdminUserVisitAccBean>> visitList(
            @ApiParam(required = false, value = "规格型号") @RequestParam(required = false) String specification,
            @ApiParam(value = "页号",required = true)@RequestParam(required = true) Integer pageNum,
            @ApiParam(value = "页大小",required = true)@RequestParam(required = true) Integer pageSize,
            HttpServletRequest request
    ) throws Exception {
        IPage<AdminUserVisitAccBean> page = k3StockLogic.visitAccList(specification,pageNum, pageSize,request);
        return ResponseHelper.success(page);
    }


    @ApiOperation(value = "库存到货访问通知-数量")
    @GetMapping("/visit/count")
    public ResponseHelper<Integer> visitCount() throws Exception {
        Integer total = k3StockLogic.visitAccCount();
        return ResponseHelper.success(total);
    }



}
