package co.yixiang.yshop.module.shop.service.canvas;

import cn.hutool.core.util.ObjectUtil;
import co.yixiang.yshop.module.shop.controller.admin.canvasdetail.vo.CanvasDetailRespVO;
import co.yixiang.yshop.module.shop.convert.canvasdetail.CanvasDetailConvert;
import co.yixiang.yshop.module.shop.dal.dataobject.canvasdetail.CanvasDetailDO;
import co.yixiang.yshop.module.shop.enums.common.StateEnum;
import co.yixiang.yshop.module.shop.service.canvasdetail.CanvasDetailService;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import java.util.*;

import co.yixiang.yshop.module.shop.controller.admin.canvas.vo.*;
import co.yixiang.yshop.module.shop.dal.dataobject.canvas.CanvasDO;
import co.yixiang.yshop.framework.common.pojo.PageResult;

import co.yixiang.yshop.module.shop.convert.canvas.CanvasConvert;
import co.yixiang.yshop.module.shop.dal.mysql.canvas.CanvasMapper;

import static co.yixiang.yshop.framework.common.exception.util.ServiceExceptionUtil.exception;
import static co.yixiang.yshop.module.shop.enums.ErrorCodeConstants.CANVAS_NOT_EXISTS;
import static co.yixiang.yshop.module.shop.enums.ErrorCodeConstants.CANVAS_USED;

/**
 * 画布信息 Service 实现类
 *
 * @author moxiangrong
 */
@Service
@Validated
public class CanvasServiceImpl implements CanvasService {

    @Resource
    private CanvasMapper canvasMapper;

    @Resource
    private CanvasDetailService canvasDetailService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createCanvas(CanvasCreateReqVO createReqVO) {
        // 插入
        CanvasDO canvas = CanvasConvert.INSTANCE.convert(createReqVO);
        // 默认关闭
        canvas.setState(StateEnum.CLOSE.getValue());
        canvasMapper.insert(canvas);
        canvasDetailService.batchInsert(canvas.getId());
        // 返回
        return canvas.getId();
    }

    @Override
    public void updateCanvas(CanvasUpdateReqVO updateReqVO) {
        // 校验存在
        validateCanvasExists(updateReqVO.getId());
        // 更新
        CanvasDO updateObj = CanvasConvert.INSTANCE.convert(updateReqVO);
        canvasMapper.updateById(updateObj);
    }

    @Override
    public void updateCanvasJson(CanvasJsonUpdateReqVO jsonUpdateReqVO) {
        // 校验存在
        validateCanvasExists(jsonUpdateReqVO.getId());
        // 更新
        canvasDetailService.updateJson(jsonUpdateReqVO);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void useCanvas(Long id) {
        // 校验存在
        CanvasDO canvasDO = validateCanvasExists(id);
        // 修改其他同终端同类型的为关闭状态
        LambdaUpdateWrapper<CanvasDO> uw = new LambdaUpdateWrapper<>();
        uw.set(CanvasDO::getState, StateEnum.CLOSE.getValue());
        uw.eq(CanvasDO::getType, canvasDO.getType());
        canvasMapper.update(null, uw);
        // 修改状态为开启
        CanvasDO updateDO = new CanvasDO();
        updateDO.setId(id);
        updateDO.setState(StateEnum.OPEN.getValue());
        canvasMapper.updateById(updateDO);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteCanvas(Long id) {
        // 校验存在
        CanvasDO canvasDO = validateCanvasExists(id);
        if (StateEnum.OPEN.getValue().equals(canvasDO.getState())) {
            throw exception(CANVAS_USED);
        }
        // 删除
        canvasMapper.deleteById(id);
        canvasDetailService.batchDelete(id);
    }

    private CanvasDO validateCanvasExists(Long id) {
        CanvasDO canvasDO = canvasMapper.selectById(id);
        if (ObjectUtil.isNull(canvasDO)) {
            throw exception(CANVAS_NOT_EXISTS);
        }
        return canvasDO;
    }

    @Override
    public CanvasRespVO getCanvas(Long id) {
        // 校验存在
        CanvasDO canvasDO = validateCanvasExists(id);
        return CanvasConvert.INSTANCE.convert(canvasDO);
    }

    @Override
    public CanvasDetailRespVO getCanvasDetail(CanvasDetailReqVO reqVO) {
        return canvasDetailService.getCanvasDetail(reqVO);
    }

    @Override
    public List<CanvasDO> getCanvasList(Collection<Long> ids) {
        return canvasMapper.selectBatchIds(ids);
    }

    @Override
    public PageResult<CanvasDO> getCanvasPage(CanvasPageReqVO pageReqVO) {
        return canvasMapper.selectPage(pageReqVO);
    }

    @Override
    public List<CanvasDO> getCanvasList(CanvasExportReqVO exportReqVO) {
        return canvasMapper.selectList(exportReqVO);
    }

}
