package com.ym.mec.student.controller;

import com.ym.mec.auth.api.entity.SysUser;
import com.ym.mec.biz.dal.dao.*;
import com.ym.mec.biz.dal.dto.PracticeGroupBuyDto;
import com.ym.mec.biz.dal.dto.PracticeGroupBuyParamsDto;
import com.ym.mec.biz.dal.entity.ClassGroup;
import com.ym.mec.biz.dal.entity.CourseScheduleEvaluate;
import com.ym.mec.biz.dal.entity.PracticeGroup;
import com.ym.mec.biz.dal.entity.Student;
import com.ym.mec.biz.dal.enums.GroupStatusEnum;
import com.ym.mec.biz.dal.enums.GroupType;
import com.ym.mec.biz.dal.enums.MessageTypeEnum;
import com.ym.mec.biz.dal.enums.PracticeGroupType;
import com.ym.mec.biz.service.PracticeGroupService;
import com.ym.mec.biz.service.SysMessageService;
import com.ym.mec.biz.service.SysUserService;
import com.ym.mec.common.controller.BaseController;
import com.ym.mec.common.entity.HttpResponseResult;
import com.ym.mec.common.exception.BizException;
import com.ym.mec.thirdparty.message.MessageSenderPluginContext;
import com.ym.mec.util.date.DateUtil;
import com.ym.mec.util.http.HttpUtil;
import com.yonge.log.model.AuditLogAnnotation;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * @Author Joburgess
 * @Date 2020/1/31
 */
@RequestMapping("practiceGroup")
@Api(tags = "陪练课服务")
@RestController
public class PracticeGroupController extends BaseController {

    @Autowired
    private PracticeGroupService practiceGroupService;
    @Autowired
    private SysUserService sysUserService;
    List<Integer> excludeOrganIds=new ArrayList<>(Arrays.asList(new Integer[]{36}));
    @Autowired
    private SysMessageService sysMessageService;
    @Autowired
    private PracticeGroupDao practiceGroupDao;
    @Autowired
    private ClassGroupDao classGroupDao;
    @Autowired
    private SysConfigDao sysConfigDao;
    @Autowired
    private CourseScheduleEvaluateDao courseScheduleEvaluateDao;
    @Autowired
    private StudentDao studentDao;

    @ApiOperation("获取学生的陪练课")
    @GetMapping(value = "/findUserPracticeCourses")
    public Object findUserPracticeCourses(){
        return succeed(practiceGroupService.findUserPracticeCourses(sysUserService.getUserId()));
    }

    @ApiOperation("检测用户是否能够申请免费陪练课")
    @GetMapping(value = "/checkCanApplyFreePracticeGroup")
    private HttpResponseResult checkCanApplyFreePracticeGroup(){
        SysUser sysUser = sysUserService.getUser();
        Map<String,Object> result=practiceGroupService.checkCanApplyFreePracticeGroup(sysUser.getId());
        Integer applyTimes = practiceGroupDao.countUserPracticeApplyRecord(sysUser.getId());
        result.put("canApply", applyTimes < 1 ? 1 : 0);
        result.put("organId", sysUser.getOrganId());
        return succeed(result);
    }

    @ApiOperation("获取陪练课预约参数")
    @GetMapping(value = "/getPracticeApplyParams")
    public Object getPracticeApplyParams(){
        SysUser sysUser = sysUserService.getUser();
        if (sysUser.getTenantId() == null) {
            return failed( "用户机构信息异常");
        }
        Map<String,Object> result=practiceGroupService.getPracticeApplyParams(sysUser.getId(),sysUser.getTenantId());
        Integer applyTimes = practiceGroupDao.countUserPracticeApplyRecord(sysUser.getId());
        result.put("enableApply", applyTimes < 1 ? 1 : 0);
        return succeed(result);
    }

    @ApiOperation("获取可以预约的教师")
    @GetMapping(value = "/getEnableApplyTeachers")
    public Object getEnableApplyTeachers(Integer subjectId){
        return succeed(practiceGroupService.getEnableApplyTeachers(sysUserService.getUserId(), subjectId));
    }

    @ApiOperation("获取可以预约的教师--付费")
    @GetMapping(value = "/getEnableApplyTeachersWithPay")
    public Object getEnableApplyTeachersWithPay(Integer subjectId){
        return succeed(practiceGroupService.getEnableApplyTeachersWithPay(sysUserService.getUserId(), subjectId));
    }

    @ApiOperation("获取指定学员所在分部下的教师空闲时间")
    @GetMapping(value = "/getTeacherFreeTimes")
    public Object getTeacherFreeTimes(Integer teacherId, Date firstClassTime){
        return succeed(practiceGroupService.getTeacherFreeTimes(sysUserService.getUserId(),teacherId,firstClassTime));
    }

    @ApiOperation("获取指定学员所在分部下的教师空闲时间")
    @GetMapping(value = "/getTeachersFreeTimes")
    public Object getTeachersFreeTimes(Integer subjectId, Date firstClassTime){
        return succeed(practiceGroupService.getTeachersFreeTimes(sysUserService.getUserId(),subjectId,firstClassTime));
    }

    @ApiOperation("陪练课预约")
    @PostMapping(value = "/practiceApply")
    @AuditLogAnnotation(operateName = "陪练课预约")
    public Object practiceApply(PracticeGroup practiceGroup){
        SysUser sysUser = sysUserService.getUser();
        if(excludeOrganIds.contains(sysUser.getOrganId())){
            throw new BizException("请联系老师确认您的所属分部");
        }
        if(sysUser.getTenantId() == null){
            throw new BizException("请联系老师确认您的所属机构");
        }
        practiceGroup.setStudentId(sysUser.getId());
        practiceGroup.setTenantId(sysUser.getTenantId());
        return succeed(practiceGroupService.practiceApply(practiceGroup));
    }

    @ApiOperation("获取陪练课预约参数——付费")
    @GetMapping(value = "/getPayPracticeApplyParams")
    public Object getPayPracticeApplyParams(Integer organId){
        SysUser sysUser = sysUserService.getUser();
        if(sysUser.getTenantId() == null){
            throw new BizException("请联系老师确认您的所属机构");
        }
        return succeed(practiceGroupService.getPayPracticeApplyParams(sysUser.getId(), Objects.nonNull(organId)?organId:sysUser.getOrganId(),sysUser.getTenantId()));
    }

    @ApiOperation("获取指定教师的空闲时间——付费")
    @GetMapping(value = "/getPayPracticeTeacherFreeTimes")
    public Object getPayPracticeTeacherFreeTimes(Integer teacherId,Integer buyMonths, boolean renew, Long groupId, PracticeGroupType type){
        SysUser sysUser = sysUserService.getUser();
        Map payPracticeTeacherFreeTimes = practiceGroupService.getPayPracticeTeacherFreeTimes(sysUser.getId(),teacherId, buyMonths,renew,groupId);
        if(Objects.nonNull(type)&&PracticeGroupType.COME_ON_PACKAGE.equals(type)){
            Map<Integer, List<String>> weekNumApplyTimesMap = (Map<Integer, List<String>>) payPracticeTeacherFreeTimes.get("teacherFreeDays");
            for (Map.Entry<Integer, List<String>> weekNumApplyTimesMapEntry : weekNumApplyTimesMap.entrySet()) {
                DateTimeFormatter dtf = DateTimeFormatter.ofPattern("HH:mm:ss");
                Iterator<String> iterator = weekNumApplyTimesMapEntry.getValue().iterator();
                while (iterator.hasNext()){
                    String timeStr = iterator.next();
                    if("23:30:00".equals(timeStr)){
                        iterator.remove();
                        continue;
                    }
                    LocalTime time = LocalTime.parse(timeStr, dtf);
                    LocalTime nextTime = time.plusMinutes(30);
                    if(weekNumApplyTimesMapEntry.getValue().contains(nextTime.format(DateUtil.timeFormatter))){
                        continue;
                    }
                    iterator.remove();
                }
            }
            Iterator<Map.Entry<Integer, List<String>>> iterator = weekNumApplyTimesMap.entrySet().iterator();
            while (iterator.hasNext()) {
                Map.Entry<Integer, List<String>> next = iterator.next();
                if (CollectionUtils.isEmpty(next.getValue())) {
                    iterator.remove();
                }
            }
        }
        return succeed(payPracticeTeacherFreeTimes);
    }

    @ApiOperation("获取学生上一次的购买信息--付费")
    @GetMapping(value = "/findUserLatestPracticeGroup")
    public HttpResponseResult findUserLatestPracticeGroup(Long groupId){
        return succeed(practiceGroupService.findUserLatestPracticeGroup(sysUserService.getUserId(),groupId));
    }

    @ApiOperation("检测学生是否是新用户")
    @GetMapping(value = "/isNewStudent")
    public HttpResponseResult isNewStudent(){
        SysUser sysUser = sysUserService.getUser();
        int studentExitChargePractices = practiceGroupDao.checkStudentExitChargePractice(sysUser.getId(),"2021-03-09 00:00:00");
        Student student = studentDao.get(sysUser.getId());
        if(student == null){
            throw new BizException("学员信息不存在");
        }
        Map<String, Integer> result=new HashMap<>();
        result.put("organId", sysUser.getOrganId());
        result.put("isNewStudent", studentExitChargePractices<=0?0:1);

        List<PracticeGroup> userStatusPracticeGroups = practiceGroupDao.findUserStatusPracticeGroups(sysUser.getId(), null, PracticeGroupType.COME_ON_PACKAGE);
        long normalGroupNum = userStatusPracticeGroups.stream().filter(p -> GroupStatusEnum.NORMAL.equals(p.getGroupStatus())).count();
        int comeOnPackage = student.getComeOnPackage()==null?0:student.getComeOnPackage();
        result.put("comeOnPackage", 1==comeOnPackage&&normalGroupNum<=0?1:0);
        return succeed(result);
    }

    @ApiOperation("陪练课购买")
    @PostMapping(value = "/buyPracticeGroup")
    @AuditLogAnnotation(operateName = "陪练课购买")
    public HttpResponseResult buyPracticeGroup(@RequestBody PracticeGroupBuyDto practiceGroupBuyParams){
        SysUser sysUser = sysUserService.getUser();
        if(excludeOrganIds.contains(sysUser.getOrganId())){
            throw new BizException("请联系老师确认您的所属分部");
        }
        practiceGroupBuyParams.setStudentId(sysUser.getId());
        if(Objects.isNull(practiceGroupBuyParams.getType())||PracticeGroupType.CHARGE.equals(practiceGroupBuyParams.getType())){
            return practiceGroupService.buyPracticeGroup(practiceGroupBuyParams, null);
        }else{
            return practiceGroupService.createPackagePracticeGroup(practiceGroupBuyParams, null);
        }
    }

    @ApiOperation("学生主动排课(目前只适用于小小训练营活动)")
    @PostMapping(value = "/createActivityPracticeGroup")
    @AuditLogAnnotation(operateName = "学生主动排课(目前只适用于小小训练营活动)")
    public HttpResponseResult createActivityPracticeGroup(@RequestBody PracticeGroupBuyDto practiceGroupBuyParams){
        return practiceGroupService.studentCreateActivityPracticeGroup(practiceGroupBuyParams);
    }

    @ApiOperation(value = "获取网管课购买信息")
    @PostMapping("/getPracticeGroupPayInfo")
    public Object getPracticeGroupPayInfo(Long vipGroupId){
        return succeed(practiceGroupService.getPracticeGroupPayInfo(vipGroupId,sysUserService.getUserId()));
    }

    @ApiOperation("营销活动购买")
    @PostMapping(value = "/buyActivity")
    @AuditLogAnnotation(operateName = "营销活动购买")
    public HttpResponseResult buyActivity(@RequestBody PracticeGroupBuyParamsDto practiceGroupBuyParams) throws Exception {
//        if(CollectionUtils.isNotEmpty(practiceGroupBuyParams.getCouponIdList())){
//            throw new BizException("当前活动不支持优惠券");
//        }
        SysUser sysUser = sysUserService.getUser();
        practiceGroupBuyParams.setUserId(sysUser.getId());
        practiceGroupBuyParams.setOrganId(sysUser.getOrganId());
        return succeed(practiceGroupService.buyActivityPracticeGroup(practiceGroupBuyParams));
    }

    @ApiOperation("是否可以购买活动")
    @GetMapping(value = "/checkActivity")
    public HttpResponseResult checkActivity(){
        practiceGroupService.checkActivity();
        return succeed();
    }

    @ApiOperation(value = "购买指导老师创建的网管课")
    @PostMapping("/buyTeacherPracticeGroup")
    @AuditLogAnnotation(operateName = "购买指导老师创建的网管课")
    public Object buyTeacherPracticeGroup(@RequestBody PracticeGroupBuyParamsDto practiceGroupBuyParams) throws Exception {
        return practiceGroupService.buyTeacherPracticeGroup(practiceGroupBuyParams);
    }

    @ApiOperation("获取用户历史购买的陪练课")
    @GetMapping(value = "/findUserHistoryBuyPracticeGroups")
    public HttpResponseResult findUserHistoryBuyPracticeGroups(Long groupId, PracticeGroupType type){
        return succeed(practiceGroupService.findUserHistoryBuyPracticeGroups(sysUserService.getUserId(), groupId, type));
    }

    @ApiOperation("查询订单信息")
    @GetMapping(value = "/queryOrderInfo")
    public HttpResponseResult queryOrderInfo(String orderNo){
        return succeed(practiceGroupService.queryOrderInfo(orderNo));
    }

    @ApiOperation("重新支付")
    @PostMapping(value = "/repay")
    @AuditLogAnnotation(operateName = "重新支付")
    public HttpResponseResult repay(Integer groupId, boolean useBalancePayment) throws Exception {
        return practiceGroupService.repay(sysUserService.getUserId(),groupId,useBalancePayment);
    }

    @ApiOperation("免费陪练课定点推送")
    @GetMapping(value = "/freePush")
    public HttpResponseResult freePush(Integer userId, String pushType){
        sysUserService.getUser();
        String baseApiUrl = sysConfigDao.findConfigValue("base_api_url");

        String pushUrl = baseApiUrl + "/#/auditionbanner/id";

//        String smsUrl = baseApiUrl + "/#/transfer?url=" + baseApiUrl + "/#/auditionbanner/id";
//
//        SysUser student = sysUserFeignService.queryUserById(userId);

        if(pushType.equals("ALL")||pushType.equals("JIGUANG")){
            Map<Integer, String> userMap = new HashMap<>();
            userMap.put(userId, userId.toString());
            sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.JIGUANG, MessageTypeEnum.STUDENT_SMS_PUSH_FREE_PRACTICE_APPLY_PUSH,
                    userMap, null, 0, "5?" + pushUrl, "STUDENT");
        }

//        if(pushType.equals("ALL")||pushType.equals("SMS")){
//            Map<Integer, String> userPhoneMap = new HashMap<>();
//            userPhoneMap.put(userId, student.getPhone());
//            sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.YIMEI, MessageTypeEnum.FREE_PRACTICE_APPLY_PUSH,
//                    userPhoneMap, null, 0, null, "STUDENT", HttpUtil.getSortUrl(smsUrl));
//        }

        return succeed();
    }

    @ApiOperation("陪练课完成报告推送")
    @GetMapping(value = "/reportPush")
    public HttpResponseResult reportPush(Integer userId, String pushType){
        sysUserService.getUser();
        String baseApiUrl = sysConfigDao.findConfigValue("base_api_url");
        PracticeGroup userFreePracticeGroup = practiceGroupDao.getUserFreePracticeGroup(userId);
        ClassGroup classGroup = classGroupDao.findByMusicGroupAndType(userFreePracticeGroup.getId().toString(), GroupType.PRACTICE.getCode());

        CourseScheduleEvaluate courseScheduleEvaluate = courseScheduleEvaluateDao.findByClassGroupId(classGroup.getId());
        if(Objects.isNull(courseScheduleEvaluate)){
            return failed("未生成课程报告");
        }

        String pushUrl = baseApiUrl + "/#/reportDetail?classGroupId=" + classGroup.getId();

        String smsUrl = baseApiUrl + "/#/transfer?url=" + baseApiUrl + "&hash=reportDetail&classGroupId=" + classGroup.getId();

        SysUser student = sysUserService.queryUserById(userId);

        if(pushType.equals("ALL")||pushType.equals("JIGUANG")){
            Map<Integer, String> userMap = new HashMap<>();
            userMap.put(userId, userId.toString());
            sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.JIGUANG, MessageTypeEnum.STUDENT_SMS_PUSH_PRACTICE_COMPLETED_STUDY_REPORT,
                    userMap, null, 0, "5?" + pushUrl, "STUDENT", pushUrl);
        }

        if(pushType.equals("ALL")||pushType.equals("SMS")){
            Map<Integer, String> userPhoneMap = new HashMap<>();
            userPhoneMap.put(userId, student.getPhone());
            sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.AWSMS, MessageTypeEnum.STUDENT_SMS_PUSH_PRACTICE_COMPLETED_STUDY_REPORT,
                    userPhoneMap, null, 0, null, "STUDENT", HttpUtil.getSortUrl(smsUrl));
        }

        return succeed();
    }

    @ApiOperation("陪练课完成报告推送")
    @GetMapping(value = "/pushStudyReport")
    public HttpResponseResult pushStudyReport(Date expiredDate, String pushType){
        sysUserService.getUser();
        practiceGroupService.pushStudyReport(expiredDate,pushType);
        return succeed();
    }

    @ApiOperation("检测用户是否存在待支付的课程组订单")
    @GetMapping(value = "/checkExistWaitPayOrder")
    public HttpResponseResult checkExistWaitPayOrder(Long groupId){
        return succeed(practiceGroupService.checkExistWaitPayOrder(sysUserService.getUserId(),groupId));
    }

    @ApiOperation("取消待支付的订单")
    @PostMapping(value = "/cancelWaitPayOrder")
    @AuditLogAnnotation(operateName = "取消待支付的订单")
    public HttpResponseResult cancelWaitPayOrder(Integer groupId) throws Exception{
        return practiceGroupService.cancelWaitPayOrder(sysUserService.getUserId(), groupId);
    }
}
