package com.inspect.metadata.prodevmnt.service.impl;

import com.inspect.base.core.constant.Color;
import com.inspect.metadata.prodevmnt.domain.BasedataDeviceType;
import com.inspect.metadata.prodevmnt.domain.vo.ProDeviceTypeTreeSelectVO;
import com.inspect.metadata.prodevmnt.mapper.BasedataDeviceTypeMapper;
import com.inspect.metadata.prodevmnt.service.IBasedataDeviceTypeService;
import com.inspect.metadata.prodevmnt.util.ProDeviceTypeTreeSelectUtil;
import com.inspect.base.core.utils.DateUtils;
import com.inspect.base.core.utils.StringUtils;
import com.inspect.base.core.utils.bean.BeanUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

@Service
public class BasedataDeviceTypeServiceImpl implements IBasedataDeviceTypeService {
    private final Logger log = LoggerFactory.getLogger(this.getClass());

    private final BasedataDeviceTypeMapper basedataDevicetypeMapper;

    public BasedataDeviceTypeServiceImpl(BasedataDeviceTypeMapper basedataDevicetypeMapper) {
        this.basedataDevicetypeMapper = basedataDevicetypeMapper;
    }

    public BasedataDeviceType selectBasedataDeviceTypeByDeviceTypeId(Long deviceTypeId) {
        return this.basedataDevicetypeMapper.selectBasedataDeviceTypeByDeviceTypeId(deviceTypeId);
    }

    public List<BasedataDeviceType> selectBasedataDeviceTypeList(BasedataDeviceType basedataDevicetype) {
        return this.basedataDevicetypeMapper.selectBasedataDeviceTypeList(basedataDevicetype);
    }

    public int insertBasedataDeviceType(BasedataDeviceType basedataDeviceType) {
        log.info("[METADATA] insertBasedataDeviceType, param: {}", basedataDeviceType);
        BasedataDeviceType info = basedataDevicetypeMapper.selectBasedataDeviceTypeByDeviceTypeId(basedataDeviceType.getParentId());
        basedataDeviceType.setLevel(info.getLevel() + 1);
        basedataDeviceType.setAncestors(info.getAncestors() + "," + basedataDeviceType.getParentId());
        basedataDeviceType.setCreateTime(DateUtils.getNowDate());
        return basedataDevicetypeMapper.insertBasedataDeviceType(basedataDeviceType);
    }

    public int updateBasedataDeviceType(BasedataDeviceType basedataDevicetype) {
        BasedataDeviceType info = this.basedataDevicetypeMapper.selectBasedataDeviceTypeByDeviceTypeId(basedataDevicetype.getParentId());
        basedataDevicetype.setLevel(info.getLevel() + 1);
        basedataDevicetype.setUpdateTime(DateUtils.getNowDate());
        return this.basedataDevicetypeMapper.updateBasedataDeviceType(basedataDevicetype);
    }

    public int deleteBasedataDeviceTypeByDeviceTypeIds(Long[] deviceTypeIds) {
        return this.basedataDevicetypeMapper.deleteBasedataDeviceTypeByDeviceTypeIds(deviceTypeIds);
    }

    public int deleteBasedataDeviceTypeByDeviceTypeId(Long deviceTypeId) {
        return this.basedataDevicetypeMapper.deleteBasedataDeviceTypeByDeviceTypeId(deviceTypeId);
    }

    public Map getDeviceTypeIdByDeviceTypeName(BasedataDeviceType basedataDevicetype) {
        return this.basedataDevicetypeMapper.getDeviceTypeIdByDeviceTypeName(basedataDevicetype);
    }

    public String checkDeviceTypeNameUnique(BasedataDeviceType basedataDevicetype) {
        long deviceTypeId = StringUtils.isNull(basedataDevicetype.getDeviceTypeId()) ? -1L : basedataDevicetype.getDeviceTypeId();
        BasedataDeviceType info = basedataDevicetypeMapper.checkDeviceTypeNameUnique(basedataDevicetype.getDeviceTypeName(), basedataDevicetype.getParentId());
        if (StringUtils.isNotNull(info) && info.getDeviceTypeId() != deviceTypeId) {
            return "1";
        } else {
            BasedataDeviceType subInfo = basedataDevicetypeMapper.checkDeviceTypeNameUnique(basedataDevicetype.getDeviceTypeName(), basedataDevicetype.getDeviceTypeId());
            return null != subInfo ? "1" : "0";
        }
    }

    public String checkDeviceTypeCodeUnique(BasedataDeviceType basedataDevicetype) {
        long deviceTypeId = StringUtils.isNull(basedataDevicetype.getDeviceTypeId()) ? -1L : basedataDevicetype.getDeviceTypeId().longValue();
        BasedataDeviceType info = this.basedataDevicetypeMapper.checkDeviceTypeCodeUnique(basedataDevicetype.getDeviceTypeCode(), basedataDevicetype.getDeviceTypeId());
        return StringUtils.isNotNull(info) && info.getDeviceTypeId() != deviceTypeId ? "1" : "0";
    }

    public int getMaxDeviceTypeId() {
        return this.basedataDevicetypeMapper.getMaxDeviceTypeId();
    }

    public Map<Long, String> getDeviceTypeAllPatchIdName() {
        BasedataDeviceType basedataDevicetype = new BasedataDeviceType();
        List<BasedataDeviceType> list = this.basedataDevicetypeMapper.selectBasedataDeviceTypeList(basedataDevicetype);
        Map<Long, String> map = new HashMap<>();
        BasedataDeviceType device;
        StringBuilder builder;
        if (!list.isEmpty()) {
            for (Iterator<BasedataDeviceType> iterator = list.iterator(); iterator.hasNext(); map.put(device.getDeviceTypeId(), builder.toString())) {
                device = iterator.next();
                builder = new StringBuilder();
                builder.append(device.getDeviceTypeName());
                Long parentId = device.getParentId();
                if (null != parentId) {
                    this.recursionGetIdName(parentId, builder);
                }
            }
        }

        return map;
    }

    public void recursionGetIdName(Long parentId, StringBuilder builder) {
        BasedataDeviceType basedataDevice = this.basedataDevicetypeMapper.selectBasedataDeviceTypeByDeviceTypeId(parentId);
        if (null != basedataDevice) {
            builder.insert(0, basedataDevice.getDeviceTypeName() + "/");
            if (null != basedataDevice.getParentId()) {
                parentId = basedataDevice.getParentId();
                this.recursionGetIdName(parentId, builder);
            }
        }

    }

    public List<ProDeviceTypeTreeSelectVO> getProDeviceTypeTreeSelect(BasedataDeviceType basedataDevicetype) {
        List<ProDeviceTypeTreeSelectVO> mainDevVOS = new ArrayList<>();
        List<BasedataDeviceType> list = basedataDevicetypeMapper.selectBasedataDeviceTypeList(basedataDevicetype);
        if (!list.isEmpty()) {
            for (BasedataDeviceType device : list) {
                ProDeviceTypeTreeSelectVO proDeviceTreeSelect = new ProDeviceTypeTreeSelectVO();
                BeanUtils.copyBeanProp(proDeviceTreeSelect, device);
                mainDevVOS.add(proDeviceTreeSelect);
            }
        }

        return ProDeviceTypeTreeSelectUtil.buildDeviceTree(mainDevVOS);
    }

    public List<BasedataDeviceType> getCompTypeTreeSelectByMainDeviceTypeId(BasedataDeviceType basedataDevicetype) {
        List<BasedataDeviceType> list = this.basedataDevicetypeMapper.selectBasedataDeviceTypeList(basedataDevicetype);
        if (null != list && !list.isEmpty()) {
            for (BasedataDeviceType deviceType : list) {
                this.getDeviceTypeChildByRecursion(deviceType);
            }
            log.info(Color.GREEN + "[METADATA] basedataDeviceType: {}, res size: {}" + Color.END, basedataDevicetype, list.size());
        } else {
            log.info(Color.GREEN + "[METADATA] basedataDeviceType: {}, res size: 0" + Color.END, basedataDevicetype);
        }


        return list;
    }

    private void getDeviceTypeChildByRecursion(BasedataDeviceType deviceType) {
        BasedataDeviceType basedataDevicetype = new BasedataDeviceType();
        basedataDevicetype.setParentId(deviceType.getDeviceTypeId());
        List<BasedataDeviceType> list = this.basedataDevicetypeMapper.selectBasedataDeviceTypeList(basedataDevicetype);
        if (!list.isEmpty()) {
            deviceType.setChildren(list);

            for (BasedataDeviceType type : list) {
                this.getDeviceTypeChildByRecursion(type);
            }
        }

    }
}
