package com.njcn.gather.type.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.njcn.common.pojo.enums.common.DataStateEnum;
import com.njcn.common.pojo.exception.BusinessException;
import com.njcn.gather.pqdif.pojo.po.PqPqdifPath;
import com.njcn.gather.pqdif.service.IPqPqdifPathService;
import com.njcn.gather.pojo.enums.DetectionResponseEnum;
import com.njcn.gather.system.dictionary.pojo.po.DictData;
import com.njcn.gather.system.dictionary.service.IDictDataService;
import com.njcn.gather.type.mapper.DevTypeMapper;
import com.njcn.gather.type.pojo.param.DevTypeParam;
import com.njcn.gather.type.pojo.po.DevType;
import com.njcn.gather.type.service.IDevTypeService;
import com.njcn.web.factory.PageFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author hongawen
 * @since 2025-01-13
 */
@Service
public class DevTypeServiceImpl extends ServiceImpl<DevTypeMapper, DevType> implements IDevTypeService {

    @Resource
    private IDictDataService dictDataService;

    @Resource
    private IPqPqdifPathService pqPqdifPathService;


    @Override
    public List<DevType> listAll() {
        LambdaQueryWrapper<DevType> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(DevType::getState, DataStateEnum.ENABLE.getCode())
                .orderByAsc(DevType::getName);
        List<DevType> devTypes = this.baseMapper.selectList(queryWrapper);
        return devTypes;
    }

    @Override
    public DevType getByName(String name) {
        return this.lambdaQuery().eq(DevType::getName, name).eq(DevType::getState, DataStateEnum.ENABLE.getCode()).one();
    }

    @Override
    public DevType getById(String id) {
        return this.lambdaQuery().eq(DevType::getId, id).eq(DevType::getState, DataStateEnum.ENABLE.getCode()).one();
    }

    @Override
    public List<DevType> listByIds(List<String> ids) {
        return this.lambdaQuery().in(DevType::getId, ids).eq(DevType::getState, DataStateEnum.ENABLE.getCode()).list();
    }

    @Override
    public Page<DevType> listDevType(DevTypeParam.QueryParam queryParam) {
        LambdaQueryWrapper<DevType> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DevType::getState, DataStateEnum.ENABLE.getCode())
                .like(StrUtil.isNotBlank(queryParam.getName()), DevType::getName, queryParam.getName())
                .orderByDesc(DevType::getCreateTime);
        Page<DevType> page = this.page(new Page<>(PageFactory.getPageNum(queryParam), PageFactory.getPageSize(queryParam)), wrapper);
        return page;
    }

    @Override
    @Transactional
    public boolean addDevType(DevTypeParam addParam) {
        addParam.setName(addParam.getName().trim());
        this.checkRepeat(addParam, false);
        this.checkPqdif(addParam.getPqdif());
        DevType devType = new DevType();
        BeanUtil.copyProperties(addParam, devType);
        devType.setState(DataStateEnum.ENABLE.getCode());
        return this.save(devType);
    }

    @Override
    @Transactional
    public boolean updateDevType(DevTypeParam.UpdateParam updateParam) {
        updateParam.setName(updateParam.getName().trim());
        this.checkRepeat(updateParam, true);
        this.checkPqdif(updateParam.getPqdif());
        DevType devType = new DevType();
        BeanUtil.copyProperties(updateParam, devType);
        return this.updateById(devType);
    }

    @Override
    @Transactional
    public boolean deleteDevType(List<String> ids) {
        return this.lambdaUpdate().in(DevType::getId, ids).set(DevType::getState, DataStateEnum.DELETED.getCode()).update();
    }

    @Override
    public DictData getReportName(String devTypeId) {
        DevType devType = this.lambdaQuery().eq(DevType::getId, devTypeId).eq(DevType::getState, DataStateEnum.ENABLE.getCode()).one();
        if (Objects.nonNull(devType)) {
            return dictDataService.getDictDataById(devType.getReportName());
        }
        return null;
    }

    private void checkRepeat(DevTypeParam param, boolean isExcludeSelf) {
        LambdaQueryWrapper<DevType> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DevType::getName, param.getName())
                .eq(DevType::getState, DataStateEnum.ENABLE.getCode());
        if (isExcludeSelf) {
            if (param instanceof DevTypeParam.UpdateParam) {
                wrapper.ne(DevType::getId, ((DevTypeParam.UpdateParam) param).getId());
            }
        }
        int count = this.count(wrapper);
        if (count > 0) {
            throw new BusinessException(DetectionResponseEnum.DEV_TYPE_NAME_REPEAT);
        }
    }

    private void checkPqdif(String pqdifId) {
        PqPqdifPath pqdif = pqPqdifPathService.lambdaQuery()
                .eq(PqPqdifPath::getId, pqdifId)
                .eq(PqPqdifPath::getState, DataStateEnum.ENABLE.getCode())
                .one();
        if (Objects.isNull(pqdif)) {
            throw new BusinessException(DetectionResponseEnum.PQDIF_NOT_EXIST);
        }
    }
}
