package com.yc.ship.module.product.controller.admin.voyagestockdetail;

import com.yc.ship.module.product.controller.admin.voyagestockdetail.vo.*;
import com.yc.ship.module.product.dal.dataobject.voyagestock.VoyageStockDO;
import com.yc.ship.module.product.dal.dataobject.voyagestockdetail.VoyageStockDetailDO;
import com.yc.ship.module.product.enums.ProductStockStaticsName;
import com.yc.ship.module.product.service.voyagestock.VoyageStockService;
import com.yc.ship.module.product.service.voyagestockdetail.VoyageStockDetailService;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.security.access.prepost.PreAuthorize;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;

import javax.validation.*;
import com.yc.ship.framework.common.pojo.CommonResult;
import com.yc.ship.framework.common.util.object.BeanUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.yc.ship.framework.common.pojo.CommonResult.success;

@Tag(name = "管理后台 - 航次库存")
@RestController
@RequestMapping("/product/voyage-stock-detail")
@Validated
public class VoyageStockDetailController {

    @Resource
    private VoyageStockDetailService voyageStockDetailService;

    @Resource
    private VoyageStockService voyageStockService;

    @PostMapping("/create")
    @Operation(summary = "创建航次库存")
    @PreAuthorize("@ss.hasPermission('product:voyage-stock-detail:create')")
    public CommonResult<Boolean> createVoyageStock(@Valid @RequestBody List<VoyageStockDetailSaveReqVO> createReqVO) {
        return success(voyageStockDetailService.createVoyageStock(createReqVO));
    }

    @PostMapping("/batch-create")
    @Operation(summary = "批量创建航次库存")
    @PreAuthorize("@ss.hasPermission('product:voyage-stock-detail:batchcreate')")
    public CommonResult<Boolean> batchCreateVoyageStock(@Valid @RequestBody VoyageStockDetailBatchSaveReqVO createReqVO) {
        return success(voyageStockDetailService.batchCreateVoyageStock(createReqVO));
    }

    @PutMapping("/update")
    @Operation(summary = "更新航次库存")
    @PreAuthorize("@ss.hasPermission('product:voyage-stock-detail:update')")
    public CommonResult<Boolean> updateVoyageStock(@Valid @RequestBody VoyageStockDetailSaveReqVO updateReqVO) {
        voyageStockDetailService.updateVoyageStock(updateReqVO);
        return success(true);
    }

    @DeleteMapping("/delete")
    @Operation(summary = "删除航次库存")
    @Parameter(name = "id", description = "编号", required = true)
    @PreAuthorize("@ss.hasPermission('product:voyage-stock-detail:delete')")
    public CommonResult<Boolean> deleteVoyageStock(@RequestParam("id") Long id) {
        voyageStockDetailService.deleteVoyageStock(id);
        return success(true);
    }

    @GetMapping("/get")
    @Operation(summary = "获得航次库存")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    @PreAuthorize("@ss.hasPermission('product:voyage-stock-detail:query')")
    public CommonResult<VoyageStockDetailRespVO> getVoyageStock(@RequestParam("id") Long id) {
        VoyageStockDetailDO voyageStock = voyageStockDetailService.getVoyageStock(id);
        return success(BeanUtils.toBean(voyageStock, VoyageStockDetailRespVO.class));
    }

    /**
     * 已废弃，请使用getByVoyageIdNew
     * @param voyageId
     * @return
     */
    @Deprecated
    @GetMapping("/getByVoyageId")
    @Operation(summary = "获得航次库存")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    public CommonResult<VoyageStockDetailRespVO> getVoyageStockByVoyageId(@RequestParam("voyageId") Long voyageId) {
        VoyageStockDO voyageStock = voyageStockService.getVoyageStock(voyageId);
        List<VoyageStockDetailDO> list = voyageStockDetailService.getListByVoyageId(voyageId);
        VoyageStockDetailRespVO respVO = new VoyageStockDetailRespVO();
        List<VoyageStockDetailHeaderRespVO> headerList = new ArrayList<>();
        Map<Long, List<VoyageStockDetailDO>> map = list.stream().collect(Collectors.groupingBy(VoyageStockDetailDO::getRoomModelId));
        map.forEach((roomModelId, detailList) -> {
            VoyageStockDetailHeaderRespVO header = new VoyageStockDetailHeaderRespVO();
            header.setRoomModelId(roomModelId);
            header.setRoomModelName(detailList.get(0).getRoomModelName());
            header.setFloorList(detailList.stream().map(VoyageStockDetailDO::getFloor).collect(Collectors.toList()));
            headerList.add(header);
        });
        List<Map<String, Object>> totalList = new ArrayList<>();
        Map<String, Object> mapTotal = new HashMap<>();//房间总数量
        mapTotal.put("staticsName", ProductStockStaticsName.TOTAL_NUM);
        mapTotal.put("allTotalNum", voyageStock.getTotalNum());
        Map<String, Object> mapShelf = new HashMap<>(); //本次上架数量
        mapShelf.put("staticsName", ProductStockStaticsName.SHELF_NUM);
        mapShelf.put("allTotalNum", 0);
        Map<String, Object> mapNotShelf = new HashMap<>(); //待上架房间数量
        mapNotShelf.put("staticsName", ProductStockStaticsName.NOT_SHELF_NUM);
        mapNotShelf.put("allTotalNum", voyageStock.getNotShelfNum());
        Map<String, Object> mapShelfed = new HashMap<>(); //已上架房间数量
        mapShelfed.put("staticsName", ProductStockStaticsName.SHELFED_NUM);
        mapShelfed.put("allTotalNum", voyageStock.getShelfedNum());
        Map<String, Object> mapBook = new HashMap<>(); // 预定房间数
        mapBook.put("staticsName", ProductStockStaticsName.BOOK_NUM);
        mapBook.put("allTotalNum", voyageStock.getBookNum());
        Map<String, Object> mapCanSell = new HashMap<>(); //可售房间数
        mapCanSell.put("staticsName", ProductStockStaticsName.CAN_SELL_NUM);
        mapCanSell.put("allTotalNum", voyageStock.getCanSellNum());
        Map<String, Object> mapOverSold = new HashMap<>(); //超卖房间数
        mapOverSold.put("staticsName", ProductStockStaticsName.OVERSOLD_NUM);
        mapOverSold.put("allTotalNum", voyageStock.getOversoldNum());
        Map<String, Object> mapSurplus = new HashMap<>(); //剩余房间数
        mapSurplus.put("staticsName", ProductStockStaticsName.SURPLUS_NUM);
        mapSurplus.put("allTotalNum", voyageStock.getSurplusNum());
        totalList.add(mapTotal);
        totalList.add(mapShelf);
        totalList.add(mapNotShelf);
        totalList.add(mapShelfed);
        totalList.add(mapBook);
        totalList.add(mapCanSell);
        totalList.add(mapOverSold);
        totalList.add(mapSurplus);
        list.stream().forEach(detail -> {
            mapTotal.put(detail.getRoomModelId()+"_"+detail.getFloor(),detail.getTotalNum());
            mapShelf.put(detail.getRoomModelId()+"_"+detail.getFloor(),0);
            mapNotShelf.put(detail.getRoomModelId()+"_"+detail.getFloor(),detail.getNotShelfNum());
            mapShelfed.put(detail.getRoomModelId()+"_"+detail.getFloor(),detail.getShelfedNum());
            mapBook.put(detail.getRoomModelId()+"_"+detail.getFloor(),detail.getBookNum());
            mapCanSell.put(detail.getRoomModelId()+"_"+detail.getFloor(),detail.getCanSellNum());
            mapOverSold.put(detail.getRoomModelId()+"_"+detail.getFloor(),detail.getOversoldNum());
            mapSurplus.put(detail.getRoomModelId()+"_"+detail.getFloor(),detail.getSurplusNum());
        });
        respVO.setHeaderList(headerList);
        respVO.setTotalList(totalList);
        return success(respVO);
    }

    @GetMapping("/getByVoyageIdNew")
    @Operation(summary = "获得航次库存")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    public CommonResult<List<VoyageStockDetailRespNewVO>> getVoyageStockByVoyageIdNew(@RequestParam("voyageId") Long voyageId) {
        List<VoyageStockDetailDO> list = voyageStockDetailService.getListByVoyageId(voyageId);
        VoyageStockDO voyageStock = voyageStockService.getVoyageStock(voyageId);
        VoyageStockDetailDO insideCabin = voyageStockDetailService.getVoyageStockTotalRow(voyageId);
        VoyageStockDetailDO voyageStockDetailDO = BeanUtils.toBean(voyageStock, VoyageStockDetailDO.class);
        voyageStockDetailDO.setRoomModelName("合计");
        voyageStockDetailDO.setFloor(0);
        voyageStockDetailDO.setShelfNum(BigDecimal.ZERO);
        list.add(insideCabin);
        list.add(voyageStockDetailDO);
        list.stream().forEach(detail -> {
            detail.setShelfNum(BigDecimal.ZERO);
        });
        return success(BeanUtils.toBean(list, VoyageStockDetailRespNewVO.class));
    }

    @GetMapping("/getInitByShip")
    @Operation(summary = "获得初始化航次库存")
    @Parameter(name = "shipId", description = "船ID", required = true, example = "1024")
    public CommonResult<List<VoyageStockDetailRespNewVO>> getInitByShip(@RequestParam("shipId") Long shipId) {
        return success(voyageStockDetailService.getInitByShip(shipId));
    }

    @GetMapping("/getByVoyageIdMap")
    @Operation(summary = "获得航次库存")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    public CommonResult<Map<String, BigDecimal>> getVoyageStockByVoyageIdMap(@RequestParam("voyageId") Long voyageId) {
        List<VoyageStockDetailDO> list = voyageStockDetailService.getListByVoyageId(voyageId);
        Map<String, BigDecimal> map = new HashMap<>();
        list.stream().forEach(detail -> {
            map.put(detail.getRoomModelId()+"_"+detail.getFloor(),detail.getShelfedNum());
        });
        return success(map);
    }

    @GetMapping("/getShelfedByVoyageId")
    @Operation(summary = "获得已上架的航次库存")
    @Parameter(name = "voyageId", description = "航次ID", required = true, example = "1024")
    public CommonResult<List<VoyageStockDetailRespNewVO>> getShelfedByVoyageId(@RequestParam("voyageId") Long voyageId) {
        List<VoyageStockDetailDO> list = voyageStockDetailService.getListByVoyageId(voyageId);
        List<VoyageStockDetailRespNewVO> respList = BeanUtils.toBean(list, VoyageStockDetailRespNewVO.class);
        return success(respList);
    }

}