package cn.iocoder.yudao.module.member.service.activitytabledish;

import cn.iocoder.yudao.framework.common.exception.ErrorCode;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.member.controller.admin.activityrestaurant.vo.ActivityRestaurantSaveReqVO;
import cn.iocoder.yudao.module.member.controller.admin.activitytabledish.vo.ActivityTableDishPageReqVO;
import cn.iocoder.yudao.module.member.controller.admin.activitytabledish.vo.ActivityTableDishSaveReqVO;
import cn.iocoder.yudao.module.member.controller.admin.activitytabledish.vo.ActivityUpdateDishVO;
import cn.iocoder.yudao.module.member.dal.dataobject.activitytable.ActivityTableDO;
import cn.iocoder.yudao.module.member.dal.dataobject.activitytabledish.ActivityTableDishDO;
import cn.iocoder.yudao.module.member.dal.mysql.activitytabledish.ActivityTableDishMapper;
import cn.iocoder.yudao.module.member.service.activitytable.ActivityTableService;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

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

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.ACTIVITY_TABLE_DISH_NOT_EXISTS;

/**
 * 活动用餐桌子配置 Service 实现类
 *
 * @author 我是秦俊旗
 */
@Service
@Validated
public class ActivityTableDishServiceImpl implements ActivityTableDishService {

    @Resource
    private ActivityTableDishMapper activityTableDishMapper;
    @Resource
    private ActivityTableService activityTableService;

    @Override
    public Long createActivityTableDish(ActivityTableDishSaveReqVO createReqVO) {
        // 插入
        ActivityTableDishDO activityTableDish = BeanUtils.toBean(createReqVO, ActivityTableDishDO.class);

        List<ActivityTableDishDO> activityTableDishDOS = activityTableDishMapper.selectList(Wrappers.<ActivityTableDishDO>lambdaQuery()
                .eq(ActivityTableDishDO::getActivityId, activityTableDish.getActivityId())
                .eq(ActivityTableDishDO::getSerialNumber, activityTableDish.getSerialNumber()));
        if (!activityTableDishDOS.isEmpty()) {
            throw exception(new ErrorCode(1_005_000_02, createReqVO.getSerialNumber() + "桌号已存在"));
        }

        activityTableDishMapper.insert(activityTableDish);
        // 返回
        return activityTableDish.getId();
    }

    @Override
    public void updateActivityTableDish(ActivityTableDishSaveReqVO updateReqVO) {
        // 校验存在
        validateActivityTableDishExists(updateReqVO.getId());
        // 更新
        ActivityTableDishDO updateObj = BeanUtils.toBean(updateReqVO, ActivityTableDishDO.class);
        activityTableDishMapper.updateById(updateObj);
    }

    @Override
    public void deleteActivityTableDish(Long id) {
        // 校验存在
        ActivityTableDishDO activityTableDishDO = activityTableDishMapper.selectById(id);
        if (activityTableDishDO == null) {
            throw exception(ACTIVITY_TABLE_DISH_NOT_EXISTS);
        }
        Long activityId = activityTableDishDO.getActivityId();
        List<ActivityTableDO> listByActivityId = activityTableService.getListByActivityId(activityId);
        if (!listByActivityId.isEmpty()) {
            throw exception(new ErrorCode(1_005_000_03, "该桌位已被预定，无法删除"));
        }
        // 删除
        activityTableDishMapper.deleteById(id);
    }

    private void validateActivityTableDishExists(Long id) {
        if (activityTableDishMapper.selectById(id) == null) {
            throw exception(ACTIVITY_TABLE_DISH_NOT_EXISTS);
        }
    }

    @Override
    public ActivityTableDishDO getActivityTableDish(Long id) {
        return activityTableDishMapper.selectById(id);
    }

    @Override
    public PageResult<ActivityTableDishDO> getActivityTableDishPage(ActivityTableDishPageReqVO pageReqVO) {
        return activityTableDishMapper.selectPage(pageReqVO);
    }

    @Override
    public void createByRestaurant(ActivityRestaurantSaveReqVO activityRestaurantSaveReqVO) {
        Integer totalTable = activityRestaurantSaveReqVO.getTotalTable();
        ArrayList<ActivityTableDishDO> activityTableDOS = new ArrayList<>();
        for (int i = 1; i <= totalTable; i++) {
            ActivityTableDishDO activityTableDO = new ActivityTableDishDO();
            activityTableDO.setActivityId(activityRestaurantSaveReqVO.getActivityId());
            activityTableDO.setSerialNumber(i);
            activityTableDO.setPrice(activityRestaurantSaveReqVO.getPrice());
            activityTableDOS.add(activityTableDO);
        }
        activityTableDishMapper.insertBatch(activityTableDOS);
    }

    @Override
    public Boolean updateDish(ActivityUpdateDishVO updateReqVO) {
        int update = activityTableDishMapper.update(Wrappers.<ActivityTableDishDO>lambdaUpdate()
                .set(ActivityTableDishDO::getDish, updateReqVO.getDish())
                .set(ActivityTableDishDO::getMerchantId, updateReqVO.getMerchantId())
                .in(ActivityTableDishDO::getId, updateReqVO.getIds()));
        return update>0;
    }

    @Override
    public List<ActivityTableDishDO> getListByIds(List<Long> ids) {
            return activityTableDishMapper.selectList(Wrappers.<ActivityTableDishDO>lambdaQuery()
                    .in(ActivityTableDishDO::getId, ids));
    }

    @Override
    public List<ActivityTableDishDO> getListByActivityIdAndMerchantId(Long activityId, Long merchantId) {
        return activityTableDishMapper.selectList(Wrappers.<ActivityTableDishDO>lambdaQuery()
                .eq(ActivityTableDishDO::getMerchantId, merchantId)
                .eq(ActivityTableDishDO::getActivityId, activityId)
        );
    }

    @Override
    public Long getMerchantIdByActivityIdAndSerialNumber(Long activityId, Integer serialNumber) {
        ActivityTableDishDO activityTableDishDO = activityTableDishMapper.selectOne(Wrappers.<ActivityTableDishDO>lambdaQuery()
                .eq(ActivityTableDishDO::getSerialNumber, serialNumber)
                .eq(ActivityTableDishDO::getActivityId, activityId).last("limit 1")
        );
        if(activityTableDishDO != null){
            return activityTableDishDO.getMerchantId();
        }
        return null;
    }
}