package cn.iocoder.yudao.module.system.service.devuce;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.system.controller.app.devuce.vo.DevucePageReqVO;
import cn.iocoder.yudao.module.system.controller.app.devuce.vo.DevuceSaveReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.deviceInfo.DeviceInfoDO;
import cn.iocoder.yudao.module.system.dal.dataobject.devuce.DevuceDO;
import cn.iocoder.yudao.module.system.dal.dataobject.dishes.DishesDO;
import cn.iocoder.yudao.module.system.dal.dataobject.dishesnutrition.DishesNutritionDO;
import cn.iocoder.yudao.module.system.dal.dataobject.dishestype.DishesTypeDO;
import cn.iocoder.yudao.module.system.dal.mysql.deviceInfo.DeviceInfoMapper;
import cn.iocoder.yudao.module.system.dal.mysql.devuce.DevuceMapper;
import cn.iocoder.yudao.module.system.dal.mysql.dishes.DishesMapper;
import cn.iocoder.yudao.module.system.dal.mysql.dishesnutrition.DishesNutritionMapper;
import cn.iocoder.yudao.module.system.dal.mysql.dishestype.DishesTypeMapper;
import cn.iocoder.yudao.module.system.enums.ErrorCodeConstants;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;

/**
 * 设备 Service 实现类
 *
 * @author 开发账号
 */
@Service
@Validated
public class DevuceServiceImpl implements DevuceService {

    @Resource
    private DevuceMapper devuceMapper;
    @Resource
    private DishesMapper dishesMapper;
    @Resource
    private DishesTypeMapper dishesTypeMapper;
    @Resource
    private HttpServletRequest httpServletRequest;
    @Resource
    private DeviceInfoMapper deviceInfoMapper;
    @Resource
    private DishesNutritionMapper dishesNutritionMapper;
    @Override
    public Long createDevuce(DevuceSaveReqVO createReqVO) {
        // 插入
        DevuceDO devuce = BeanUtil.toBean(createReqVO, DevuceDO.class);
        devuceMapper.insert(devuce);
        // 返回
        return devuce.getId();
    }


    @Override
    public void updateDevuce(DevuceSaveReqVO updateReqVO) {
        // 校验存在
        /*if (ObjUtil.isNotEmpty(updateReqVO.getRemWeight())
                || ObjUtil.isNotEmpty(updateReqVO.getTotalWeight())
                || ObjUtil.isNotEmpty(updateReqVO.getDiff())) {
            //进行计算总量数据
            if (ObjUtil.isEmpty(updateReqVO.getDiff())) {
                //第一次绑定
                updateReqVO.setRemWeight(updateReqVO.getTotalWeight());
                bind(updateReqVO);
                return updateReqVO;
            } else {
                BigDecimal remWeight = updateReqVO.getRemWeight();
                BigDecimal diff = updateReqVO.getDiff();
                //下一次剩余的重量
                BigDecimal subtract = remWeight.subtract(diff);
                updateReqVO.setRemWeight(subtract);
                bind(updateReqVO);
                return updateReqVO;
            }
        }else{
            bind(updateReqVO);
            return null;
        }*/
            updateReqVO.setDeviceSn(this.getHearder());
            bind(updateReqVO);
    }
    public String getHearder(){
        try {
            return httpServletRequest.getHeader("Authorization");
        } catch (Exception e) {
            throw exception(2000_10_001,"无法获取设备编码");
        }
    }
    public void bind(DevuceSaveReqVO updateReqVO){
        if (devuceMapper.selectList(new LambdaQueryWrapperX<DevuceDO>()
                .eqIfPresent(DevuceDO::getDeviceSn,updateReqVO.getDeviceSn())) == null) {
            createDevuce(updateReqVO);
        }else{
            //自动换绑
            devuceMapper.update(new LambdaUpdateWrapper<DevuceDO>()
                    .set(DevuceDO::getBind,DevuceDO.LAPSE)
                    .set(DevuceDO::getDeleted,Boolean.TRUE)
                    .eq(DevuceDO::getDeviceSn,updateReqVO.getDeviceSn())
                    .eq(DevuceDO::getDeleted,Boolean.FALSE));
            createDevuce(updateReqVO);
        }
    }
    @Override
    public void deleteDevuce(Long id) {
        // 校验存在
        validateDevuceExists(id);
        // 删除
        devuceMapper.deleteById(id);
    }

    private void validateDevuceExists(Long id) {
        if (devuceMapper.selectById(id) == null) {
            throw exception(ErrorCodeConstants.DEVUCE_NOT_EXISTS);
        }
    }

    @Override
    public DevuceDO getDevuce(Long id) {
        return devuceMapper.selectById(id);
    }

    @Override
    public PageResult<DevuceDO> getDevucePage(DevucePageReqVO pageReqVO) {
        return devuceMapper.selectPage(pageReqVO);
    }

    @Override
    public DishesDO getDevuceList() {
        //获取当前设备绑定的菜品id
        DevuceDO devuceDO = devuceMapper.selectOne(new LambdaQueryWrapperX<DevuceDO>()
                .eq(DevuceDO::getDeviceSn, this.getHearder()));
        if(ObjUtil.isEmpty(devuceDO)){
            return null;
        }else{
            //获取菜品信息
            return dishesMapper.selectOne(new LambdaQueryWrapperX<DishesDO>()
                    .eqIfPresent(DishesDO::getId, devuceDO.getDishesId()));
        }
    }

    @Override
    public List<DishesDO> getDishesList(Long carteenId,Long dishecType) {
        //获取已绑定的菜品id
        List<Long> collect = devuceMapper.selectList(new LambdaQueryWrapperX<DevuceDO>()
                .eq(DevuceDO::getBind, DevuceDO.BIND))
                .stream()
                .map(DevuceDO::getDishesId).collect(Collectors.toList());
        if(ObjUtil.isNotEmpty(collect)){
            return  dishesMapper.selectList(new LambdaQueryWrapperX<DishesDO>()
                    .notIn(DishesDO::getId, collect)
                    .eq(DishesDO::getCarteenId,carteenId)
                    .eq(DishesDO::getDishecType,dishecType));
        }else{
            return   dishesMapper.selectList(new LambdaQueryWrapperX<DishesDO>()
                    .eq(DishesDO::getCarteenId,carteenId)
                    .eq(DishesDO::getDishecType,dishecType));
        }

    }

    /**
     * @param carteenId
     * @return
     * @Description: 获取菜品分类
     * @Author: qjq
     * @Date: 2024/4/9 上午10:33
     */
    @Override
    public List<DishesTypeDO> getDishesTypeList(Long carteenId) {
        return dishesTypeMapper.selectList(new LambdaQueryWrapperX<DishesTypeDO>().eq(DishesTypeDO::getCarteenId,carteenId));
    }

    /**
     * @param dishesId
     * @return
     * @Description: 获取菜品营养与菜品名称
     * @Author: qjq
     * @Date: 2024/4/19 下午2:44
     */
    @Override
    public List<Map> getDishesNutrition(Long dishesId,String cId) {

        List<DishesNutritionDO> rawDOS = dishesNutritionMapper.selectList(new LambdaQueryWrapperX<DishesNutritionDO>()
                .eqIfPresent(DishesNutritionDO::getDishesId, dishesId));
        List<Map> maps = BeanUtil.copyToList(rawDOS, Map.class);
        DishesDO dishesDO = dishesMapper.selectById(dishesId);
        String s;
        if(StrUtil.isNotBlank(cId)){
            s = dishesMapper.selectByCidUserName(cId);
        } else {
            s = null;
        }
        maps.forEach(f ->{
            f.put("dishesName",dishesDO.getDishesName());
            f.put("dishesImageUrl",dishesDO.getDishesImageUrl());
            f.put("userName",s);
        });
        return maps;
    }

    /**
     * @return
     * @Description: 根据ip获取门店id
     * @Author: qjq
     * @Date: 2024/4/10 下午4:28
     */
    @Override
    public Long getCarteenIdByIp() {
        String hearder = this.getHearder();
        List<DeviceInfoDO> deviceInfoDOS = deviceInfoMapper.selectList(new LambdaQueryWrapperX<DeviceInfoDO>()
                .eq(DeviceInfoDO::getDeviceIp, hearder)
        );
        if(ObjUtil.isNotEmpty(deviceInfoDOS)){
            return deviceInfoDOS.get(0).getCarteenId();
        }else{
            throw exception(2000_10_002,"无法通IP获取门店");
        }
    }
}