package com.bonus.canteen.core.device.service.impl;

import java.sql.SQLIntegrityConstraintViolationException;
import java.util.List;

import cn.hutool.core.util.ObjectUtil;
import com.bonus.canteen.core.common.utils.MqUtil;
import com.bonus.canteen.core.device.dto.ApkDTO;
import com.bonus.canteen.core.device.dto.DeviceDTO;
import com.bonus.canteen.core.device.dto.DeviceSearchDTO;
import com.bonus.canteen.core.device.vo.DeviceFullInfoVO;
import com.bonus.canteen.core.user.domain.DeviceMqPersonalUpdateMessageDTO;
import com.bonus.common.core.exception.ServiceException;
import com.bonus.common.core.web.domain.AjaxResult;
import com.bonus.common.houqin.constant.GlobalConstants;
import com.bonus.common.houqin.mq.constant.LeMqConstant;
import com.bonus.common.houqin.utils.id.Id;
import com.bonus.common.security.utils.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.bonus.canteen.core.device.mapper.DoubleScreenMachineMapper;
import com.bonus.canteen.core.device.service.IDoubleScreenMachineService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 设备绑定多档口子Service业务层处理
 *
 * @author xsheng
 * @date 2025-04-03
 */
@Service
public class DoubleScreenMachineServiceImpl implements IDoubleScreenMachineService {
    @Autowired
    private DoubleScreenMachineMapper mapper;

    /**
     * 查询设备绑定多档口子
     *
     * @param dto 查询条件
     * @return 设备绑定多档口子
     */
    @Override
    public List<DeviceFullInfoVO> getDoubleScreenMachineList(DeviceSearchDTO dto) {
        return mapper.getDoubleScreenMachineList(dto);
    }

    /**
     * 新增设备绑定多档口子
     *
     * @param dto 设备绑定多档口子
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void insert(DeviceDTO dto) {
        if (dto == null) {
            throw new RuntimeException("参数为空");
        }
        if (ObjectUtil.isEmpty(dto.getDeviceName()) || ObjectUtil.isEmpty(dto.getDeviceSn()) || ObjectUtil.isEmpty(dto.getDeviceName())
                || ObjectUtil.isEmpty(dto.getAreaId()) || ObjectUtil.isEmpty(dto.getCanteenId()) || ObjectUtil.isEmpty(dto.getStallId())) {
            throw new RuntimeException("请先讲填写所有必填项，再提交相关数据！");
        }
        dto.setTenantId(GlobalConstants.TENANT_ID);
        dto.setCreateBy(String.valueOf(SecurityUtils.getUserId()));
        //判断设备sn、设备编号、设备名称是否存在
        int count = mapper.checkIsExistDeviceNum(dto.getDeviceNum(), null);
        if (count > 0) {
            throw new RuntimeException("设备编号已存在");
        }
        count = mapper.checkIsExistDeviceName(dto.getDeviceName(), null);
        if (count > 0) {
            throw new RuntimeException("设备名称已存在");
        }
        count = mapper.checkIsExistDeviceSn(dto.getDeviceSn(), null);
        if (count > 0) {
            throw new RuntimeException("设备sn已存在");
        }
        int code = mapper.insertMachine(dto);
        if (code == 0) {
            throw new RuntimeException("设备新增失败");
        }
        code = mapper.insertMachineBind(dto);
        if (code == 0) {
            throw new RuntimeException("设备绑定失败");
        }
        dto.setId(Id.next());
        code = mapper.insertDeviceRecipe(dto);
        if (code == 0) {
            throw new RuntimeException("添加菜谱关联失败");
        }
        //发送mq
        DeviceMqPersonalUpdateMessageDTO bean = new DeviceMqPersonalUpdateMessageDTO().setUpdatePerson(0, "update");
        MqUtil.pushToSingleDevice(bean, LeMqConstant.Topic.DEVICE_UPDATE_INFO_V4, dto.getDeviceSn());
    }

    /**
     * 修改设备绑定多档口子
     *
     * @param dto 设备绑定多档口子
     * @return 结果
     */
    @Override
    public void update(DeviceDTO dto) {
        if (dto == null) {
            throw new RuntimeException("参数为空");
        }
        if (ObjectUtil.isEmpty(dto.getDeviceName()) || ObjectUtil.isEmpty(dto.getDeviceSn()) || ObjectUtil.isEmpty(dto.getDeviceName())
                || ObjectUtil.isEmpty(dto.getAreaId()) || ObjectUtil.isEmpty(dto.getCanteenId()) || ObjectUtil.isEmpty(dto.getStallId())) {
            throw new RuntimeException("请先讲填写所有必填项，再提交相关数据！");
        }
        //判断设备sn、设备编号、设备名称是否存在
        int count = mapper.checkIsExistDeviceNum(dto.getDeviceNum(), dto.getDeviceId());
        if (count > 0) {
            throw new RuntimeException("设备编号已存在");
        }
        count = mapper.checkIsExistDeviceName(dto.getDeviceName(), dto.getDeviceId());
        if (count > 0) {
            throw new RuntimeException("设备名称已存在");
        }
        count = mapper.checkIsExistDeviceSn(dto.getDeviceSn(), dto.getDeviceId());
        if (count > 0) {
            throw new RuntimeException("设备sn已存在");
        }
        int code = mapper.updateMachine(dto);
        if (code == 0) {
            throw new RuntimeException("设备更新失败");
        }
        code = mapper.updateMachineBind(dto);
        if (code == 0) {
            throw new RuntimeException("设备绑定更新失败");
        }
        code = mapper.updateDeviceRecipe(dto);

        if (code == 0) {
            throw new RuntimeException("修改菜谱关联失败");
        }
        //发送mq
        DeviceMqPersonalUpdateMessageDTO bean = new DeviceMqPersonalUpdateMessageDTO().setUpdatePerson(0, "update");
        MqUtil.pushToSingleDevice(bean, LeMqConstant.Topic.DEVICE_UPDATE_INFO_V4, dto.getDeviceSn());
    }

    /**
     * 删除设备绑定多档口子信息
     *
     * @param deviceId 设备绑定多档口子ID
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(String deviceId) {
        int code = mapper.deleteMachine(deviceId);
        if (code == 0) {
            throw new RuntimeException("设备删除失败");
        }
        code = mapper.deleteMachineBind(deviceId);
        if (code == 0) {
            throw new RuntimeException("设备绑定删除失败");
        }
    }

    /**
     * 根据sn更新时间
     *
     * @param sn
     */
    @Override
    public void updateTimeBySn(String sn) {
        int code = mapper.updateTimeBySn(sn);
        if (code == 0) {
            throw new RuntimeException("更新时间失败");
        }
    }

    @Override
    public AjaxResult uploadApk(ApkDTO dto) {
        try {
            ApkDTO apkDTO = mapper.getApkByType(dto.getType(), dto.getVersion());
            if (apkDTO != null) {
                //检查最新的一条版本是否相同
                ApkDTO lastBean = mapper.getApkByType(dto.getType(), null);
                if (lastBean != null && !lastBean.getVersion().equals(dto.getVersion())){
                    return AjaxResult.error("该版本已存在");
                }
                mapper.updateApk(dto);
            } else {
                mapper.insertApk(dto);
            }
        } catch (Exception e) {
            return AjaxResult.error("操作失败");
        }
        return AjaxResult.success();
    }
}
