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

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.system.controller.admin.devuce.vo.DevuceListVO;
import cn.iocoder.yudao.module.system.controller.app.devuce.vo.DevucePageReqVO;
import cn.iocoder.yudao.module.system.controller.app.devuce.vo.DevuceReqVO;
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 cn.iocoder.yudao.module.system.service.carteen.CarteenService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
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;
    @Resource
    private CarteenService carteenService;


    @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,String dishesName) {
        //获取已绑定的菜品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{
        String mac = this.getHearder();
        DeviceInfoDO deviceInfoDO = deviceInfoMapper.selectOne(new LambdaQueryWrapper<DeviceInfoDO>()
                .eq(DeviceInfoDO::getDeviceIp, mac)
                .last("limit 1"));
        if(ObjectUtil.isNotEmpty(deviceInfoDO)){
            carteenId = deviceInfoDO.getCarteenId();
        }
        return   dishesMapper.selectList(new LambdaQueryWrapperX<DishesDO>()
                    .eq(DishesDO::getCarteenId,carteenId)
                    .gt(DishesDO::getId,94)
                    .eq(dishecType!=null,DishesDO::getDishecType,dishecType)
                    .like(StrUtil.isNotBlank(dishesName),DishesDO::getDishesName,dishesName)
                    .orderByDesc(DishesDO::getId));
//        }

    }

    @Override
    public PageResult<DishesDO> getDishesPage(Long carteenId, Long dishecType, String dishesName,Integer pageNo,Integer pageSize) {
        String mac = this.getHearder();
        DeviceInfoDO deviceInfoDO = deviceInfoMapper.selectOne(new LambdaQueryWrapper<DeviceInfoDO>()
                .eq(DeviceInfoDO::getDeviceIp, mac)
                .last("limit 1"));
        if(ObjectUtil.isNotEmpty(deviceInfoDO)){
            carteenId = deviceInfoDO.getCarteenId();
        }
        PageParam pageParam = new PageParam();
        pageParam.setPageNo(pageNo);
        pageParam.setPageSize(pageSize);
        PageResult<DishesDO> dishesDOPageResult = dishesMapper.selectPage(pageParam, null, new LambdaQueryWrapperX<DishesDO>()
                .eq(DishesDO::getCarteenId, carteenId)
                .gt(DishesDO::getId, 94)
                .eq(dishecType != null, DishesDO::getDishecType, dishecType)
                .like(StrUtil.isNotBlank(dishesName), DishesDO::getDishesName, dishesName)
                .orderByDesc(DishesDO::getId));

        return dishesDOPageResult;
    }

    /**
     * @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 ->{
            String nutritionName = f.get("nutritionName").toString();
            f.put("nutritionName",nutritionName.substring(0,nutritionName.length()-7));
            f.put("dishesName",dishesDO.getDishesName());
            f.put("dishesImageUrl",dishesDO.getDishesImageUrl());
            f.put("userName",s);
            f.put("dishesSumPrice",dishesDO.getDishesSumPrice());
        });
        if(CollectionUtil.isEmpty(maps)){
            List<Map> newMap = new ArrayList<>();
            List<String> list = Arrays.asList("能量", "脂肪", "碳水化合物", "蛋白质");

            for(int i= 0;i<4;i++){
                HashMap<Object, Object> map = new HashMap<>();
                map.put("dishesName",dishesDO.getDishesName());
                map.put("dishesImageUrl",dishesDO.getDishesImageUrl());
                map.put("userName",s);
                map.put("dishesSumPrice",dishesDO.getDishesSumPrice());
                map.put("nutritionName",list.get(i));
                map.put("nutritionNumber",100);
                map.put("nutritionPer","33.34%");
                newMap.add(map);
            }
            return newMap;
        }
        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获取门店");
        }
    }

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

    @Override
    public void updateWeight(DevuceReqVO updateReqVO) {
        String hearder = this.getHearder();
        devuceMapper.update(new DevuceDO(),new LambdaUpdateWrapper<DevuceDO>()
                .set(updateReqVO.getRemWeight()!=null,DevuceDO::getRemWeight,updateReqVO.getRemWeight())
                .set(updateReqVO.getTotalWeight()!=null,DevuceDO::getTotalWeight,updateReqVO.getTotalWeight())
                .set(updateReqVO.getTotalWeight()!=null,DevuceDO::getFirstWeight,updateReqVO.getTotalWeight())
                .eq(DevuceDO::getDeviceSn,hearder)
                .eq(DevuceDO::getBind,true));
    }

    @Override
    public void addWeight(BigDecimal addWeight) {
        String hearder = this.getHearder();
        List<DevuceDO> devuceDOS = devuceMapper.selectList(Wrappers.<DevuceDO>lambdaQuery()
                .eq(DevuceDO::getDeviceSn, hearder)
                .eq(DevuceDO::getBind, true));
        if(CollectionUtil.isNotEmpty(devuceDOS)){
            DevuceDO devuceDO = devuceDOS.get(0);
            devuceDO.setTotalWeight(devuceDO.getTotalWeight().add(addWeight));
            devuceDO.setRemWeight(devuceDO.getRemWeight().add(addWeight));
            devuceMapper.updateById(devuceDO);
        }
    }

    @Override
    public List<DevuceListVO> getList(Long storeId) {
        ArrayList<DevuceListVO> devuceListVOS = new ArrayList<>();
        List<DeviceInfoDO> deviceInfoDOS = deviceInfoMapper.selectList(Wrappers.<DeviceInfoDO>lambdaQuery()
                .eq(DeviceInfoDO::getCarteenId, storeId));
        if(CollectionUtil.isEmpty(deviceInfoDOS)){
            return devuceListVOS;
        }
        List<String> collect = deviceInfoDOS.stream().map(DeviceInfoDO::getDeviceIp).collect(Collectors.toList());

        List<DevuceDO> devuceDOS = devuceMapper.selectList(Wrappers.<DevuceDO>lambdaQuery()
                .in(DevuceDO::getDeviceSn, collect)
                .eq(DevuceDO::getBind, true));
        if(CollectionUtil.isEmpty(devuceDOS)){
            return devuceListVOS;
        }
        for (DevuceDO devuceDO:devuceDOS){
            DevuceListVO devuceListVO = new DevuceListVO();
            BeanUtil.copyProperties(devuceDO,devuceListVO);
            DishesDO dishesDO = dishesMapper.selectById(devuceDO.getDishesId());
            if(ObjUtil.isNotEmpty(dishesDO)&& ObjUtil.isNotEmpty(dishesDO.getDishesName())){
                devuceListVO.setDishesName(dishesDO.getDishesName());
            }
            devuceListVOS.add(devuceListVO);
        }
        return devuceListVOS;
    }

}