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

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

import javax.annotation.Resource;

import com.ym.mec.auth.api.entity.SysMenu;
import com.ym.mec.biz.dal.dao.*;
import com.ym.mec.biz.dal.entity.*;
import com.ym.mec.biz.service.MusicGroupSubjectPlanService;
import com.ym.mec.common.entity.ImResult;
import com.ym.mec.common.entity.ImUserModel;
import com.ym.mec.im.ImFeignService;
import com.ym.mec.util.date.DateUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.ym.mec.auth.api.client.SysUserFeignService;
import com.ym.mec.auth.api.entity.SysUser;
import com.ym.mec.auth.api.enums.SysUserType;
import com.ym.mec.auth.api.enums.UserLockFlag;
import com.ym.mec.biz.dal.dto.StudentApplyDetailDto;
import com.ym.mec.biz.dal.dto.StudentFeeDto;
import com.ym.mec.biz.dal.dto.StudentInfo;
import com.ym.mec.biz.dal.enums.DealStatusEnum;
import com.ym.mec.biz.dal.enums.GoodsType;
import com.ym.mec.biz.dal.enums.OrderDetailTypeEnum;
import com.ym.mec.biz.dal.enums.OrderTypeEnum;
import com.ym.mec.biz.dal.enums.YesOrNoEnum;
import com.ym.mec.biz.dal.page.StudentRegistrationQueryInfo;
import com.ym.mec.biz.service.StudentPaymentOrderDetailService;
import com.ym.mec.biz.service.StudentPaymentOrderService;
import com.ym.mec.biz.service.StudentRegistrationService;
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 StudentRegistrationServiceImpl extends BaseServiceImpl<Long, StudentRegistration> implements StudentRegistrationService {

    @Resource
    private StudentRegistrationDao studentRegistrationDao;
    @Autowired
    private StudentPaymentOrderService studentPaymentOrderService;
    @Autowired
    private StudentPaymentOrderDetailService studentPaymentOrderDetailService;
    @Autowired
    private TeacherDao teacherDao;
    @Autowired
    private ClassGroupDao classGroupDao;
    @Autowired
    private ClassGroupStudentMapperDao classGroupStudentMapperDao;
    @Autowired
    private MusicGroupStudentFeeDao musicGroupStudentFeeDao;
    @Autowired
    private MusicGroupPaymentCalenderDao musicGroupPaymentCalenderDao;
    @Autowired
    private MusicGroupSubjectPlanDao musicGroupSubjectPlanDao;
    @Autowired
    private SubjectDao subjectDao;
    @Autowired
    private ImFeignService imFeignService;
    @Autowired
    private MusicGroupSubjectPlanService musicGroupSubjectPlanService;

    @Override
    public BaseDAO<Long, StudentRegistration> getDAO() {
        return studentRegistrationDao;
    }

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

        List<StudentApplyDetailDto> dataList = null;
        int count = studentRegistrationDao.queryStudentDetailCount(params);
        if (count > 0) {
            pageInfo.setTotal(count);
            params.put("offset", pageInfo.getOffset());
            dataList = studentRegistrationDao.queryStudentDetailPage(params);
        }
        if (count == 0) {
            dataList = new ArrayList<>();
        }
        pageInfo.setRows(dataList);
        return pageInfo;
    }

    @Override
    public boolean batchUpdateSubject(String userIds, Integer subId) {
        String[] userId = userIds.split(",");
        StudentRegistration studentRegistration;
        Date date = new Date();
        for (String str : userId) {
            studentRegistration = studentRegistrationDao.get(Long.parseLong(str));
            if (studentRegistration.getPaymentStatus() == YesOrNoEnum.NO) {
                studentRegistration.setUpdateTime(date);
                studentRegistration.setSubjectId(subId);
                studentRegistrationDao.update(studentRegistration);
            }
        }
        return true;
    }

    @Override
    public StudentFeeDto queryFeeDetail(Integer studentId, String musicGroupId) {
//		return studentRegistrationDao.queryFeeDetail(studentId,musicGroupId);
        return null;
    }

    @Override
    public List<Map<String,Object>> getNoClassStuBySubjectId(String musicGroupId, String actualSubjectId) {
        List<StudentRegistration> students = studentRegistrationDao.getNoClassStuBySubjectId(musicGroupId, actualSubjectId);
        List<Map<String,Object>> mapArrayList = new ArrayList<>();
        if(students != null && students.size() > 0){
            String[] subjectIds = actualSubjectId.split(",");
            if(subjectIds != null && subjectIds.length > 0){
                List<Map<Integer, String>> subjectNames = subjectDao.queryNameByIds(actualSubjectId);
                Map<Integer, String> subjectNameMap = MapUtil.convertMybatisMap(subjectNames);
                for (int i = 0;i<subjectIds.length;i++){
                    Map<String,Object> resultMap = new HashMap<>(3);
                    int subjectId = Integer.parseInt(subjectIds[i]);
                    List<StudentRegistration> collect = students.stream().filter(e -> e.getSubjectId().equals(subjectId)).collect(Collectors.toList());
                    resultMap.put("subjectId",subjectId);
                    resultMap.put("subjectName",subjectNameMap.get(subjectId));
                    resultMap.put("rows",collect);
                    mapArrayList.add(resultMap);
                }
            }
        }
        return mapArrayList;
    }

    @Override
    public List<Map<Integer,Long>> getNoClassStuCountBySubjectId(String musicGroupId) {
        return studentRegistrationDao.getNoClassStuCountBySubjectId(musicGroupId);
    }

    @Override
    public Integer updateByUserIdAndMusicGroupId(StudentRegistration studentRegistration) {
        return studentRegistrationDao.updateByUserIdAndMusicGroupId(studentRegistration);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public StudentRegistration addStudent(StudentRegistration studentRegistration) {
        Date date = new Date();
        int userId = 0;
        SysUser sysUser = studentRegistrationDao.getSysUserByPhone(studentRegistration.getParentsPhone());
        if (sysUser == null) {
            sysUser = new SysUser();
            sysUser.setPhone(studentRegistration.getParentsPhone());
            sysUser.setCreateTime(date);
            sysUser.setUpdateTime(date);
            sysUser.setLockFlag(UserLockFlag.NOACTIVATED);
            sysUser.setDelFlag(com.ym.mec.auth.api.enums.YesOrNoEnum.NO);
            sysUser.setUserType(SysUserType.STUDENT);
            sysUser.setGender(studentRegistration.getGender());
            sysUser.setOrganId(studentRegistration.getOrganId());
            sysUser.setRealName(studentRegistration.getName());
            sysUser.setIdCardNo(studentRegistration.getIdCardNo());
            teacherDao.addSysUser(sysUser);
            userId = sysUser.getId();
        }
        studentRegistration.setUserId(sysUser.getId());
        studentRegistrationDao.insert(studentRegistration);
        //增加报名学生数
        MusicGroupSubjectPlan musicOneSubjectClassPlan = musicGroupSubjectPlanService.getMusicOneSubjectClassPlan(studentRegistration.getMusicGroupId(), studentRegistration.getSubjectId());
        musicOneSubjectClassPlan.setApplyStudentNum(musicOneSubjectClassPlan.getApplyStudentNum()+1);
        return studentRegistration;
    }

    @Override
    public StudentInfo queryStudentInfo(Integer userId) {
        return studentRegistrationDao.queryStudentInfo(userId);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public StudentPaymentOrder addOrder(Integer userId, BigDecimal amount, String orderNo, String paymentChannel, BigDecimal courseFee, List<MusicGroupSubjectGoodsGroup> goodsGroups, List<Goods> goodsList, List<Goods> otherGoodsList, String musicGroupId) {

        Date date = new Date();
        StudentPaymentOrder studentPaymentOrder = new StudentPaymentOrder();
        studentPaymentOrder.setUserId(userId);
        studentPaymentOrder.setOrderNo(orderNo);
        studentPaymentOrder.setType(OrderTypeEnum.APPLY);
        studentPaymentOrder.setExpectAmount(amount);
        studentPaymentOrder.setActualAmount(amount);
        studentPaymentOrder.setStatus(DealStatusEnum.ING);
        studentPaymentOrder.setPaymentChannel(paymentChannel);
        studentPaymentOrder.setMusicGroupId(musicGroupId);
        studentPaymentOrderService.insert(studentPaymentOrder);

        ArrayList<StudentPaymentOrderDetail> studentPaymentOrderDetailList = new ArrayList<>();
        StudentPaymentOrderDetail studentPaymentOrderDetail = new StudentPaymentOrderDetail();
        studentPaymentOrderDetail.setType(OrderDetailTypeEnum.COURSE);
        studentPaymentOrderDetail.setPrice(courseFee);
        studentPaymentOrderDetail.setCreateTime(date);
        studentPaymentOrderDetail.setUpdateTime(date);
        studentPaymentOrderDetail.setPaymentOrderId(studentPaymentOrder.getId());
        studentPaymentOrderDetailList.add(studentPaymentOrderDetail);
        //乐器及打包辅件
        if (goodsGroups != null) {
            for (MusicGroupSubjectGoodsGroup goodsGroup : goodsGroups) {
                StudentPaymentOrderDetail studentPaymentOrderDetail4goodsGroup = new StudentPaymentOrderDetail();
                OrderDetailTypeEnum type = null;
                if (goodsGroup.getType().equals(GoodsType.INSTRUMENT)) {
                    type = OrderDetailTypeEnum.MUSICAL;
                } else if (goodsGroup.getType().equals(GoodsType.ACCESSORIES)) {
                    type = OrderDetailTypeEnum.ACCESSORIES;
                } else if (goodsGroup.getType().equals(GoodsType.OTHER)) {
                    type = OrderDetailTypeEnum.TEACHING;
                }
                studentPaymentOrderDetail4goodsGroup.setType(type);
                studentPaymentOrderDetail4goodsGroup.setPrice(goodsGroup.getPrice());
                studentPaymentOrderDetail4goodsGroup.setGoodsIdList(goodsGroup.getGoodsIdList());
                studentPaymentOrderDetail4goodsGroup.setCreateTime(date);
                studentPaymentOrderDetail4goodsGroup.setUpdateTime(date);
                studentPaymentOrderDetail4goodsGroup.setPaymentOrderId(studentPaymentOrder.getId());
                studentPaymentOrderDetailList.add(studentPaymentOrderDetail4goodsGroup);
            }
        }

        //单独辅件
        if (goodsList != null) {
            for (Goods goods : goodsList) {
                StudentPaymentOrderDetail studentPaymentOrderDetail4goods = new StudentPaymentOrderDetail();
                studentPaymentOrderDetail4goods.setType(OrderDetailTypeEnum.ACCESSORIES);
                studentPaymentOrderDetail4goods.setPrice(goods.getGroupPurchasePrice());
                studentPaymentOrderDetail4goods.setGoodsIdList(goods.getId().toString());
                studentPaymentOrderDetail4goods.setCreateTime(date);
                studentPaymentOrderDetail4goods.setUpdateTime(date);
                studentPaymentOrderDetail4goods.setPaymentOrderId(studentPaymentOrder.getId());
                studentPaymentOrderDetailList.add(studentPaymentOrderDetail4goods);

            }
        }
        //单独教谱
        if (otherGoodsList != null) {
            for (Goods goods : otherGoodsList) {
                StudentPaymentOrderDetail studentPaymentOrderDetail4otherGoods = new StudentPaymentOrderDetail();
                studentPaymentOrderDetail4otherGoods.setType(OrderDetailTypeEnum.TEACHING);
                studentPaymentOrderDetail4otherGoods.setPrice(goods.getGroupPurchasePrice());
                studentPaymentOrderDetail4otherGoods.setGoodsIdList(goods.getId().toString());
                studentPaymentOrderDetail4otherGoods.setCreateTime(date);
                studentPaymentOrderDetail4otherGoods.setUpdateTime(date);
                studentPaymentOrderDetail4otherGoods.setPaymentOrderId(studentPaymentOrder.getId());
                studentPaymentOrderDetailList.add(studentPaymentOrderDetail4otherGoods);
            }
        }

        studentPaymentOrderDetailService.batchAdd(studentPaymentOrderDetailList);

        //增加报名学生数
//        MusicGroupSubjectPlan musicOneSubjectClassPlan = musicGroupSubjectPlanService.getMusicOneSubjectClassPlan(musicGroupId, studentPaymentOrder.get);
//        musicOneSubjectClassPlan.setApplyStudentNum(musicOneSubjectClassPlan.getApplyStudentNum()+1);

        return studentPaymentOrder;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public StudentPaymentOrder reAddOrder(Integer userId, BigDecimal amount, String orderNo, String paymentChannel, BigDecimal courseFee, List<MusicGroupSubjectGoodsGroup> goodsGroups, List<Goods> goodsList, List<Goods> otherGoodsList, String musicGroupId, StudentPaymentOrder oldOrder) {
        //关闭老订单
        oldOrder.setStatus(DealStatusEnum.CLOSE);
        studentPaymentOrderService.update(oldOrder);
        Date date = new Date();
        StudentPaymentOrder studentPaymentOrder = new StudentPaymentOrder();
        studentPaymentOrder.setUserId(userId);
        studentPaymentOrder.setOrderNo(orderNo);
        studentPaymentOrder.setType(OrderTypeEnum.APPLY);
        studentPaymentOrder.setExpectAmount(amount);
        studentPaymentOrder.setActualAmount(amount);
        studentPaymentOrder.setStatus(DealStatusEnum.ING);
        studentPaymentOrder.setPaymentChannel(paymentChannel);
        studentPaymentOrder.setMusicGroupId(musicGroupId);
        studentPaymentOrderService.insert(studentPaymentOrder);

        ArrayList<StudentPaymentOrderDetail> studentPaymentOrderDetailList = new ArrayList<>();
        StudentPaymentOrderDetail studentPaymentOrderDetail = new StudentPaymentOrderDetail();
        studentPaymentOrderDetail.setType(OrderDetailTypeEnum.COURSE);
        studentPaymentOrderDetail.setPrice(courseFee);
        studentPaymentOrderDetail.setCreateTime(date);
        studentPaymentOrderDetail.setUpdateTime(date);
        studentPaymentOrderDetail.setPaymentOrderId(studentPaymentOrder.getId());
        studentPaymentOrderDetailList.add(studentPaymentOrderDetail);
        //乐器及打包辅件
        if (goodsGroups != null) {
            for (MusicGroupSubjectGoodsGroup goodsGroup : goodsGroups) {
                StudentPaymentOrderDetail studentPaymentOrderDetail4goodsGroup = new StudentPaymentOrderDetail();
                OrderDetailTypeEnum type = null;
                if (goodsGroup.getType().equals(GoodsType.INSTRUMENT)) {
                    type = OrderDetailTypeEnum.MUSICAL;
                } else if (goodsGroup.getType().equals(GoodsType.ACCESSORIES)) {
                    type = OrderDetailTypeEnum.ACCESSORIES;
                } else if (goodsGroup.getType().equals(GoodsType.OTHER)) {
                    type = OrderDetailTypeEnum.TEACHING;
                }
                studentPaymentOrderDetail4goodsGroup.setType(type);
                studentPaymentOrderDetail4goodsGroup.setPrice(goodsGroup.getPrice());
                studentPaymentOrderDetail4goodsGroup.setGoodsIdList(goodsGroup.getGoodsIdList());
                studentPaymentOrderDetail4goodsGroup.setCreateTime(date);
                studentPaymentOrderDetail4goodsGroup.setUpdateTime(date);
                studentPaymentOrderDetail4goodsGroup.setPaymentOrderId(studentPaymentOrder.getId());
                studentPaymentOrderDetailList.add(studentPaymentOrderDetail4goodsGroup);
            }
        }

        //单独辅件
        if (goodsList != null) {
            for (Goods goods : goodsList) {
                StudentPaymentOrderDetail studentPaymentOrderDetail4goods = new StudentPaymentOrderDetail();
                studentPaymentOrderDetail4goods.setType(OrderDetailTypeEnum.ACCESSORIES);
                studentPaymentOrderDetail4goods.setPrice(goods.getGroupPurchasePrice());
                studentPaymentOrderDetail4goods.setGoodsIdList(goods.getId().toString());
                studentPaymentOrderDetail4goods.setCreateTime(date);
                studentPaymentOrderDetail4goods.setUpdateTime(date);
                studentPaymentOrderDetail4goods.setPaymentOrderId(studentPaymentOrder.getId());
                studentPaymentOrderDetailList.add(studentPaymentOrderDetail4goods);

            }
        }
        //单独教谱
        if (otherGoodsList != null) {
            for (Goods goods : otherGoodsList) {
                StudentPaymentOrderDetail studentPaymentOrderDetail4otherGoods = new StudentPaymentOrderDetail();
                studentPaymentOrderDetail4otherGoods.setType(OrderDetailTypeEnum.TEACHING);
                studentPaymentOrderDetail4otherGoods.setPrice(goods.getGroupPurchasePrice());
                studentPaymentOrderDetail4otherGoods.setGoodsIdList(goods.getId().toString());
                studentPaymentOrderDetail4otherGoods.setCreateTime(date);
                studentPaymentOrderDetail4otherGoods.setUpdateTime(date);
                studentPaymentOrderDetail4otherGoods.setPaymentOrderId(studentPaymentOrder.getId());
                studentPaymentOrderDetailList.add(studentPaymentOrderDetail4otherGoods);
            }
        }

        studentPaymentOrderDetailService.batchAdd(studentPaymentOrderDetailList);

        return studentPaymentOrder;
    }

    @Override
    public StudentRegistration queryByUserIdAndMusicGroupId(Integer userId, String musicGroupId) {
        return studentRegistrationDao.queryByUserIdAndMusicGroupId(userId, musicGroupId);
    }

    @Override
    public StudentRegistration getByPhoneAndMusicGroupId(String musicGroupId, String parentsPhone) {
        return studentRegistrationDao.getByPhoneAndMusicGroupId(musicGroupId, parentsPhone);
    }

    @Override
    public Integer insertStudent(StudentRegistration studentRegistration) throws Exception {
        StudentRegistration phoneAndMusicGroupId = studentRegistrationDao.getByPhoneAndMusicGroupId(studentRegistration.getMusicGroupId(), studentRegistration.getParentsPhone());
        if(phoneAndMusicGroupId != null){
            throw new Exception("该学员已存在");
        }else {
            SysUser sysUser = studentRegistrationDao.getSysUserByPhone(studentRegistration.getParentsPhone());
            Integer userId;
            if(sysUser == null){
                //新增user
                sysUser = new SysUser();
                sysUser.setRealName(studentRegistration.getName());
                sysUser.setUsername(studentRegistration.getName());
                sysUser.setGender(studentRegistration.getGender());
                sysUser.setUserType(SysUserType.STUDENT);
                teacherDao.addSysUser(sysUser);
                userId = sysUser.getId();
                //注册到融云
                ImResult register = imFeignService.register(new ImUserModel(userId.toString(), sysUser.getUsername(), sysUser.getAvatar()));
                sysUser.setImToken(register.getToken());
                teacherDao.updateUser(sysUser);
            }else {
                userId = sysUser.getId();
            }
            studentRegistration.setUserId(userId);
            //学生报名表
            studentRegistrationDao.insert(studentRegistration);
            if(studentRegistration.getClassGroupId() != null){
                ClassGroup classGroup = classGroupDao.get(studentRegistration.getClassGroupId());
                if(classGroup != null){
                    if(classGroup.getMusicGroupId().equals(studentRegistration.getMusicGroupId())){
                        throw new Exception("班级录入错误");
                    }else {
                        //修改实际学生人数
                        classGroup.setStudentNum(classGroup.getStudentNum() + 1);
                        classGroup.setUpdateTime(new Date());
                        classGroupDao.update(classGroup);
                    }
                }else {
                    throw new Exception("班级不存在");
                }
                //新增班级学生关系
                classGroupStudentMapperDao.insert(new ClassGroupStudentMapper(studentRegistration.getClassGroupId(),userId));
                //乐团学生费用表
                MusicGroupSubjectPlan musicOneSubjectClassPlan = musicGroupSubjectPlanDao.getMusicOneSubjectClassPlan(studentRegistration.getMusicGroupId(), studentRegistration.getActualSubjectId());
                //获取当前月
                Integer month = Integer.parseInt(DateUtil.getMonth(new Date()));
                //获取下次缴费月份
                List<MusicGroupPaymentCalender> musicGroupPaymentCalenders = musicGroupPaymentCalenderDao.findByMusicGroupId(studentRegistration.getMusicGroupId());
                List<Integer> months = musicGroupPaymentCalenders.stream().map(e -> e.getPaymentMonth()).collect(Collectors.toList());
                for (int i = 0;i<months.size();i++){
                    if(months.get(i).equals(month)){
                        month = i == months.size()-1?months.get(0):months.get(i+1);
                    }
                }
                Calendar calendar = Calendar.getInstance();
                calendar.add(Calendar.MONTH, month);
                DateUtil.getFirstDayOfMonth(calendar.getTime());
                //保存乐团学生费用表
                musicGroupStudentFeeDao.insert(new MusicGroupStudentFee(studentRegistration.getMusicGroupId(),
                        userId,studentRegistration.getSubjectId(),musicOneSubjectClassPlan.getFee(),
                        DateUtil.getFirstDayOfMonth(calendar.getTime()),0,studentRegistration.getTemporaryCourseFee()));
            }
            return userId;
        }
    }

    @Override
    public List<StudentRegistration> findClassGroupStu(String musicGroupId, Integer classGroupId) {
        return studentRegistrationDao.findClassGroupStu(musicGroupId, classGroupId);
    }
}