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

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.excel.EasyExcel;
import com.tmerclub.cloud.api.delivery.dto.DeliveryOrderDTO;
import com.tmerclub.cloud.api.delivery.dto.DeliveryOrderItemDTO;
import com.tmerclub.cloud.api.delivery.feign.DeliveryFeignClient;
import com.tmerclub.cloud.api.order.vo.PurchaseOrderAddrVO;
import com.tmerclub.cloud.common.exception.LuckException;
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.order.constant.PurchasesStatusEnum;
import com.tmerclub.cloud.order.dto.PurchaseOrderDTO;
import com.tmerclub.cloud.order.listener.PurchaseOrderExcelListener;
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.PurchaseOrderExcelVO;
import com.tmerclub.cloud.order.vo.PurchaseOrderItemVO;
import com.tmerclub.cloud.order.vo.PurchaseOrderVO;
import com.tmerclub.cloud.order.vo.UnDeliveryPurchaseOrderExcelVO;
import io.swagger.v3.oas.annotations.Operation;
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.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author tmerclub on 2018/09/15.
 */
@RestController("supplierPurchaseOrderController")
@RequestMapping("/s/purchase/order")
@Tag(name = "供应商端采购订单")
public class PurchaseOrderController {

    @Autowired
    private PurchaseOrderService purchaseOrderService;
    @Autowired
    private PurchaseOrderExcelService orderExcelService;
    @Autowired
    private PurchaseOrderAddrService purchaseOrderAddrService;
    @DubboReference
    private DeliveryFeignClient deliveryFeignClient;

    private static final Logger logger = LoggerFactory.getLogger(PurchaseOrderController.class);

    /**
     * 通过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.get().getTenantId(), purchaseOrderVO.getSupplierId())) {
            throw new LuckException(ResponseEnum.UNAUTHORIZED);
        }
        // 详情用户收货地址
        PurchaseOrderAddr purchaseOrderAddr = purchaseOrderAddrService.getById(purchaseOrderVO.getPurchaseOrderAddrId());
        purchaseOrderVO.setPurchaseOrderAddr(BeanUtil.map(purchaseOrderAddr, PurchaseOrderAddrVO.class));
        return ServerResponseEntity.success(purchaseOrderVO);
    }

    /**
     * 订单项待发货数量查询
     */
    @GetMapping("/order_item_and_address/{purchaseOrderId}")
    @Operation(summary = "订单项待发货数量查询", description = "订单项待发货数量查询")
    public ServerResponseEntity<PurchaseOrderVO> getOrderItemAndAddress(@PathVariable("purchaseOrderId") Long purchaseOrderId) {
        // 订单和订单项
        PurchaseOrderVO purchaseOrderVO = purchaseOrderService.info(purchaseOrderId, AuthUserContext.get().getTenantId());
        List<PurchaseOrderItemVO> orderItems = purchaseOrderVO.getPurchaseOrderItemList();
        for (PurchaseOrderItemVO orderItem : orderItems) {
            orderItem.setChangeNum(orderItem.getBeDeliveredNum() == -1 ? orderItem.getPurchaseStock() : orderItem.getBeDeliveredNum());
        }
        // 用户收货地址
        PurchaseOrderAddr purchaseOrderAddr = purchaseOrderAddrService.getById(purchaseOrderVO.getPurchaseOrderAddrId());
        purchaseOrderVO.setPurchaseOrderAddr(BeanUtil.map(purchaseOrderAddr, PurchaseOrderAddrVO.class));
        return ServerResponseEntity.success(purchaseOrderVO);
    }

    /**
     * 审核付款凭证
     *
     * @param purchaseOrder
     * @return 是否修改成功
     */
    @PutMapping("/auditVoucher")
    @Operation(summary = "审核付款凭证", description = "审核付款凭证")
    public ServerResponseEntity<Void> auditVoucher(@RequestBody PurchaseOrderDTO purchaseOrder) {

        purchaseOrder.setSupplierId(AuthUserContext.get().getTenantId());
        purchaseOrderService.auditVoucher(purchaseOrder);
        return ServerResponseEntity.success();
    }

    /**
     * 发货
     */
    @PostMapping("/delivery")
    @Operation(summary = "发货", description = "发货")
    public ServerResponseEntity<Void> delivery(@Valid @RequestBody DeliveryOrderDTO deliveryOrderParam) {
        // 检查发货数量
        PurchaseOrderVO purchaseOrderVO = purchaseOrderService.info(deliveryOrderParam.getOrderId(), AuthUserContext.get().getTenantId());
        if (Objects.isNull(purchaseOrderVO)) {
            return ServerResponseEntity.fail(ResponseEnum.UNAUTHORIZED);
        }
        // 订单不在支付状态
        if (!Objects.equals(purchaseOrderVO.getStatus(), PurchasesStatusEnum.WAIT_STOCK.value())) {
            return ServerResponseEntity.showFailMsg("订单状态异常");
        }
        List<DeliveryOrderItemDTO> selectOrderItems = deliveryOrderParam.getSelectOrderItems();
        if (CollectionUtil.isEmpty(selectOrderItems)) {
            return ServerResponseEntity.showFailMsg("请至少选择一个订单项进行发货操作");
        }
        Map<Long, PurchaseOrderItemVO> orderItemMap = purchaseOrderVO.getPurchaseOrderItemList().stream().collect(Collectors.toMap(PurchaseOrderItemVO::getPurchaseItemId, orderItem -> orderItem));
        for (DeliveryOrderItemDTO selectOrderItem : selectOrderItems) {
            if (!orderItemMap.containsKey(selectOrderItem.getOrderItemId())) {
                throw new LuckException("订单项不存在");
            }
            PurchaseOrderItemVO orderItem = orderItemMap.get(selectOrderItem.getOrderItemId());
            if (orderItem.getBeDeliveredNum() < selectOrderItem.getChangeNum()) {
                throw new LuckException("订单项可发货数量不足,请刷新后重试");
            }
        }
        // 用户收货地址
        PurchaseOrderAddr purchaseOrderAddr = purchaseOrderAddrService.getById(purchaseOrderVO.getPurchaseOrderAddrId());
        if (Objects.nonNull(purchaseOrderAddr)) {
            deliveryOrderParam.setConsignee(purchaseOrderAddr.getConsignee());
            deliveryOrderParam.setMobile(purchaseOrderAddr.getMobile());
        }
        purchaseOrderService.delivery(deliveryOrderParam);
        return ServerResponseEntity.success();
    }

    @GetMapping("/un_delivery_sold_excel")
    @Operation(summary = "导出待发货的订单excel")
    public ServerResponseEntity<Void> unDeliveryOrderSoldExcel(HttpServletResponse response, PurchaseOrderDTO purchaseOrder) {
        purchaseOrder.setSupplierId(AuthUserContext.get().getTenantId());
        orderExcelService.excelUnDeliveryOrderList(response, purchaseOrder);
        return ServerResponseEntity.success();
    }

    @PostMapping("/export_order_excel")
    @Operation(summary = "导入订单")
    public ServerResponseEntity<String> exportOrderExcel(@RequestParam("excelFile") MultipartFile file) {
        if (Objects.isNull(file)) {
            throw new LuckException("网络繁忙，请稍后重试");
        }
        String info;
        try {
            Map<Integer, List<String>> errorMap = new HashMap<>(8);
            EasyExcel.read(file.getInputStream(), UnDeliveryPurchaseOrderExcelVO.class, new PurchaseOrderExcelListener(orderExcelService, errorMap)).sheet().doRead();
            info = orderExcelService.orderExportError(errorMap);
        } catch (IOException e) {
            logger.error("导入订单失败，失败原因：{}", e.getMessage());
            throw new LuckException(e.getMessage());
        }
        return ServerResponseEntity.success(info);
    }

    @GetMapping("/soldExcel")
    @Operation(summary = "导出excel", description = "导出订单excel")
    public ServerResponseEntity<Void> orderSoldExcel(HttpServletResponse response, PurchaseOrderDTO purchaseOrder) {
        purchaseOrder.setSupplierId(AuthUserContext.get().getTenantId());
        List<PurchaseOrderExcelVO> list = orderExcelService.excelOrderList(purchaseOrder);
        ExcelUtil.soleExcel(response, list, PurchaseOrderExcelVO.EXCEL_NAME, PurchaseOrderExcelVO.MERGE_ROW_INDEX, PurchaseOrderExcelVO.MERGE_COLUMN_INDEX, PurchaseOrderExcelVO.class);
        return ServerResponseEntity.success();
    }
}
