package com.ym.mec.biz.service.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import com.ym.mec.biz.dal.dao.ChargeTypeOrganizationFeeDao;
import com.ym.mec.biz.dal.dao.MusicGroupDao;
import com.ym.mec.biz.dal.dao.StudentRegistrationDao;
import com.ym.mec.biz.dal.dao.SubjectDao;
import com.ym.mec.biz.dal.dao.SubjectGoodsMapperDao;
import com.ym.mec.biz.dal.dto.ConditionDto;
import com.ym.mec.biz.dal.dto.SubFeeSettingDto;
import com.ym.mec.biz.dal.dto.SubjectApplyDetailDto;
import com.ym.mec.biz.dal.entity.ChargeTypeOrganizationFee;
import com.ym.mec.biz.dal.entity.Subject;
import com.ym.mec.biz.dal.entity.SubjectGoodsMapper;
import com.ym.mec.biz.dal.enums.YesOrNoEnum;
import com.ym.mec.biz.dal.page.SubjectQueryInfo;
import com.ym.mec.biz.service.SubjectService;
import com.ym.mec.common.dal.BaseDAO;
import com.ym.mec.common.page.PageInfo;
import com.ym.mec.common.service.impl.BaseServiceImpl;
import com.ym.mec.util.collection.MapUtil;

@Service
public class SubjectServiceImpl extends BaseServiceImpl<Integer, Subject> implements SubjectService {

    @Autowired
    private SubjectDao subjectDao;
    @Autowired
    private StudentRegistrationDao studentRegistrationDao;
    @Autowired
    private SubjectGoodsMapperDao subjectGoodsMapperDao;
    @Autowired
    private ChargeTypeOrganizationFeeDao chargeTypeOrganizationFeeDao;

    @Override
    public BaseDAO<Integer, Subject> getDAO() {
        return subjectDao;
    }

    @Override
    public List<Subject> findSubByMusicGroupId(String musicGroupId) {
        return subjectDao.findSubByMusicGroupId(musicGroupId);
    }

    @Override
    public PageInfo<Subject> queryPageTree(SubjectQueryInfo queryInfo) {
        PageInfo<Subject> pageInfo = queryPage(queryInfo);
        for (Subject subject : pageInfo.getRows()) {
            subject = getTree(subject, queryInfo.getDelFlag(), queryInfo.getTenantId());
        }
        return pageInfo;
    }

    @Override
    public List<Subject> findDefaultSubByChargeTypeId(Integer chargeTypeId, Integer organId, Integer number) {
        List<Subject> subByChargeTypeId = subjectDao.findDefaultSubByChargeTypeId(chargeTypeId);
        ChargeTypeOrganizationFee byOrganId = chargeTypeOrganizationFeeDao.findByOrganId(chargeTypeId, organId);
        if (byOrganId != null) {
            BigDecimal bigDecimal = new BigDecimal(number);
            subByChargeTypeId.forEach(e -> {
                e.setFee(byOrganId.getCourseFee().multiply(bigDecimal));
            });
        }
        return subByChargeTypeId;
    }

    @Override
    public List<SubjectApplyDetailDto> findSubApplyDetail(String musicGroupId) {
        List<SubjectApplyDetailDto> subApplyDetail = subjectDao.findSubApplyDetail(musicGroupId);
        
        List<SubjectApplyDetailDto> registers = studentRegistrationDao.queryStudentApplyDetail(musicGroupId);
        
        Map<Integer,SubjectApplyDetailDto> map = registers.stream().collect(Collectors.toMap(SubjectApplyDetailDto :: getSubjectId, t -> t));

        Map<Long,BigDecimal> maps = MapUtil.convertIntegerMap(studentRegistrationDao.querySubjectAmount(musicGroupId));
        subApplyDetail.forEach(detail -> {
        	SubjectApplyDetailDto dto = new SubjectApplyDetailDto();
        	if(map.containsKey(detail.getSubjectId())){
        		dto = map.get(detail.getSubjectId());
        	}
        	detail.setTotalAmount(maps.get(detail.getSubjectId().longValue()));
            detail.setPayNum(dto.getPayNum());
            detail.setApplyStudentNum(dto.getApplyStudentNum());
            detail.setPayingNum(dto.getPayingNum());
            detail.setCheckNum(dto.getCheckNum());
            detail.setNormalNum(dto.getNormalNum());
            detail.setBuyCloudTeacherNum(dto.getBuyCloudTeacherNum());
            detail.setCloudTeacherStudentNumOfApply(dto.getCloudTeacherStudentNumOfApply());
            detail.setNoCloudTeacherStudentNumOfNormal(dto.getNoCloudTeacherStudentNumOfNormal());
        });
        return subApplyDetail;
    }

    @Override
    public void upSetSubject(Subject subject) {
        if (subject.getDelFlag() == YesOrNoEnum.YES) {
            subjectDao.delete(subject.getId());
            return;
        }
        Integer parentId = upset(subject, null);
        List<Subject> subjects = subject.getSubjects();
        if (subjects != null && subjects.size() > 0) {
            subjects.forEach(e -> {
                upset(e, parentId);
            });
        }
    }

    private Integer upset(Subject subject, Integer parentId) {
        if (parentId != null) {
            subject.setParentSubjectId(parentId);
        }
        if (subject.getId() != null) {
            subject.setUpdateTime(new Date());
            subjectDao.update(subject);
        } else {
            subjectDao.insert(subject);
        }
        return subject.getId();
    }

    @Override
    public void markGoods(List<SubjectGoodsMapper> subjectGoodsMappers) {
        subjectGoodsMappers.forEach(e -> {
            upsetGoods(e);
        });
    }

    private void upsetGoods(SubjectGoodsMapper subjectGoodsMapper) {
        if (subjectGoodsMapper.getId() != null) {
            if (subjectGoodsMapper.getDelFlag()) {
                subjectGoodsMapperDao.delete(subjectGoodsMapper.getId());
                return;
            }
            subjectGoodsMapper.setUpdateTime(new Date());
            subjectGoodsMapperDao.update(subjectGoodsMapper);
        } else {
            subjectGoodsMapperDao.insert(subjectGoodsMapper);
        }
    }


    private Subject getTree(Subject sub, YesOrNoEnum yesOrNoEnum, Integer tenantId) {
        //得到根节点对象
        //获取子节点list
        List<Subject> subjects = subjectDao.findByParentId(sub.getId(), yesOrNoEnum, tenantId);
        //如果存在子节点
        if (subjects != null && subjects.size() > 0) {
            //将子节点list放入父节点对象
            sub.setSubjects(subjects);
            //遍历子节点....
            for (Subject subject : subjects) {
                getTree(subject, yesOrNoEnum, tenantId);
            }
        }
        return sub;
    }

    @Override
    public List<Subject> findTeacherSubjects(Integer userId) {
        return subjectDao.findTeacherSubjects(userId);
    }

    @Override
    public List<ConditionDto> findSubjectConditions() {
        return subjectDao.findSubjectConditions();
    }

    @Override
    public Map<Long, String> findSubjectMapBySubjectIdsList(List<String> subjectIdsList) {
        if (CollectionUtils.isEmpty(subjectIdsList)) {
            return new HashMap<>();
        }
        String subjectIdsString = StringUtils.join(subjectIdsList, ",");
        String[] split = subjectIdsString.split(",");
        List<String> subjectIds = new ArrayList<>(Arrays.asList(split));
        subjectIds = subjectIds.stream().distinct().collect(Collectors.toList());
        List<Map<Long, String>> bySubjecIds = subjectDao.findBySubjecIds(StringUtils.join(subjectIds, ","));
        Map<Long, String> subjectIdAndName = MapUtil.convertMybatisMap(bySubjecIds);
        return subjectIdAndName;
    }

    @Override
    public List<Subject> findSubSubjects(Integer parentSubjectId) {
        return subjectDao.findSubSubjects(parentSubjectId);
    }

    @Override
    public List<Subject> findBySubjectByIdList(List<Integer> subjectIdList) {
        return subjectDao.findBySubjectByIdList(StringUtils.join(subjectIdList, ","));
    }

    @Override
    public List<Subject> findBySubjectByIdList(String subjectIdList) {
        return subjectDao.findBySubjectByIdList(subjectIdList);
    }

    @Override
    public List<String> findBySubIds(String subIds) {
        return subjectDao.findBySubIds(subIds);
    }

    @Override
    public SubFeeSettingDto setSubjectInfo(Integer chargeTypeId) {
        return null;
    }

    @Override
    public PageInfo<Subject> queryPageByIdOrName(SubjectQueryInfo queryInfo) {
        PageInfo<Subject> pageInfo = new PageInfo<>(queryInfo.getPage(), queryInfo.getRows());
        Map<String, Object> params = new HashMap<String, Object>();
        MapUtil.populateMap(params, queryInfo);

        List<Subject> dataList = null;
        int count = subjectDao.queryPageByIdOrNameCount(params);
        if (count > 0) {
            pageInfo.setTotal(count);
            params.put("offset", pageInfo.getOffset());
            dataList = subjectDao.queryPageByIdOrName(params);
        }
        if (count == 0) {
            dataList = new ArrayList<>();
        }
        pageInfo.setRows(dataList);
        return pageInfo;
    }

    @Override
    public List<Subject> list() {
        return subjectDao.list();
    }
}
