package com.yida.data.user.service.impl;

import cc.mrbird.febs.common.redis.service.RedisService;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yida.data.common.core.entity.constant.CachePrefixConstant;
import com.yida.data.common.core.entity.school.EduYidaAppAccount;
import com.yida.data.common.core.entity.system.Dept;
import com.yida.data.common.core.entity.system.EduYidaApp;
import com.yida.data.common.core.entity.user.EduParent;
import com.yida.data.common.core.entity.user.EduParentStudent;
import com.yida.data.common.core.entity.user.EduParentType;
import com.yida.data.common.core.entity.user.EduStudent;
import com.yida.data.common.core.utils.AppUtil;
import com.yida.data.common.core.vo.NameValueVO;
import com.yida.data.common.service.CommonService;
import com.yida.data.system.feign.RemoteDeptService;
import com.yida.data.user.dto.ListStudentDTO;
import com.yida.data.user.mapper.EduParentMapper;
import com.yida.data.user.mapper.EduParentStudentMapper;
import com.yida.data.user.mapper.EduStudentMapper;
import com.yida.data.user.service.EduParentService;
import com.yida.data.user.service.EduParentTypeService;
import com.yida.data.user.vo.ParentInfoVO;
import com.yida.data.user.vo.StaParentDistributeVO;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.Map.Entry;

@Service
@RequiredArgsConstructor
@Transactional(rollbackFor = Exception.class)
public class EduParentServiceImpl extends ServiceImpl<EduParentMapper, EduParent> implements EduParentService {

    private final EduStudentMapper eduStudentMapper;
    private final EduParentTypeService eduParentTypeService;
    private final EduParentStudentMapper eduParentStudentMapper;

    private final RedisService redisService;
    private final CommonService commonService;

    private final RemoteDeptService remoteDeptService;

    /**
     * 保存本地家长信息
     *
     * @param eduParent 需要保存的家长信息
     * @return com.yida.data.common.core.common.ResultBean<com.yida.data.common.core.entity.user.EduParent>
     * @author ZYJ
     * @date 2021/8/21 15:27
     */
    @Override
    public EduParent saveLocalParent(EduParent eduParent) {
        EduParentType parentType = eduParentTypeService.getParentType(eduParent.getParentType());
        // 设置家长类型id字段
        eduParent.setParentTypeId(parentType.getId());
        // 保存本地家长信息
        this.save(eduParent);
        return eduParent;
    }

    @Override
    public void dealParentWxDelete(String wxId, Long schoolId) {
        EduParent parent =
                baseMapper.selectOne(Wrappers.lambdaQuery(new EduParent())
                        .eq(EduParent::getWxId, wxId)
                        .eq(EduParent::getSchoolId, schoolId));
        if (parent != null) {
            List<EduParentStudent> parentStudentList =
                    eduParentStudentMapper.selectList(
                            Wrappers.lambdaQuery(new EduParentStudent()).eq(EduParentStudent::getParentId, parent.getId()));
            if (CollUtil.isNotEmpty(parentStudentList)) {
                // 删除学生缓存
                String[] studentIds =
                        parentStudentList.stream().filter(x -> x.getStudentId() != null)
                                .map(x -> x.getStudentId().toString()).toArray(String[]::new);
                redisService.hdel(CachePrefixConstant.STUDENT_DATA, studentIds);
            }
            baseMapper.deleteById(parent.getId());
            eduParentStudentMapper
                    .delete(Wrappers.lambdaQuery(new EduParentStudent()).eq(EduParentStudent::getParentId, parent.getId()));
        }
    }


    @Override
    public void dealWxParentChange(EduParent eduParent, Long schoolId) {
        Dept school = commonService.getDept(schoolId);
        Boolean createStudent = false;
        if (eduParent.getChildren().size() == 1) {
            String studentUserid = eduParent.getChildren().get(0).get("student_userid").toString();
            Long count = eduStudentMapper.selectCount(Wrappers.<EduStudent>lambdaQuery()
                    .eq(EduStudent::getSchoolId, schoolId)
                    .eq(EduStudent::getWxId, studentUserid));
            if (count == 0) {
                createStudent = true;
            }
        }
        if (createStudent) {
            return;
        }
        EduParent existParent = getOne(Wrappers.lambdaQuery(new EduParent()).eq(EduParent::getWxId,
                eduParent.getWxId()));
        if (existParent != null) {
            eduParent.setId(existParent.getId());
            updateById(eduParent);
        } else {
            // 学校绑定了易达app
            if (school.getSchoolType().contains(Dept.TYPE_YIDA_APP)) {
                EduYidaApp yidaApp = commonService.getYidaApp(schoolId);
                EduYidaAppAccount yidaAppAccount = commonService.getYidaAppAccount(schoolId, 0);
                eduParent
                        .setYidaAppUserId(AppUtil.userSave(eduParent.getMobile(), "用户" + eduParent.getMobile(), yidaApp));
                AppUtil.subscribeFollow(yidaAppAccount.getYidaAppAccountId(),
                        eduParent.getYidaAppUserId(), yidaApp);
            }
            save(eduParent);
        }
        List<Long> ids = new ArrayList<>();
        //学生关系
        for (Map<String, Object> child : eduParent.getChildren()) {
            String studentId = child.get("student_userid").toString();
            String relation = child.get("relation").toString();
            EduStudent student =
                    eduStudentMapper.selectOne(Wrappers.lambdaQuery(new EduStudent()).eq(EduStudent::getWxId, studentId)
                            .eq(EduStudent::getSchoolId, schoolId));
            if (student == null) {
                // 不存在学生  不进行增加家长操作
                return;
            }
            ids.add(student.getId());
            redisService.hdel(CachePrefixConstant.STUDENT_DATA, student.getId().toString());
            EduParentStudent eduParentStudent =
                    eduParentStudentMapper.getRelationByParentAndStudent(eduParent.getId(), student.getId());
            if (eduParentStudent == null) {
                // 关系不存在进行添加
                eduParentStudent = new EduParentStudent();
                eduParentStudent.setStudentId(student.getId());
                eduParentStudent.setParentId(eduParent.getId());
            } else if (eduParentStudent.getParentTypeName().equals(relation)) {
                // 关系未改变不用更改关系
                continue;
            }
            EduParentType type = eduParentTypeService.getParentType(relation);
            eduParentStudent.setParentTypeId(type.getId());
            if (eduParentStudent.getId() == null) {
                eduParentStudentMapper.insert(eduParentStudent);
            } else {
                eduParentStudentMapper.updateById(eduParentStudent);
            }
        }
        if (CollUtil.isEmpty(ids)) {
            ids.add(0L);
        }
        eduParentStudentMapper.delete(Wrappers.lambdaQuery(new EduParentStudent())
                .eq(EduParentStudent::getParentId, eduParent.getId())
                .notIn(EduParentStudent::getStudentId, ids));
        updateById(eduParent);
    }


    @Override
    public List<ParentInfoVO> listParentByClass(List<Long> classIds, String parentName) {
        return baseMapper.listParentByClass(classIds, parentName);
    }

    @Override
    public ParentInfoVO getParentWithStudent(String wxId, String mobile, Long schoolId) {
        return baseMapper.getParentWithStudent(wxId, mobile, schoolId);
    }

    @Override
    public StaParentDistributeVO staParentDistribute(List<Long> schoolIds) {
        StaParentDistributeVO vo = new StaParentDistributeVO();
        Map<String, Integer> sectionMap = new HashMap<>();
        Map<String, Integer> typeMap = new HashMap<>();
        Set<Long> parentIds = new HashSet<>();
        // 查询学生数据
        List<EduStudent> studentList = eduStudentMapper.listStudent(ListStudentDTO.builder().schoolIds(schoolIds).build());
        // 构造原始数据
        for (EduStudent student : studentList) {
            for (EduParent parent : student.getParents()) {
                sectionMap.put(student.getSectionName(), sectionMap.getOrDefault(student.getSectionName(), 0) + 1);
                typeMap.put(parent.getParentType(), typeMap.getOrDefault(parent.getParentType(), 0) + 1);
                parentIds.add(parent.getId());
            }
        }
        // 转换成列表数据
        // 学段数据
        if (!sectionMap.isEmpty()) {
            List<NameValueVO<String, Integer>> sectionList = new ArrayList<>();
            for (Entry<String, Integer> section : sectionMap.entrySet()) {
                sectionList.add(
                        new NameValueVO<String, Integer>(section.getKey() == null ? "未知" : section.getKey(), section.getValue()));
            }
            vo.setSection(sectionList);
        }
        // 身份数据
        if (!typeMap.isEmpty()) {
            List<NameValueVO<String, Integer>> typeList = new ArrayList<>();
            for (Entry<String, Integer> type : typeMap.entrySet()) {
                typeList.add(
                        new NameValueVO<String, Integer>(type.getKey() == null ? "未知" : type.getKey(), type.getValue()));
            }
            vo.setType(typeList);
        }
        vo.setNum(parentIds.size());
        return vo;
    }

    @Override
    public void checkParent(Long schoolId, String mobile, String appUserId) {
        // 判断是否已经有家长数据
        List<EduParent> parentList = list(new LambdaQueryWrapper<>(new EduParent())
                .eq(EduParent::getMobile, mobile)
                .eq(EduParent::getSchoolId, schoolId));
        if (CollUtil.isEmpty(parentList)) {
            // 添加家长数据
            EduParent eduParent = new EduParent();
            eduParent.setMobile(mobile);
            eduParent.setWxId(StrUtil.uuid().replace("-", ""));
            if (StringUtils.isNotBlank(appUserId)) {
                eduParent.setYidaAppUserId(appUserId);
            }
            eduParent.setSchoolId(schoolId);
            save(eduParent);
        }
    }
}
