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


import cn.hutool.core.lang.TypeReference;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.zfire.mall.manager.annotation.ApiNotAuth;
import com.zfire.mall.manager.annotation.ZfireList;
import com.zfire.mall.manager.bean.ExcelData;
import com.zfire.mall.manager.bean.admin.AdminUserCom;
import com.zfire.mall.manager.bean.invoice.InvoiceProjectVO;
import com.zfire.mall.manager.bean.k3.KingDeeMaterialBean;
import com.zfire.mall.manager.bean.k3.StockPositionStock;
import com.zfire.mall.manager.bean.listV2.dto.InvoiceProjectDTO;
import com.zfire.mall.manager.bean.reserved.*;
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.common.CommonLogic;
import com.zfire.mall.manager.logic.reserved.ReservedLogic;
import com.zfire.mall.manager.plus.entity.KingDeeCustomer;
import com.zfire.mall.manager.plus.entity.KingDeeMaterial;
import com.zfire.mall.manager.utils.CommonUtils;
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.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
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.util.List;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;

/**
 * @author CHANGE
 */
@Slf4j
@RestController
@Api(value = "预留单", tags = {"预留单"})
@RequestMapping(value = "/reserve", produces = "application/json; charset=utf-8")
public class ReservedController {


    @Autowired
    RedisLockRegistry redisLockRegistry;

    @Autowired
    ReservedLogic reservedLogic;

    @Autowired
    CommonLogic commonLogic;



    @ApiOperation(value = "订单选择列表")
    @GetMapping("/listOrder")
    public ResponseHelper<IPage<ReservedOrderBean>> listOrder(
            @ApiParam(required = false, value = "销售单号") @RequestParam(required = false) String orderId,
            @ApiParam(required = false, value = "经销商名称") @RequestParam(required = false) String customerName,
            @ApiParam(required = false, value = "经销商编号") @RequestParam(required = false) String customerNumber,
            @ApiParam(required = false, value = "产品类别") @RequestParam(required = false) String mainName,
            @ApiParam(required = false, value = "产品编码") @RequestParam(required = false) String materialCode,
            @ApiParam(required = false, value = "物料代码") @RequestParam(required = false) String materialOldNumber,
            @ApiParam(required = false, value = "产品名称") @RequestParam(required = false) String materialName,
            @ApiParam(required = false, value = "规格型号") @RequestParam(required = false) String specification,
            @ApiParam(value = "仓库id",required = false)@RequestParam(required = false) String correspondId,
            @ApiParam(required = false, value = "订单类型 TRADE=商用 HOME=家用 RETAIL=零售单 RETAIL_POLICY 销售政策单  PERMU 置换单") @RequestParam(required = false) String orderType,
            @ApiParam(value = "页号", required = true) @RequestParam Integer pageNum,
            @ApiParam(value = "页大小", required = true) @RequestParam Integer pageSize
    ) throws Exception {
        IPage<ReservedOrderBean> reservedOrderIPage = reservedLogic.listOrder(materialOldNumber, correspondId,customerName, orderId, specification, mainName, orderType, customerNumber, materialCode, materialName, pageNum, pageSize);
        return ResponseHelper.success(reservedOrderIPage);
    }


    @ApiOperation(value = "预留单列表")
    @GetMapping("/list")
    public ResponseHelper<IPage<ReservedBean>> list(
            @ApiParam(required = false, value = "预留单号") @RequestParam(required = false) String id,
            @ApiParam(required = false, value = "销售单号") @RequestParam(required = false) String orderId,
            @ApiParam(required = false, value = "经销商名称") @RequestParam(required = false) String customerName,
            @ApiParam(required = false, value = "产品编码") @RequestParam(required = false) String materialCode,
            @ApiParam(required = false, value = "产品名称") @RequestParam(required = false) String materialName,
            @ApiParam(required = false, value = "规格型号") @RequestParam(required = false) String specification,
            @ApiParam(required = false, value = "预留开始时间") @RequestParam(required = false) String startTime,
            @ApiParam(required = false, value = "预留结束时间") @RequestParam(required = false) String endTime,
            @ApiParam(required = false, value = "经销商编号") @RequestParam(required = false) String customerNumber,
            @ApiParam(required = false, value = "创建人") @RequestParam(required = false) String createBy,
            @ApiParam(required = false, value = "修改人") @RequestParam(required = false) String updateBy,
            @ApiParam(value = "仓库id",required = false)@RequestParam(required = false) String correspondId,
            @ApiParam(required = false, value = "1 打开 0关闭") @RequestParam(required = false) Integer status,
            @ApiParam(value = "页号", required = true) @RequestParam Integer pageNum,
            @ApiParam(value = "页大小", required = true) @RequestParam Integer pageSize
    ) throws Exception {
        IPage<ReservedBean> reservedBeanIPage = reservedLogic.list(createBy,updateBy,id,status, correspondId,customerName, orderId, specification, startTime, endTime, customerNumber, materialCode, materialName, pageNum, pageSize);
        return ResponseHelper.success(reservedBeanIPage);
    }


    @ZfireList
    @PostMapping("/listV2")
    @ApiOperation("预留单列表-列表V2")
    public ResponseHelper<IPage<ReservedBeanVO>> listV2(
            @RequestBody ZfireParamBean zfireParamBean
    ) throws RemoteServiceException {
        IPage<ReservedBeanVO> list = reservedLogic.listV2(zfireParamBean);
        return ResponseHelper.success(list, new TypeReference<ReservedBeanVO>() {});
    }

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

    @ApiOperation(value = "预留单详情")
    @GetMapping("/detail")
    public ResponseHelper<ReservedDetail> detail(
            @ApiParam(required = true, value = "id") @RequestParam(required = true) String id
    ) throws Exception {
        ReservedDetail reservedDetail = reservedLogic.detail(id);
        return ResponseHelper.success(reservedDetail);
    }


    @PostMapping("/add")
    @ApiOperation("预留单添加")
    public ResponseHelper add(@RequestBody ReservedAdd reservedAdd, HttpServletRequest request) throws Exception {
        Lock obtain = redisLockRegistry.obtain(Constant.RedisPrefix.RESERVED_APPLICATION);
        try {
            if (!obtain.tryLock(5, TimeUnit.SECONDS)) {
                throw new RemoteServiceException("系统繁忙，请稍后再试");
            }

            AdminUserCom adminUser = commonLogic.getAdminUser();

            if (adminUser.getIsCustomer())
                throw new RemoteServiceException("经销商不可操作预留单");

            reservedLogic.add(reservedAdd);
        } finally {
            obtain.unlock();
        }
        return ResponseHelper.success();
    }

    @PostMapping("/close")
    @ApiOperation("预留单关闭")
    public ResponseHelper update( @ApiParam(required = false, value = "预留详细单号") @RequestParam(required = false) String itemId,
                                  HttpServletRequest request) throws Exception {
        Lock obtain = redisLockRegistry.obtain(Constant.RedisPrefix.RESERVED_APPLICATION+itemId);
        try {
            if (!obtain.tryLock(5, TimeUnit.SECONDS)) {
                throw new RemoteServiceException("系统繁忙，请稍后再试");
            }
            reservedLogic.update(itemId, request);
        } finally {
            obtain.unlock();
        }
        return ResponseHelper.success();
    }

    @PostMapping("/closeList")
    @ApiOperation("批量预留单关闭")
    public ResponseHelper closeList( @ApiParam(required = false, value = "预留详细单号") @RequestParam(required = false) List<String> itemId,
                                  HttpServletRequest request) throws Exception {

            reservedLogic.closeList(itemId, request);

        return ResponseHelper.success();
    }

    @PostMapping("/updateReserved")
    @ApiOperation("预留单修改")
    public ResponseHelper updateReserved( @RequestBody ReservedAdd reservedAdd,
                                  HttpServletRequest request) throws Exception {
        Lock obtain = redisLockRegistry.obtain(Constant.RedisPrefix.RESERVED_APPLICATION+reservedAdd.getId());
        try {
            if (!obtain.tryLock(5, TimeUnit.SECONDS)) {
                throw new RemoteServiceException("系统繁忙，请稍后再试");
            }
            reservedLogic.updateReserved(reservedAdd, request);
        } finally {
            obtain.unlock();
        }
        return ResponseHelper.success();
    }

    @ApiOperation(value = "预留单列表-导出")
    @GetMapping("/export")
    public void list(
            @ApiParam(required = false, value = "预留单号") @RequestParam(required = false) String id,
            @ApiParam(required = false, value = "销售单号") @RequestParam(required = false) String orderId,
            @ApiParam(required = false, value = "经销商名称") @RequestParam(required = false) String customerName,
            @ApiParam(required = false, value = "产品编码") @RequestParam(required = false) String materialCode,
            @ApiParam(required = false, value = "产品名称") @RequestParam(required = false) String materialName,
            @ApiParam(required = false, value = "规格型号") @RequestParam(required = false) String specification,
            @ApiParam(required = false, value = "预留开始时间") @RequestParam(required = false) String startTime,
            @ApiParam(required = false, value = "预留结束时间") @RequestParam(required = false) String endTime,
            @ApiParam(required = false, value = "创建人") @RequestParam(required = false) String createBy,
            @ApiParam(required = false, value = "修改人") @RequestParam(required = false) String updateBy,
            @ApiParam(value = "仓库id",required = false)@RequestParam(required = false) String correspondId,
            @ApiParam(required = false, value = "经销商编号") @RequestParam(required = false) String customerNumber,
            @ApiParam(required = false, value = "1 打开 0关闭") @RequestParam(required = false) Integer status,
            HttpServletRequest request, HttpServletResponse response
    ) throws Exception {
        IPage<ReservedBean> reservedBeanIPage = reservedLogic.list(createBy,updateBy,id, status,correspondId,customerName, orderId, specification, startTime, endTime, customerNumber, materialCode, materialName, 1, -1);
        ExcelData excelData = reservedLogic.export(reservedBeanIPage.getRecords());
        ExcelUtils.exportExcel(request,response,"预留单.xlsx",excelData);
    }


    @ApiOperation(value = "物料编码查询物料")
    @GetMapping("/detailMaterialNumber")
    public ResponseHelper<IPage<KingDeeMaterial>> detailMaterialNumber(
            @ApiParam(required = false,value = "产品编码") @RequestParam(required = false) String number,
            @ApiParam(required = false,value = "产品名称") @RequestParam(required = false) String name,
            @ApiParam(value = "规格",required = false) @RequestParam(required = false) String specification,
            @ApiParam(value = "页号", required = true) @RequestParam Integer pageNum,
            @ApiParam(value = "页大小", required = true) @RequestParam Integer pageSize
    ) throws Exception {
        IPage<KingDeeMaterial> list = reservedLogic.detailMaterialNumber(number,name,specification,pageNum,pageSize);
        return ResponseHelper.success(list);
    }


    @ApiOperation(value = "经销商编码查询经销商")
    @GetMapping("/detailCustomer")
    public ResponseHelper<List<KingDeeCustomer>> detailCustomer(
            @ApiParam(required = false,value = "经销商编码") @RequestParam(required = false) String number,
            @ApiParam(required = false,value = "经销商名称") @RequestParam(required = false) String name
    ) throws Exception {
        List<KingDeeCustomer> list = reservedLogic.detailCustomer(number,name);
        return ResponseHelper.success(list);
    }

    @ApiNotAuth
    @ApiOperation(value = "系统自动生成预留单")
    @GetMapping("/automaticReserved")
    public ResponseHelper automaticReserved() throws Exception {
         reservedLogic.automaticReserved();
        return ResponseHelper.success();
    }

    @ApiOperation(value = "经销商仓库列表")
    @GetMapping("/listStock")
    public ResponseHelper<IPage<StockPositionStock>> listStock(
            @ApiParam(value = "仓库名称",required = false)@RequestParam(required = false) String name,
            @ApiParam(value = "经销商id",required = true)@RequestParam(required = true) String customerId,
            @ApiParam(value = "仓位名称",required = false)@RequestParam(required = false) String stockName,
            @ApiParam(value = "1 正常仓 2虚拟仓",required = false)@RequestParam(required = false) Integer type,
            @ApiParam(value = "页号",required = true)@RequestParam(required = true) Integer pageNum,
            @ApiParam(value = "页大小",required = true)@RequestParam(required = true) Integer pageSize
    ) throws Exception {
        IPage<StockPositionStock> stockIPage = reservedLogic.listStock(name,stockName,pageNum,pageSize,customerId);
        return ResponseHelper.success(stockIPage);
    }


    @GetMapping("/download")
    @ApiOperation("下载模板")
    public void download(
            HttpServletResponse response
    ) throws IOException {
        CommonUtils.downloadFile("reserved.xlsx",response);
    }


    @PostMapping("/importData")
    @ApiOperation("导入")
    public ResponseHelper importData(
            MultipartFile file
    ) throws IOException {
        reservedLogic.improtData(file);
        return ResponseHelper.success();
    }

}