package com.yc.ship.module.resource.service.room;

import com.yc.ship.framework.common.pojo.PageResult;
import com.yc.ship.framework.common.util.collection.CollectionUtils;
import com.yc.ship.framework.common.util.object.BeanUtils;
import com.yc.ship.module.resource.controller.admin.room.vo.ResourceRoomBatchSaveReqVO;
import com.yc.ship.module.resource.controller.admin.room.vo.ResourceRoomPageReqVO;
import com.yc.ship.module.resource.controller.admin.room.vo.ResourceRoomRespVO;
import com.yc.ship.module.resource.controller.admin.room.vo.ResourceRoomSaveReqVO;
import com.yc.ship.module.resource.dal.dataobject.room.ResourceRoomDO;
import com.yc.ship.module.resource.dal.dataobject.roommodelrooms.ResourceRoomModelRoomsDO;
import com.yc.ship.module.resource.dal.mysql.room.ResourceRoomMapper;
import com.yc.ship.module.resource.dal.mysql.roomModelRooms.ResourceRoomModelRoomsMapper;
import com.yc.ship.module.resource.helper.RoomNumberHelper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

import static com.yc.ship.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.yc.ship.module.resource.enums.ErrorCodeConstants.ROOM_NOT_EXISTS;
import static com.yc.ship.module.resource.enums.ErrorCodeConstants.ROOM_NUMS_EXISTS;

/**
 * 资源管理-游轮房间管理 Service 实现类
 *
 * @author lfy
 */
@Service
@Validated
public class ResourceRoomServiceImpl implements ResourceRoomService {

    @Resource
    private ResourceRoomMapper roomMapper;

    @Resource
    private ResourceRoomModelRoomsMapper roomModelRoomsMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createRoom(ResourceRoomSaveReqVO createReqVO) {
        // 插入
        ResourceRoomDO room = BeanUtils.toBean(createReqVO, ResourceRoomDO.class);
        validateRoomNumsExists(room.getRoomNum(), room.getShipId());
        roomMapper.insert(room);
        //添加到房间房型关联表中
        handleRoomModelRooms(room);
        // 返回
        return room.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateRoom(ResourceRoomSaveReqVO updateReqVO) {
        // 校验存在
        validateRoomExists(updateReqVO.getId());
        // 更新
        ResourceRoomDO updateObj = BeanUtils.toBean(updateReqVO, ResourceRoomDO.class);
        roomMapper.updateById(updateObj);
        //更新房间房型关联表中的数据
        handleRoomModelRooms(updateObj);
    }

    private void handleRoomModelRooms(ResourceRoomDO room) {
        roomModelRoomsMapper.deleteByRoomId(room.getId());
        ResourceRoomModelRoomsDO roomModelRooms = ResourceRoomModelRoomsDO.builder()
                .roomId(room.getId())
                .roomModelId(room.getRoomModelId())
                .build();
        roomModelRoomsMapper.insert(roomModelRooms);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteRoom(Long id) {
        // 校验存在
        validateRoomExists(id);
        // 删除
        roomMapper.deleteById(id);
        roomModelRoomsMapper.deleteByRoomId(id);
    }

    private void validateRoomExists(Long id) {
        if (roomMapper.selectById(id) == null) {
            throw exception(ROOM_NOT_EXISTS);
        }
    }

    /**
     * 验证同一游轮上相同房间号是否已存在
     * @param roomNum 房间号
     * @param shipId  游轮ID
     */
    private void validateRoomNumsExists(Integer roomNum, Long shipId) {
        if (roomMapper.selectByShipIdAndRoomNums(roomNum, shipId) != null) {
            throw exception(ROOM_NUMS_EXISTS);
        }
    }

    @Override
    public ResourceRoomDO getRoom(Long id) {
        return roomMapper.selectById(id);
    }

    @Override
    public PageResult<ResourceRoomDO> getRoomPage(ResourceRoomPageReqVO pageReqVO) {
        return roomMapper.selectPage(pageReqVO);
    }

    @Override
    public List<ResourceRoomDO> getRoomListByShipId(String shipId) {
        return roomMapper.selectByShipId(shipId);
    }

    @Override
    public List<ResourceRoomDO> getRoomListByShipIdAndFloors(String shipId, String floors) {
        List<Integer> floorList = Arrays.stream(floors.split(",")).map(Integer::parseInt).collect(Collectors.toList());
        return roomMapper.selectByShipIdAndFloors(shipId, floorList);
    }

    @Override
    public Boolean createBatchRoom(ResourceRoomBatchSaveReqVO createReqVO) {
        Integer startNum = createReqVO.getStartNum();
        List<String> roomNums = RoomNumberHelper.generate(createReqVO.getFloors().toString(), startNum, createReqVO.getNum(), createReqVO.getRoomNumLen());
        //已存在的房间号
        List<String> exitRoomNums = roomMapper.selectRoomNumListByShipId(createReqVO.getShipId(), roomNums);
        roomNums.removeAll(exitRoomNums);
        List<ResourceRoomDO> list = new ArrayList<>();
        roomNums.stream().forEach(roomNum -> {
            ResourceRoomDO room = ResourceRoomDO.builder()
                    .roomNum(Integer.parseInt(roomNum))
                    .roomModelId(createReqVO.getRoomModelId())
                    .shipId(createReqVO.getShipId())
                    .floors(createReqVO.getFloors())
                    .brief(createReqVO.getBrief())
                    .status(createReqVO.getStatus())
                    .canSale(createReqVO.getCanSale())
                    .build();
            list.add(room);
        });
        Boolean flag = roomMapper.insertBatch(list);
        return flag;
    }

    @Override
    public List<ResourceRoomDO> getRoomListByIds(List<Long> ids) {
        if(CollectionUtils.isAnyEmpty(ids)) {
            return Collections.emptyList();
        }
        return roomMapper.selectByIds(ids);
    }

    @Override
    public List<ResourceRoomDO> getRoomListByRoomModelIdAndFloor(Long shipId, List<String> roomModelIdFloorList) {
        if(CollectionUtils.isAnyEmpty(roomModelIdFloorList)) {
            return Collections.emptyList();
        }
        return roomMapper.selectRoomListByRoomModelIdAndFloor(shipId, roomModelIdFloorList);
    }


    @Override
    public List<ResourceRoomRespVO> getRoomListByShipIdAndFloorsForArrange(String shipId, String voyageId, String floors) {
        return roomMapper.selectAllByShipIdAndFloors(shipId,voyageId, floors);
    }
}