
package com.tmerclub.cloud.order.controller.multishop;


import com.tmerclub.cloud.api.auth.bo.UidInfoBO;
import com.tmerclub.cloud.api.delivery.feign.DeliveryFeignClient;
import com.tmerclub.cloud.api.order.vo.PurchaseOrderAddrVO;
import com.tmerclub.cloud.api.product.feign.SpuFeignClient;
import com.tmerclub.cloud.common.constant.Constant;
import com.tmerclub.cloud.common.exception.LuckException;
import com.tmerclub.cloud.common.leaf.manager.SegmentManager;
import com.tmerclub.cloud.common.response.ResponseEnum;
import com.tmerclub.cloud.common.response.ServerResponseEntity;
import com.tmerclub.cloud.common.security.AuthUserContext;
import com.tmerclub.cloud.common.util.BeanUtil;
import com.tmerclub.cloud.common.util.ExcelUtil;
import com.tmerclub.cloud.constant.DistributedIdKey;
import com.tmerclub.cloud.order.dto.PurchaseOrderDTO;
import com.tmerclub.cloud.order.dto.PurchaseOrderItemDTO;
import com.tmerclub.cloud.order.model.PurchaseOrder;
import com.tmerclub.cloud.order.model.PurchaseOrderAddr;
import com.tmerclub.cloud.order.service.PurchaseOrderAddrService;
import com.tmerclub.cloud.order.service.PurchaseOrderExcelService;
import com.tmerclub.cloud.order.service.PurchaseOrderService;
import com.tmerclub.cloud.order.vo.PurchaseOrderInboundExcelVO;
import com.tmerclub.cloud.order.vo.PurchaseOrderItemVO;
import com.tmerclub.cloud.order.vo.PurchaseOrderVO;
import com.tmerclub.cloud.order.vo.PurchaseSpuImportVO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.Valid;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.*;

/**
 * 采购订单
 *
 * @author YXF
 * @date 2021-09-08 10:42:01
 */
@RestController("multishopPurchaseOrderController")
@RequestMapping("/m/purchase/order")
@Tag(name = "multishop-采购订单接口")
public class PurchaseOrderController {

    @Autowired
    private PurchaseOrderService purchaseOrderService;
    @Autowired
    private PurchaseOrderExcelService purchaseOrderExcelService;
    @Autowired
    private SegmentManager segmentManager;
    @Autowired
    private PurchaseOrderAddrService purchaseOrderAddrService;
    @DubboReference
    private DeliveryFeignClient deliveryFeignClient;
    @DubboReference
    private SpuFeignClient spuFeignClient;

    /**
     * 通过id查询
     *
     * @param purchaseOrderId id
     * @return 单个数据
     */
    @GetMapping("/info/{purchaseOrderId}")
    @Operation(summary = "根据id查询采购订单", description = "根据id查询采购订单")
    public ServerResponseEntity<PurchaseOrderVO> getById(@PathVariable("purchaseOrderId") Long purchaseOrderId) {
        PurchaseOrderVO purchaseOrderVO = purchaseOrderService.info(purchaseOrderId, null);
        if (!Objects.equals(AuthUserContext.getShopId(), purchaseOrderVO.getShopId())) {
            throw new LuckException(ResponseEnum.UNAUTHORIZED);
        }
        // 详情用户收货地址
        PurchaseOrderAddr purchaseOrderAddr = purchaseOrderAddrService.getById(purchaseOrderVO.getPurchaseOrderAddrId());
        purchaseOrderVO.setPurchaseOrderAddr(BeanUtil.map(purchaseOrderAddr, PurchaseOrderAddrVO.class));
        return ServerResponseEntity.success(purchaseOrderVO);
    }


    /**
     * 新增
     *
     * @param purchaseOrder
     * @return 是否新增成功
     */
    @PostMapping
    @Operation(summary = "新增采购订单", description = "新增采购订单")
    public ServerResponseEntity<Void> save(@RequestBody @Valid PurchaseOrderDTO purchaseOrder) {
        UidInfoBO uidInfoBO = AuthUserContext.get();
        purchaseOrder.setShopId(uidInfoBO.getTenantId());
        purchaseOrder.setEmployeeId(uidInfoBO.getUserId());

        Map<Long, List<PurchaseOrderItemDTO>> purchaseOrderMap = new HashMap<>(purchaseOrder.getPurchaseOrderItemList().size());
        for (PurchaseOrderItemDTO purchaseOrderItem : purchaseOrder.getPurchaseOrderItemList()) {
            if (purchaseOrderItem.getPurchaseStock() <= 0) {
                throw new LuckException("请输入大于0的采购数量");
            }
            // 每个供应商的独立orderItemList
            List<PurchaseOrderItemDTO> purchaseOrderItemList = purchaseOrderMap.get(purchaseOrderItem.getSupplierId());
            if (Objects.isNull(purchaseOrderItemList)) {
                purchaseOrderItemList = new ArrayList<>(Constant.INITIAL_CAPACITY);
                purchaseOrderMap.put(purchaseOrderItem.getSupplierId(), purchaseOrderItemList);
            }
            purchaseOrderItemList.add(purchaseOrderItem);
        }

        purchaseOrderMap.forEach((supplierId, purchaseOrderItemList) -> {
            PurchaseOrderDTO purchaseOrderDTO = new PurchaseOrderDTO();
            purchaseOrderDTO.setShopId(purchaseOrder.getShopId());
            purchaseOrderDTO.setSupplierId(supplierId);
            purchaseOrderDTO.setPurchaseOrderItemList(purchaseOrderItemList);
            purchaseOrderDTO.setRemark(purchaseOrder.getRemark());
            purchaseOrderDTO.setWarehouseId(purchaseOrder.getWarehouseId());
            purchaseOrderDTO.setEmployeeId(purchaseOrder.getEmployeeId());
            // 获取订单号
            this.loadPurchaseOrderDateId(purchaseOrderDTO);
            purchaseOrderService.savePurchaseOrder(purchaseOrderDTO);
        });
        return ServerResponseEntity.success();
    }

    /**
     * 上传付款凭证
     *
     * @param purchaseOrder
     * @return 是否修改成功
     */
    @PutMapping("/updatePayVoucher")
    @Operation(summary = "上传付款凭证-更新订单", description = "上传付款凭证")
    public ServerResponseEntity<Void> updatePayVoucher(@RequestBody PurchaseOrderDTO purchaseOrder) {
        purchaseOrder.setShopId(AuthUserContext.get().getTenantId());
        purchaseOrderService.updatePayVoucher(purchaseOrder);
        return ServerResponseEntity.success();
    }

    /**
     * 入库
     *
     * @param purchaseOrder
     * @return 是否修改成功
     */
    @PutMapping("/inbound")
    @Operation(summary = "入库采购订单", description = "入库采购订单")
    public ServerResponseEntity<Void> inbound(@RequestBody PurchaseOrderDTO purchaseOrder) {
        purchaseOrder.setShopId(AuthUserContext.get().getTenantId());
        purchaseOrderService.inbound(purchaseOrder);
        return ServerResponseEntity.success();
    }

    /**
     * 作废
     *
     * @param purchaseOrderId
     */
    @DeleteMapping("/nullify/{purchaseOrderId}")
    @Operation(summary = "作废采购订单", description = "作废采购订单")
    public ServerResponseEntity<Void> nullify(@PathVariable Long purchaseOrderId) {
        purchaseOrderService.nullify(AuthUserContext.get().getTenantId(), purchaseOrderId);
        return ServerResponseEntity.success();
    }

    /**
     * 完成
     *
     * @param purchaseOrder
     */
    @PutMapping("/complete")
    @Operation(summary = "完成采购订单", description = "完成采购订单")
    public ServerResponseEntity<Void> finish(@RequestBody PurchaseOrder purchaseOrder) {
        purchaseOrder.setShopId(AuthUserContext.get().getTenantId());
        purchaseOrderService.complete(AuthUserContext.get().getTenantId(), purchaseOrder.getPurchaseOrderId());
        return ServerResponseEntity.success();
    }

    /**
     * 下载模板
     *
     * @param response
     */
    @GetMapping("/download_model")
    @ResponseBody
    @Operation(summary = "下载导入采购商品模板", description = "下载导入采购商品模板")
    public void downloadModel(HttpServletResponse response) {
        purchaseOrderService.downloadModel(response);
    }

    @Operation(summary = "导入采购商品", description = "导入采购商品")
    @Parameter(name = "warehouseId", description = "仓库id")
    @PostMapping("/export_excel")
    public ServerResponseEntity<PurchaseSpuImportVO> exportExcel(@RequestPart("excelFile") MultipartFile excelFile,
                                                                 Long warehouseId) {
        if (excelFile == null) {
            // 网络繁忙，请稍后重试
            throw new LuckException("网络繁忙，请稍后重试");
        }
        Long shopId = AuthUserContext.get().getTenantId();
        return ServerResponseEntity.success(purchaseOrderService.parseFile(excelFile, shopId, warehouseId));
    }

    @GetMapping("/inbound/export")
    @Schema(description = "导出入库商品")
    public void export(@RequestParam("purchaseOrderId") Long purchaseOrderId, HttpServletResponse response) {
        List<PurchaseOrderInboundExcelVO> purchaseOrderInboundExcelList = new ArrayList<>(Constant.INITIAL_CAPACITY);
        if (Objects.equals(purchaseOrderId, 0L)) {
            purchaseOrderInboundExcelList.add(new PurchaseOrderInboundExcelVO());
            ExcelUtil.soleExcel(response, purchaseOrderInboundExcelList, PurchaseOrderInboundExcelVO.EXCEL_NAME, PurchaseOrderInboundExcelVO.MERGE_ROW_INDEX,
                    PurchaseOrderInboundExcelVO.MERGE_COLUMN_INDEX, PurchaseOrderInboundExcelVO.class);
            return;
        }
        PurchaseOrderVO purchaseOrderVO = purchaseOrderService.info(purchaseOrderId, null);
        int index = 0;
        for (PurchaseOrderItemVO purchaseOrderItemVO : purchaseOrderVO.getPurchaseOrderItemList()) {
            PurchaseOrderInboundExcelVO purchaseOrderInboundExcelVO = new PurchaseOrderInboundExcelVO();
            purchaseOrderInboundExcelVO.setPartyCode(purchaseOrderItemVO.getPartyCode());
            purchaseOrderInboundExcelVO.setSpuName(purchaseOrderItemVO.getSpuName());
            purchaseOrderInboundExcelVO.setPurchaseStock(purchaseOrderItemVO.getPurchaseStock());
            purchaseOrderInboundExcelVO.setActualStock(purchaseOrderItemVO.getPurchaseStock() - purchaseOrderItemVO.getActualStock());
            purchaseOrderInboundExcelVO.setBeDeliveredNum(purchaseOrderItemVO.getPurchaseStock() - purchaseOrderItemVO.getActualStock());
            purchaseOrderInboundExcelList.add(purchaseOrderInboundExcelVO);
        }
        ExcelUtil.soleExcel(response, purchaseOrderInboundExcelList, PurchaseOrderInboundExcelVO.EXCEL_NAME, PurchaseOrderInboundExcelVO.MERGE_ROW_INDEX,
                PurchaseOrderInboundExcelVO.MERGE_COLUMN_INDEX, PurchaseOrderInboundExcelVO.class);
    }

    @Schema(description = "导入入库文件")
    @Parameter(name = "purchaseOrderId", description = "采购订单id")
    @PostMapping("/inbound/exportExcel/{purchaseOrderId}")
    public ServerResponseEntity<List<PurchaseOrderItemVO>> inboundExportExcel(@RequestPart("excelFile") MultipartFile excelFile,
                                                                              @PathVariable Long purchaseOrderId) {
        if (excelFile == null) {
            // 网络繁忙，请稍后重试
            throw new LuckException("网络繁忙，请稍后重试");
        }
        Long shopId = AuthUserContext.get().getTenantId();
        List<PurchaseOrderItemVO> excelInfoVO = purchaseOrderExcelService.inboundParseFile(excelFile, shopId, purchaseOrderId);
        return ServerResponseEntity.success(excelInfoVO);
    }

    private void loadPurchaseOrderDateId(PurchaseOrderDTO purchaseOrder) {
        Long purchaseOrderId = segmentManager.getSegmentIdWithDateTime(DistributedIdKey.tmerclub_PURCHASE_ORDER, purchaseOrder.getShopId());
        purchaseOrder.setPurchaseOrderId(purchaseOrderId);
        Long addId = segmentManager.getSegmentIdWithDateTime(DistributedIdKey.tmerclub_PURCHASE_ORDER_ADDR, purchaseOrder.getShopId());
        purchaseOrder.setAddrId(addId);
        for (PurchaseOrderItemDTO purchaseOrderItemDTO : purchaseOrder.getPurchaseOrderItemList()) {
            Long purchaseItemId = segmentManager.getSegmentIdWithDateTime(DistributedIdKey.tmerclub_PURCHASE_ORDER_ITEM, purchaseOrder.getShopId());
            purchaseOrderItemDTO.setPurchaseItemId(purchaseItemId);
        }
    }

}
