package com.ssj.service.course.service.impl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.repository.PagingAndSortingRepository;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import com.ssj.bean.course.domain.CourseDetailFeedbackLib;
import com.ssj.bean.course.domain.CourseSeries;
import com.ssj.bean.course.domain.CourseSeriesDetail;
import com.ssj.bean.course.domain.CourseSeriesJoin;
import com.ssj.bean.course.domain.CourseSeriesSetting;
import com.ssj.bean.weixin.libmy.domain.LibVip;
import com.ssj.bean.weixin.push.domain.Miniprogram;
import com.ssj.bean.weixin.push.domain.SendTemplateShort;
import com.ssj.bean.weixin.user.domain.User;
import com.ssj.dao.course.dao.CourseQueryDao;
import com.ssj.dao.course.dao.ICSDao;
import com.ssj.framework.basic.utils.DateHelper;
import com.ssj.framework.core.common.service.BaseServiceImpl;
import com.ssj.framework.core.persistence.DynamicSpecifications;
import com.ssj.framework.core.persistence.SearchFilter;
import com.ssj.framework.weixin.util.WxUtil;
import com.ssj.service.course.req.CourseChangeReq;
import com.ssj.service.course.res.ChangeLessonDetailRes;
import com.ssj.service.course.res.ChangeLessonRes;
import com.ssj.service.course.res.CourseLessonRes;
import com.ssj.service.course.service.CourseSeriesJoinService;
import com.ssj.service.course.service.CourseSeriesOrderService;
import com.ssj.service.course.service.CourseSeriesSettingService;
import com.ssj.service.course.service.ICSDetailService;
import com.ssj.service.course.service.ICSService;
import com.ssj.service.course.service.ICouseLibFeedbackService;
import com.ssj.service.weixin.library.service.ILibVipService;
import com.ssj.service.weixin.push.service.PushTemplateService;
import com.ssj.service.weixin.user.service.UserService;

@Service(version="1.0")
@Transactional
public class CSServiceImpl extends BaseServiceImpl<CourseSeries, String> implements ICSService {

	@Autowired
	private ICSDao dao;
	@Autowired
	private CourseQueryDao courseQueryDao;
	@Autowired
	private CourseSeriesOrderService courseSeriesOrderService;

	@Autowired
	private ICSDetailService csDetailService;

	@Autowired
	private ICouseLibFeedbackService courseLibFeedbackService;

	@Autowired
	private CourseSeriesJoinService joinService;

	@Autowired
	private CourseSeriesSettingService settingService;

	@Autowired
	private UserService userService;

	@Autowired
	private ILibVipService vipService;

	 @Autowired
	private PushTemplateService pushTemplateService;

	@Override
	public PagingAndSortingRepository<CourseSeries, String> getDao() {

		return dao;
	}

	private static List<String> colors=new ArrayList<String>();

	static{
		colors.add("#FF80A8");
		colors.add("#00B7FF");
		colors.add("#3A95FF");
		colors.add("#FFBE0F");
		colors.add("#FF6464");
		colors.add("#FF80A8");
		colors.add("#00B7FF");
		colors.add("#3A95FF");
		colors.add("#FFBE0F");
		colors.add("#FF6464");
	}



	@Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
	public List<Map<String, Object>> getCourseAll() {
		List<Map<String, Object>> list =new ArrayList<Map<String,Object>>();
		Map<String, Object> map1 =new HashMap<String, Object>();
		map1.put("course_hot_lable", "1");
		map1.put("list", this.getCourseAll(1, 1));
		Map<String, Object> map2 =new HashMap<String, Object>();
		map2.put("course_hot_lable", "2");
		map2.put("list", this.getCourseAll(2, 1));
		Map<String, Object> map3 =new HashMap<String, Object>();
		map3.put("course_hot_lable", "3");
		map3.put("list", this.getCourseAll(3, 2));
		list.add(map1);
		list.add(map2);
		list.add(map3);
		return list;
	}

	@Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
	public Page<CourseSeries> findByPage(Map<String, Object> params, Pageable initPage) {
		Map<String, SearchFilter> filters = SearchFilter.parse(params);
		Specification<CourseSeries> specification = DynamicSpecifications.bySearchFilter(filters.values(), CourseSeries.class);
		return  dao.findAll(specification, initPage);
	}

	@Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
	public List<Map<String, Object>> getCourseAll(int courseTypeLabel,int offset) {
		return courseQueryDao.getCourseAll(courseTypeLabel,offset);
	}

	@Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
	public List<Map<String, Object>> getManageJoin(String userId) {
		return courseQueryDao.getManageJoin(userId);
	}

	@Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
	public List<Map<String, Object>> getTeacherCourseInfo(String libId, String userId,int type) {

		return courseQueryDao.getTeacherCourseInfo(libId,userId,type);
	}

	@Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
	public List<CourseSeries> findByBuy(String libId) {
		List<CourseSeries> list = courseQueryDao.findByBuy(libId);
		for (CourseSeries courseSeries : list) {
			String rate =dao.getDurationByLibIdAndCourseSeriesId(libId, courseSeries.getId());
			courseSeries.setInterruptRate(rate!=null ? rate :"0");
			courseSeries.setStudentNumber(courseSeriesOrderService.getCurrentStudentSize(libId,  courseSeries.getId()));
		}
		return list;
	}

	@Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
	public Map<String, Object> getThisCourseInfo(Map<String, Object> search) {
		String format="yyyy-MM-dd";
		Map<String, Object> reqMap=courseQueryDao.getThisCourseInfo(search);

		/**
		 * 计算出
		 * next_course
		 * studyed_course
		 * course_index
		 *
		 * course_details_id
		 * course_unit
		 */
		if(reqMap!=null && reqMap.get("course_series_id")!=null){
			Integer courseIndex=1;
			String nextCourse="无";
			Integer studyedCourse=0;
			String courseDetailsId="";
			String courseUnit="";
			Integer isSend=0;
			String feedbackId="";

			String courseDate="";
			if(reqMap.get("course_date")!=null){
				courseDate=reqMap.get("course_date").toString();
			}
			String[] courseDateArrays=courseDate.split(",");
			//courseIndex=courseDateArrays.length;//默认值为最大
			Date curDate=DateHelper.parseDate(DateHelper.format(new Date(), format), format);
			for (int i = 0; i < courseDateArrays.length; i++) {
				if(DateHelper.parseDate(courseDateArrays[i], format).compareTo(curDate) == 0){
					courseIndex = i+1;
				}
				if(DateHelper.parseDate(courseDateArrays[i], format).compareTo(curDate)>0){
					nextCourse=courseDateArrays[i];
					//courseIndex=i+1;
					if(i>0){
						if(DateHelper.parseDate(courseDateArrays[i-1], format).compareTo(curDate)==0){
							studyedCourse=i-1;
						}else{
							studyedCourse=i;
						}
					}
					break;
				}
			}
			CourseSeriesDetail courseSeriesDetail=csDetailService.getCourseSeriesDetailByCourseIndex((String)reqMap.get("course_series_id"), courseIndex);
			if(courseSeriesDetail!=null){
				courseDetailsId=courseSeriesDetail.getId();
				courseUnit=courseSeriesDetail.getCourseUnit();

				String libId=search.get("libId").toString();
				CourseDetailFeedbackLib courseDetailFeedbackLib=courseLibFeedbackService.getCourseDetailFeedbackLibByTeacherId(libId,courseDetailsId);

				if(courseDetailFeedbackLib!=null){
					isSend=1;
					feedbackId=courseDetailFeedbackLib.getId();
				}
			}
			reqMap.put("studyed_course", studyedCourse);
			reqMap.put("course_details_id", courseDetailsId);
			reqMap.put("next_course", nextCourse);
			reqMap.put("course_unit", courseUnit);
			reqMap.put("is_send", isSend);
			reqMap.put("feedback_id", feedbackId);
		}
		return reqMap;
	}

	@Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
	public List<Map<String, Object>> getCourseStudentList(Map<String, Object> search) {

		return courseQueryDao.getCourseStudentList(search);
	}

	@Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
	public Map<String, Object> getFeedBackInfo(String courseDetailId, String vipId,String libId) {

		return courseQueryDao.getFeedBackInfo(courseDetailId,vipId,libId);
	}

	@Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
	public String getLatestTime(int type) {
		return dao.getLatestTime(type);
	}

	@Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
	public Double getAvg(int type) {
		return dao.getAvg(type);
	}

	@Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
	public Long getCountVip(int type) {
		return dao.getCountVip(type);
	}

	@Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
	public Long getfinAll(int type) {
		return dao.getfinAll(type);
	}

	@Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
	public Map<String, Object> getFeedBackInfoById(String id) {

		return courseQueryDao.getFeedBackInfoById(id);
	}


    @Transactional(propagation = Propagation.NOT_SUPPORTED)
	public String getCourseSeriesByColor() {
		String reqColor="#FF6464";
		List<String> list= courseQueryDao.getCourseSeriesByColor();
		for (String color : colors) {
			if(!list.contains(color)){
				reqColor=color;
				break;
			}
		}
		return reqColor;
	}

	@Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
	public List<Map<String, Object>> getCourseStudentListV2(Map<String, Object> search) {

		return courseQueryDao.getCourseStudentListV2(search);
	}

	@Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
	public List<CourseLessonRes> findOrderCourseList(String libId,String userId) {
		List<Map<String, Object>> list = courseQueryDao.findOrderCourseList(libId,userId);
		List<CourseLessonRes> resList = new ArrayList<CourseLessonRes>();
		if(list !=null && list.size()>0){
			for (Map<String, Object> map : list) {
				CourseLessonRes res = new CourseLessonRes();
				res.setCourseCover(map.get("cover_url")==null?"":map.get("cover_url").toString());
				res.setCourseName(map.get("course_name")==null?"":map.get("course_name").toString());
				res.setCourseSeriesId(map.get("id").toString());
				res.setLessonCount(Integer.parseInt(map.get("lesson_count").toString()));
				res.setStudentCount(Integer.parseInt(map.get("student_count")==null?"0":map.get("student_count").toString()));
				res.setNextCourseTime(map.get("next_course_time")==null?"":map.get("next_course_time").toString());
				resList.add(res);
			}
		}
		return resList;
	}

	@Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
	public Map<String, Object> studentManagerList(String libId, String courseSeriesId) {
		Map<String, Object> map = new HashMap<>();
		CourseSeries series = this.getById(courseSeriesId);
		map.put("courseSeriesId", courseSeriesId);
		map.put("courseName", series.getCourseName());
		map.put("courseCover", series.getCoverUrl());
		List<Map<String, Object>> list = courseQueryDao.studentManagerList(libId,courseSeriesId);
		map.put("studentCount", list.size());
		List<Map<String, Object>> list2 = new ArrayList<Map<String, Object>>();
		if(list != null && list.size()>0){
			for (Map<String, Object> map2 : list) {
				Map<String, Object> map3 = new HashMap<>();
				map3.put("vipId", map2.get("id"));
				map3.put("childName", map2.get("child_name"));
				map3.put("headImg", map2.get("img_url"));
				list2.add(map3);
			}

		}
		map.put("list", list2);

		return map;
	}

	@Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
	public Map<String, Object> bkManagerList(String libId, String courseSeriesId) {
		Map<String, Object> map = new HashMap<>();
		CourseSeries series = this.getById(courseSeriesId);
		map.put("courseSeriesId", courseSeriesId);
		map.put("courseName", series.getCourseName());
		map.put("courseCover", series.getCoverUrl());
		map.put("sugStudent", series.getClassPnum());
		map.put("sugStudentGrade", series.getCourseTarget());
		//查询一个学生
		CourseSeriesJoin join = joinService.findOneDataByAny(libId,courseSeriesId);
		List<Map<String, Object>> list = courseQueryDao.findDetailBySeriesId(libId,courseSeriesId,join.getVipId());
		map.put("courseCount", list.size());
		List<Map<String, Object>> list2 = new ArrayList<Map<String, Object>>();
		if(list != null && list.size()>0){
			for (Map<String, Object> map2 : list) {
				Map<String, Object> map3 = new HashMap<>();
				map3.put("detailId", map2.get("id"));
				map3.put("detailName", map2.get("course_unit"));
				map3.put("courseDuration", map2.get("course_duration"));
				map3.put("lastUsedTime",map2.get("begin_time")==null?"":map2.get("begin_time").toString().substring(0, 19) );
				map3.put("courseContent", map2.get("course_content").toString().replaceAll("\r","").replaceAll("\n", ""));
				list2.add(map3);
			}

		}
		map.put("list", list2);

		return map;
	}

	@Override
	public void confirmChange(CourseChangeReq req) {


		//查找详情实体
		CourseSeriesDetail detail = csDetailService.getById(req.getCourseDetailId());
		//找到一条老师设置
		CourseSeriesSetting  setting = settingService.fingByCourseSeriesIdAndLibIdLimit(detail.getSeriesId(), req.getLibId());
		List<String> weeks =Arrays.asList(setting.getWeeks().split(","));
		StringBuffer  stringbuff =new StringBuffer();
		String dates = setting.getCourseDate();
		List<String> dateList = Arrays.asList(dates.split(","));
		Date openTime = DateHelper.parseDate(req.getNewTime(), "yyyy-MM-dd");
		Date newDate = DateHelper.parseDate(req.getNewTime(), "yyyy-MM-dd");
		Date oldDate = DateHelper.parseDate(req.getOldTime(), "yyyy-MM-dd");
		Date searchDate = newDate;
		if(newDate.before(oldDate)){
			searchDate = newDate;
		}else{
			searchDate = oldDate;
		}
		//找到一个学生
		CourseSeriesJoin join = joinService.findOneDataByDetail(req.getLibId(),req.getCourseDetailId());
		//查出学生的所有上课时间
		List<CourseSeriesJoin> list = joinService.findbyLibAndVip(req.getLibId(),detail.getSeriesId(),join.getVipId(),join.getNum(),searchDate);
		list.add(0,join);
		//找出离新调课时间最近的一堂课的实体
		CourseSeriesJoin join2 = joinService.findOneDataByDetailAndTime(req.getLibId(),detail.getSeriesId(),searchDate);
		if(req.getIsPostpone()!=null && req.getIsPostpone()==2){ //以后的课程按照开课设置顺延

			//List<CourseSeriesDetail> list =csDetailService.findBySeriesIdAndAfterIndex(detail.getSeriesId(), detail.getCourseIndex());
			String courseDates =  dates.split(req.getOldTime())[0];

			int day = DateHelper.getday(openTime)-1	;//周四
			// 计算今天是周几，  看是否有提交的 周几上课
			Integer few =-1;
			if(few==-1){
				for (int j = 0; j < weeks.size(); j++) {
					few=	Integer.parseInt(weeks.get(j))-day>=0?j:-1;
					if(few>-1){
						break;
					}
				}
			}
			if(few ==-1)few =0;
			Integer we =Integer.parseInt(weeks.get(few));//第一个
			Integer oldwe =day;

			stringbuff.append(courseDates);
			int num = join2==null?1:join2.getNum();
			int i =0;
			for (CourseSeriesJoin join1:list) {
				if(i>0 || (we.equals(oldwe))){
					if(weeks.size()==1){
						if(i==0){
							openTime=DateHelper.getNextDay(openTime,(we-oldwe>0?we-oldwe:we-oldwe+7));
						}else{
							openTime=DateHelper.getNextDay(openTime,(we+7-oldwe));
						}

					}else{
						openTime=DateHelper.getNextDay(openTime, we >=oldwe ? (we-oldwe) :(we+7-oldwe));
					}
					//openTime=DateHelper.getNextDay(openTime, we >=oldwe ? (we-oldwe) :(we+7-oldwe));
				}

				stringbuff.append(DateHelper.format(openTime,"yyyy-MM-dd"));;
				if(i<list.size()-1){
					stringbuff.append(",");
				}
				num++;
				joinService.updateJoinDate(join1.getCourseDetailsId(),  req.getLibId(), num, openTime);
				if(i>0 || (we.equals(oldwe))){
					oldwe =we;
					few ++;
					few=few %weeks.size();
					we =Integer.parseInt(weeks.get(few));
				}

				i++;
			}


		}else{ //不顺延

			//查一条开课设置
			//int courseIndex = detail.getCourseIndex()-1;
			boolean ischange = true;
			for (int j = 0; j < dateList.size(); j++) {
				if(req.getOldTime().equals(dateList.get(j)) && ischange){
					stringbuff.append(req.getNewTime());
					ischange=false;
				}else{
					stringbuff.append(dateList.get(j));
				}
				if(j<dateList.size()-1){
					stringbuff.append(",");
				}else{
					openTime = DateHelper.parseDate(dateList.get(j), "yyyy-MM-dd");
				}
			}
			int num = join2==null?0:join2.getNum();
			for (CourseSeriesJoin join1:list) {
				//join1.setNum(num);
				//joinService.save(join1);
				num++;
				if(join1.getCourseDetailsId().equals(req.getCourseDetailId())){
					//更新记录
					joinService.updateDetailsData(req.getCourseDetailId(),req.getNewTime(),req.getLibId(),num);
				}else{
					joinService.updateJoinDate2(join1.getCourseDetailsId(),  req.getLibId(), num);
				}


			}
		}

		if(openTime.before(newDate)){
			openTime = newDate;
		}
		//更改开课设置表
		String courseDate = stringbuff.toString();
		List<String> courseList = Arrays.asList(courseDate.split(","));
		Collections.sort(courseList);
		settingService.updateSettingOneDay(req.getLibId(),StringUtils.join(courseList, ","),detail.getSeriesId(),openTime);
		if(req.getIsCall()!=null && req.getIsCall()==2){ //调整上课时间通知家长
			//获取到joinList
			List<CourseSeriesJoin> joinList = joinService.findbyLibJoinList(detail.getId(),req.getLibId());
			for (CourseSeriesJoin courseSeriesJoin : joinList) {
				String id = "OPENTM410945628";
				//尊敬的家长，您好，您所报读的xx课，原本计划上课时间为xxx，已调整为xxx时间，请您留意。
				User user = userService.getById(courseSeriesJoin.getUserId());
				LibVip vip = vipService.getById(courseSeriesJoin.getVipId());
				String first = "尊敬的家长，您好，您孩子"+vip.getChildName()+"所报读的" + detail.getCourseUnit() + "原本计划上课时间为"+req.getOldTime()+"已调整为"+req.getNewTime()+"时间，请您留意。";
				Map<String, String> data = new HashMap<String, String>();
				data.put("first", first);
				data.put("keyword1", "临时调课");
				data.put("keyword2", req.getOldTime());
				data.put("keyword3", req.getNewTime());
				data.put("remark", "请您留意。");
				Miniprogram m = this.getMiniprogram(WxUtil.map.get("courseAppId"), "pages/index/index");
				SendTemplateShort sendTemplateShort = new SendTemplateShort(user.getAccount(), id, null, data, m);
				pushTemplateService.saveAndSendPushWxTemplate(sendTemplateShort);
			}
		}
	}

	@Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
	public List<ChangeLessonRes> changeLessonList(String libId, String courseSeriesId) {
		List<ChangeLessonRes> list = new ArrayList<ChangeLessonRes>();

		//查询一个学生
		CourseSeriesJoin join = joinService.findOneDataByAny(libId,courseSeriesId);
		//查询这个课程有多少学生
		int studentCount = joinService.findStudentCount(libId,courseSeriesId);
		CourseSeries series = this.getById(courseSeriesId);
		ChangeLessonRes res = new ChangeLessonRes();
		res.setCourseSeriesId(series.getId());
		res.setCourseName(series.getCourseName());
		res.setCourseCover(series.getCoverUrl());

		List<Map<String, Object>> qlist = courseQueryDao.getDateDetailList(libId,courseSeriesId,join.getVipId());
		List<ChangeLessonDetailRes> dlist = new ArrayList<ChangeLessonDetailRes>();
		for (Map<String, Object> map : qlist) {
			ChangeLessonDetailRes dres = new ChangeLessonDetailRes();
			dres.setCourseDetailId(map.get("id")==null?"":map.get("id").toString());
			dres.setOpenTime(map.get("begin_time")==null?"":map.get("begin_time").toString());
			dres.setStartTime(map.get("open_time")==null?"":map.get("open_time").toString());
			dres.setDetailName(map.get("course_unit")==null?"":map.get("course_unit").toString());
			dres.setStudentCount(studentCount);
			dres.setState(map.get("begin_time")==null || "".equals(map.get("begin_time"))?3:map.get("feedback_id")==null?1:2);
			dres.setFeedbackId(map.get("feedback_id")==null?"":map.get("feedback_id").toString());
			dlist.add(dres);
		}
		res.setList(dlist);
		list.add(res);
		return list;
	}

	private Miniprogram getMiniprogram (String appId, String path){
		Miniprogram miniprogram =new  Miniprogram();
		miniprogram.setAppid(appId);
		miniprogram.setPagepath(path);
		return miniprogram;
	}
}