package cn.com.qmth.examcloud.core.questions.service.impl;

import cn.com.qmth.examcloud.commons.exception.StatusException;
import cn.com.qmth.examcloud.core.questions.base.Constants;
import cn.com.qmth.examcloud.core.questions.base.Model;
import cn.com.qmth.examcloud.core.questions.dao.PropertyRepo;
import cn.com.qmth.examcloud.core.questions.dao.entity.Property;
import cn.com.qmth.examcloud.core.questions.dao.entity.dto.PropertyConvert;
import cn.com.qmth.examcloud.core.questions.dao.entity.dto.PropertyDto;
import cn.com.qmth.examcloud.core.questions.service.PropertyService;
import cn.com.qmth.examcloud.core.questions.service.bean.PropertyAssembler;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.google.common.collect.Lists;

import java.util.ArrayList;
import java.util.List;

/**
 * @author weiwenhai
 * @describle 课程属性
 * @date 2017.11.8
 */
@Service("propertyService")
public class PropertyServiceImpl implements PropertyService {
    private static final Logger log = LoggerFactory.getLogger(PropertyServiceImpl.class);
    @Autowired
    private PropertyRepo propertyRepo;

    @Override
    public void saveProperty(List<PropertyDto> dtoList, Long orgId) {
        if (CollectionUtils.isEmpty(dtoList)) {
            throw new StatusException(Constants.SYS_CODE_500, "属性列表不能为空！");
        }
        if (orgId == null) {
            throw new StatusException(Constants.SYS_CODE_500, "机构ID不能为空！");
        }

        PropertyAssembler propertyAssembler = new PropertyAssembler();
        for (int i = 0; i < dtoList.size(); i++) {
            //取到父类节点对象
            PropertyDto dto = dtoList.get(i);

            Property property = propertyAssembler.toProperty(dto);
            property.setNumber(i + 1);
            property.setOrgId(orgId);
            property = propertyRepo.save(property);

            List<Property> sonProperties = propertyAssembler.toPropertySon(dto);
            if (CollectionUtils.isNotEmpty(sonProperties)) {
                for (int j = 0; j < sonProperties.size(); j++) {
                    Property sonProperty = sonProperties.get(j);
                    sonProperty.setParentId(property.getId());
                    sonProperty.setNumber(j + 1);
                }

                propertyRepo.saveAll(sonProperties);
            }
        }
    }

    @Override
    public void saveProperty(PropertyDto dto) {
        if (dto.getOrgId() == null) {
            throw new StatusException(Constants.SYS_CODE_500, "机构ID不能为空！");
        }
        if (dto.getCoursePropertyId() == null) {
            throw new StatusException(Constants.SYS_CODE_500, "课程属性ID不能为空！");
        }
        if (dto.getParentId() == null) {
            throw new StatusException(Constants.SYS_CODE_500, "上级ID不能为空！");
        }
        if (StringUtils.isEmpty(dto.getName())) {
            throw new StatusException(Constants.SYS_CODE_500, "属性名不能为空！");
        }
        if (StringUtils.isEmpty(dto.getCode())) {
            throw new StatusException(Constants.SYS_CODE_500, "编码不能为空！");
        }

        if (StringUtils.isBlank(dto.getId())) {
            dto.setId(null);//剔除空字符串ID(导致异常数据)
        }

        Property property = PropertyConvert.of(dto);
        if (property.getId() == null) {
            //新增
            Property existProperty = propertyRepo.findByOrgIdAndCoursePropertyIdAndParentIdAndCode(property.getOrgId(), property.getCoursePropertyId(), property.getParentId(), property.getCode());
            if (existProperty != null) {
                throw new StatusException(Constants.SYS_CODE_500, "编码已经存在！");
            }

            Integer number = 0;
            List<Property> parentProperties = propertyRepo.findByOrgIdAndCoursePropertyIdAndParentIdOrderByNumber(property.getOrgId(), property.getCoursePropertyId(), property.getParentId());
            if (parentProperties != null && parentProperties.size() > 0) {
                number = parentProperties.get(parentProperties.size() - 1).getNumber();
            }

            property.setNumber(number + 1);
        } else {
            //修改
            Property oldProperty = Model.of(propertyRepo.findById(property.getId()));
            if (oldProperty == null) {
                throw new StatusException(Constants.SYS_CODE_500, "当前属性已不存在！");
            }

            if (!oldProperty.getCode().equals(property.getCode())) {
                //检查是否重名
                Property existProperty = propertyRepo.findByOrgIdAndCoursePropertyIdAndParentIdAndCode(property.getOrgId(), property.getCoursePropertyId(), property.getParentId(), property.getCode());
                if (existProperty != null) {
                    throw new StatusException(Constants.SYS_CODE_500, "编码已经存在！");
                }
            }
        }

        propertyRepo.save(property);
    }

    @Override
    public void deleteProperty(String propertyId, String coursePropertyId, Long orgId) {
        //查询子节点对象
        List<Property> childProperties = propertyRepo.findByOrgIdAndCoursePropertyIdAndParentIdOrderByNumber(orgId, coursePropertyId, propertyId);
        if (childProperties != null && childProperties.size() > 0) {
            for (Property property : childProperties) {
                propertyRepo.delete(property);
            }
        }

        propertyRepo.deleteById(propertyId);
    }

    @Override
    public List<Property> findProperties(String coursePropertyId, Long orgId) {
        List<PropertyDto> parentProperties = this.findParentPropertyDtoList(coursePropertyId, orgId);
        if (CollectionUtils.isEmpty(parentProperties)) {
            return Lists.newArrayList();
        }

        List<Property> properties = new ArrayList<>();

        for (PropertyDto parentDto : parentProperties) {
            Property parentProperty = PropertyConvert.of(parentDto);
            properties.add(parentProperty);

            if (parentDto.getPropertyList() != null && parentDto.getPropertyList().size() > 0) {
                for (PropertyDto sonDto : parentDto.getPropertyList()) {
                    Property sonProperty = PropertyConvert.of(sonDto);
                    properties.add(sonProperty);
                }
            }
        }

        return properties;
    }

    @Override
    public List<Property> findSonProperties(String propertyId) {
        return propertyRepo.findByParentIdOrderByNumber(propertyId);
    }

    @Override
    public List<Property> findParentProperties(String coursePropertyId, Long orgId) {
        return propertyRepo.findByOrgIdAndCoursePropertyIdAndParentIdOrderByNumber(orgId, coursePropertyId, Property.ROOT_PARENT_ID);
    }

    @Override
    public List<PropertyDto> findParentPropertyDtoList(String coursePropertyId, Long orgId) {
        //查询所有父节点对象
        List<Property> parentProperties = propertyRepo.findByOrgIdAndCoursePropertyIdAndParentIdOrderByNumber(orgId, coursePropertyId, Property.ROOT_PARENT_ID);

        List<PropertyDto> dtoList = new ArrayList<>();
        if (CollectionUtils.isEmpty(parentProperties)) {
            return dtoList;
        }

        for (Property parentProperty : parentProperties) {
            PropertyDto parentDto = PropertyConvert.of(parentProperty);

            //查询所有子节点对象
            List<Property> sonProperties = propertyRepo.findByOrgIdAndCoursePropertyIdAndParentIdOrderByNumber(orgId, coursePropertyId, parentProperty.getId());

            if (CollectionUtils.isNotEmpty(sonProperties)) {
                List<PropertyDto> list = new ArrayList<>();
                for (Property sonProperty : sonProperties) {
                    PropertyDto sonDto = PropertyConvert.of(sonProperty);
                    list.add(sonDto);
                }
                parentDto.setPropertyList(list);
            }

            dtoList.add(parentDto);
        }

        return dtoList;
    }

    @Override
    public void moveUp(PropertyDto dto) {
        Property curProperty = Model.of(propertyRepo.findById(dto.getId()));
        if (curProperty == null) {
            throw new StatusException(Constants.SYS_CODE_500, "当前属性已不存在！");
        }

        //查询所有一级属性
        List<Property> parentProperties = propertyRepo.findByOrgIdAndCoursePropertyIdAndParentIdOrderByNumber(curProperty.getOrgId(), curProperty.getCoursePropertyId(), Property.ROOT_PARENT_ID);
        if (CollectionUtils.isEmpty(parentProperties)) {
            throw new StatusException(Constants.SYS_CODE_500, "无法上移！");
        }

        if (parentProperties.size() == 1) {
            throw new StatusException(Constants.SYS_CODE_500, "无法上移！");
        }

        for (int i = 0; i < parentProperties.size(); i++) {
            if (curProperty.getId().equals(parentProperties.get(i).getId())) {
                if (i == 0) {
                    throw new StatusException(Constants.SYS_CODE_500, "无法上移！");
                }

                Property nearProperty = parentProperties.get(i - 1);

                //交换编号
                Integer curNumber = curProperty.getNumber();
                curProperty.setNumber(nearProperty.getNumber());
                nearProperty.setNumber(curNumber);

                propertyRepo.save(curProperty);
                propertyRepo.save(nearProperty);
            }
        }
    }

    @Override
    public void moveDown(PropertyDto dto) {
        Property curProperty = Model.of(propertyRepo.findById(dto.getId()));
        if (curProperty == null) {
            throw new StatusException(Constants.SYS_CODE_500, "当前属性已不存在！");
        }

        //查询所有一级属性
        List<Property> parentProperties = propertyRepo.findByOrgIdAndCoursePropertyIdAndParentIdOrderByNumber(curProperty.getOrgId(), curProperty.getCoursePropertyId(), Property.ROOT_PARENT_ID);

        if (CollectionUtils.isEmpty(parentProperties)) {
            throw new StatusException(Constants.SYS_CODE_500, "无法下移！");
        }

        if (parentProperties.size() == 1) {
            throw new StatusException(Constants.SYS_CODE_500, "无法下移！");
        }

        for (int i = 0; i < parentProperties.size(); i++) {
            if (curProperty.getId().equals(parentProperties.get(i).getId())) {
                if (i == (parentProperties.size() - 1)) {
                    throw new StatusException(Constants.SYS_CODE_500, "无法下移！");
                }

                Property nearProperty = parentProperties.get(i + 1);

                //交换编号
                Integer curNumber = curProperty.getNumber();
                curProperty.setNumber(nearProperty.getNumber());
                nearProperty.setNumber(curNumber);

                propertyRepo.save(curProperty);
                propertyRepo.save(nearProperty);
            }
        }
    }

}