package com.yc.ship.module.product.controller.app.voyage;

import com.yc.ship.framework.common.pojo.CommonResult;
import com.yc.ship.framework.common.util.collection.CollectionUtils;
import com.yc.ship.framework.common.util.collection.MapUtils;
import com.yc.ship.framework.common.util.object.BeanUtils;
import com.yc.ship.module.product.controller.admin.pricetemplate.vo.*;
import com.yc.ship.module.product.controller.admin.pricevoyage.vo.PriceVoyageRespVO;
import com.yc.ship.module.product.controller.admin.voyage.vo.VoyageCalendarReqVO;
import com.yc.ship.module.product.controller.admin.voyage.vo.VoyageRespVO;
import com.yc.ship.module.product.controller.admin.voyagestockdistributeNew.vo.QueryCanSelectRoomListNewReqVO;
import com.yc.ship.module.product.controller.app.voyage.vo.*;
import com.yc.ship.module.product.dal.dataobject.basicpricearea.BasicPriceAreaDO;
import com.yc.ship.module.product.dal.dataobject.pricearea.PriceAreaDO;
import com.yc.ship.module.product.dal.dataobject.pricefloor.PriceFloorDO;
import com.yc.ship.module.product.dal.dataobject.priceroommodel.PriceRoomModelDO;
import com.yc.ship.module.product.dal.dataobject.priceroommodeltype.PriceRoomModelTypeDO;
import com.yc.ship.module.product.dal.dataobject.pricesinglesetting.PriceSingleSettingDO;
import com.yc.ship.module.product.dal.dataobject.pricevoyage.PriceVoyageDO;
import com.yc.ship.module.product.dal.dataobject.voyage.VoyageDO;
import com.yc.ship.module.product.enums.ErrorCodeConstants;
import com.yc.ship.module.product.service.basicpricearea.BasicPriceAreaService;
import com.yc.ship.module.product.service.pricearea.PriceAreaService;
import com.yc.ship.module.product.service.pricefloor.PriceFloorService;
import com.yc.ship.module.product.service.priceroommodel.PriceRoomModelService;
import com.yc.ship.module.product.service.priceroommodeltype.PriceRoomModelTypeService;
import com.yc.ship.module.product.service.pricesinglesetting.PriceSingleSettingService;
import com.yc.ship.module.product.service.pricespu.PriceSpuService;
import com.yc.ship.module.product.service.pricevoyage.PriceVoyageService;
import com.yc.ship.module.product.service.voyage.VoyageService;
import com.yc.ship.module.product.service.voyagestockdistribute.VoyageStockDistributeNewService;
import com.yc.ship.module.resource.api.room.dto.RoomRespDTO;
import com.yc.ship.module.resource.api.route.RouteApi;
import com.yc.ship.module.resource.api.route.dto.RouteRespDTO;
import com.yc.ship.module.resource.api.ship.ShipApi;
import com.yc.ship.module.resource.controller.admin.roommodel.vo.ResourceRoomModelRespVO;
import com.yc.ship.module.resource.dal.dataobject.roommodel.ResourceRoomModelDO;
import com.yc.ship.module.resource.dal.dataobject.ship.ResourceShipDO;
import com.yc.ship.module.resource.service.roommodel.ResourceRoomModelService;
import com.yc.ship.module.resource.service.ship.ResourceShipService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.commons.lang3.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

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

/**
 * 航次(航期)APP接口
 */
@Tag(name = "航次(航期) APP - 航次管理")
@RestController
@RequestMapping("/product/voyage")
@Validated
public class AppVoyageController {

    @Resource
    private VoyageService voyageService;

    @Resource
    private ResourceShipService shipService;

    @Resource
    private RouteApi routeApi;

    @Resource
    private PriceVoyageService priceVoyageService;

    @Resource
    private VoyageStockDistributeNewService voyageStockDistributeNewService;


    @GetMapping("/list-calendar")
    @Operation(summary = "获取航次（航期）日历表")
    public CommonResult<List<AppVoyageRespVO>> getVoyageListCalendar(VoyageCalendarReqVO reqVO) {
        if(StringUtils.isBlank(reqVO.getChannel())) {
            reqVO.setChannel("2");//表示小程序
        }
        List<VoyageDO> list = voyageService.getListCalendar(reqVO);
        List<AppVoyageRespVO> voyageRespVOS = BeanUtils.toBean(list, AppVoyageRespVO.class);

        List<Long> shipIds = CollectionUtils.convertList(voyageRespVOS, VoyageRespVO::getShipId);
        List<ResourceShipDO> shipList = shipService.getList(shipIds);
        Map<Long, ResourceShipDO> shipDOMap = CollectionUtils.convertMap(shipList, ResourceShipDO::getId);

        List<Long> routeIds = CollectionUtils.convertList(voyageRespVOS, VoyageRespVO::getRouteId);
        Map<Long, RouteRespDTO> longRouteRespDTOMap = routeApi.queryRoute(routeIds);

        voyageRespVOS.stream().filter(item -> {
            List<Long> shipIdList = CollectionUtils.convertList(shipList, ResourceShipDO::getId);
            Set<Long> routeIdList = longRouteRespDTOMap.keySet();
            return shipIdList.contains(item.getShipId()) && routeIdList.contains(item.getRouteId());
        });

        voyageRespVOS.stream().forEach(item -> {
            MapUtils.findAndThen(shipDOMap, item.getShipId(), ship -> {
                item.setShipShortName(ship.getShortName());
                item.setShipName(ship.getName());
            });
            MapUtils.findAndThen(longRouteRespDTOMap, item.getRouteId(), route -> {
                item.setRouteName(route.getName());
                item.setRouteResp(route);
            });
        });
        return success(voyageRespVOS);
    }

    @GetMapping("/list-calendar-price")
    @Operation(summary = "获取航次（航期）日历表价格")
    public CommonResult<List<AppVoyageCalendarPriceRespVO>> getVoyageListCalendarPrice(AppVoyageCalendarPriceReqVO reqVO) {
        List<AppVoyageCalendarPriceRespVO> list = priceVoyageService.getListCalendarPrice(reqVO);
        return success(list);
    }

    // 根据日期和游轮ID获取当日航次列表
    @GetMapping("/getVoyageListByShipIdAndDate")
    @Operation(summary = "根据日期和游轮ID获取当日航次列表")
    public CommonResult<List<AppVoyageDayRespVO>> getVoyageListByShipIdAndDate(@RequestParam(value = "shipId", required = false) Long shipId, @RequestParam(value = "date",required = false) String date) {
        List<AppVoyageDayRespVO> list = voyageService.getVoyageListByShipIdAndDate(shipId, date);
        return success(list);
    }

    @GetMapping("/getRoomModelListByVoyageId")
    @Operation(summary = "获取航次（航期）房型列表")
    public CommonResult<List<AppRoomModelPriceRespVO>> getRoomModelListByVoyageId(@RequestParam("voyageId") Long voyageId) {
        List<AppRoomModelPriceRespVO> list = priceVoyageService.getRoomModelListByVoyageId(voyageId);
        return success(list);
    }

    @GetMapping("/get-by-voyage-id")
    @Operation(summary = "通过航次ID获得航次价格")
    public CommonResult<PriceVoyageRespVO> getByVoyageId(@RequestParam("voyageId") Long voyageId) {
        PriceVoyageRespVO respVO = priceVoyageService.getByVoyageId(voyageId);
        return success(respVO);
    }

    @GetMapping("/get-by-voyage-id-new")
    @Operation(summary = "通过航次ID获得航次价格")
    public CommonResult<AppPriceVoyageRespVO> getByVoyageIdNew(@RequestParam("voyageId") Long voyageId, @RequestParam("roomModelId") Long roomModelId) {
        AppPriceVoyageRespVO respVO = priceVoyageService.getAppPrice(voyageId, roomModelId);
        return success(respVO);
    }

    //获取可以选择的房间号
    @GetMapping("/getCanSelectRoomList")
    @Operation(summary = "获取可以选择的房间号")
    public CommonResult<List<RoomRespDTO>> getCanSelectRoomList(AppCanSelectRoomReqVO reqVO) {
        List<RoomRespDTO> list = voyageStockDistributeNewService.getAppCanSelectRoomList(reqVO);
        return success(list);
    }

}
