package com.app.service.basics;

import com.app.dto.PageResult;
import com.app.dto.basics.operation.OpenCourseDto;
import com.app.dto.basics.operation.TimetablesDto;
import com.app.dto.basics.search.SearchOpenCourseDto;
import com.app.entity.basics.OpenCourse;
import com.app.mapper.basics.OpenCourseMapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import javax.validation.constraints.NotEmpty;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 功能描述：课程
 *
 * @Auther: 梁展鹏
 * @Date: 2018/7/24 11:38
 */
@Slf4j
@Service
public class OpenCourseService {

    @Resource
    private OpenCourseMapper mapper;

    @Autowired
    private SchoolService schoolService;

    /**
     * 功能描述：查询[开课]详情
     *
     * @param id 标识
     * @return
     */
    public Optional<OpenCourse> findById(String id) {
        return Optional.ofNullable(mapper.selectById(id));
    }

    /**
     * 功能描述：根据[开课]标识查询
     *
     * @param idList
     * @return
     */
    public List<OpenCourse> findAllById(List<String> idList) {
        return mapper.selectBatchIds(idList);
    }

    /**
     * 功能描述：查询[学年],[学期],[学校]的开课
     *
     * @param schoolYear 学年
     * @param semester   学期
     * @param schoolId   学校标识
     * @return
     */
    public List<OpenCourse> findBySchoolId(Integer schoolYear, Integer semester, String schoolId) {
        LambdaQueryWrapper<OpenCourse> wrapper = new QueryWrapper<OpenCourse>().lambda();
        if (!StringUtils.isEmpty(schoolYear)) { // 学年
            wrapper.eq(OpenCourse::getSchoolYear, schoolYear);
        }
        if (!StringUtils.isEmpty(semester)) { // 学期
            wrapper.eq(OpenCourse::getSemester, semester);
        }
        if (!StringUtils.isEmpty(schoolId)) { // 学校标识
            wrapper.eq(OpenCourse::getSchoolId, schoolId);
        }
        wrapper.eq(OpenCourse::getIsDel, Boolean.FALSE);
        wrapper.orderByDesc(OpenCourse::getSchoolYear, OpenCourse::getSemester, OpenCourse::getSchoolId, OpenCourse::getCourseId);

        return mapper.selectList(wrapper);
    }

    /**
     * 功能描述：查询[家长]账号所挂载学校、年级开设的本学期430课程列表
     *
     * @param schoolYear 学年
     * @param semester   学期
     * @param schoolId   学校标识
     * @param name       课程名称
     * @param gradeName  年级名称
     * @param type       课程类型
     * @param page
     * @param size
     * @return
     */
    public PageResult<OpenCourse> page(List<String> organIds, Integer schoolYear, Integer semester, String schoolId,
                                       String name, Integer gradeName, String type, Boolean isDel,
                                       Integer page, Integer size) {
        LambdaQueryWrapper<OpenCourse> wrapper = new QueryWrapper<OpenCourse>().lambda();
        if (!StringUtils.isEmpty(schoolYear)) { // 学年
            wrapper.eq(OpenCourse::getSchoolYear, schoolYear);
        }
        if (!StringUtils.isEmpty(semester)) { // 学期
            wrapper.eq(OpenCourse::getSemester, semester);
        }
        if (!StringUtils.isEmpty(schoolId)) { // 学校标识
            wrapper.eq(OpenCourse::getSchoolId, schoolId);
        }
        if (!StringUtils.isEmpty(name)) { // 课程名称
            wrapper.like(OpenCourse::getName, name);
        }
        if (!StringUtils.isEmpty(gradeName)) { // 年级名称
            wrapper.like(OpenCourse::getGradeName, gradeName);
        }
        if (!StringUtils.isEmpty(type)) { // 课程类型
            wrapper.eq(OpenCourse::getType, type);
        }
        if (Optional.ofNullable(isDel).isPresent()) {
            wrapper.eq(OpenCourse::getIsDel, isDel);
        }
        if(organIds!=null && !organIds.isEmpty()){
            wrapper.and(w ->{
                for (String organId : organIds) {
                    if(!StringUtils.isEmpty(organId)){
                        w.eq(OpenCourse::getCourseId,organId).or();
                    }
                }
            });
        }

        wrapper.orderByDesc(OpenCourse::getSchoolYear, OpenCourse::getSemester, OpenCourse::getSchoolId, OpenCourse::getCourseId);
        IPage<OpenCourse> iPage = mapper.selectPage(new Page<>(page, size), wrapper);

        return new PageResult(page, size, iPage.getTotal(), iPage.getRecords());
    }

    /**
     * 功能描述：查询[账号]底下的所有[选课单]
     *
     * @param accountId
     * @param accountChildId
     * @return
     */
    public List<OpenCourse> myShoppingCar(String accountId, String accountChildId) {
        return mapper.myShoppingCar(accountId, accountChildId);
    }

    /**
     * 功能描述：保存/更新[开课]
     *
     * @param openCourseDto
     */
    public OpenCourse saveOrUpdate(OpenCourseDto openCourseDto) {
        OpenCourse _openCourse;
        if (StringUtils.isEmpty(openCourseDto.getId())) {
            _openCourse = new OpenCourse();
            _openCourse
                    .setCourseId(openCourseDto.getCourseId())
                    .setName(openCourseDto.getName())
                    .setPrice(openCourseDto.getPrice())
                    .setThumbnail(openCourseDto.getThumbnail())
                    .setBanner(openCourseDto.getBanner())
                    .setIntroduceUrl(openCourseDto.getIntroduceUrl())
                    .setSchoolYear(openCourseDto.getSchoolYear())
                    .setSemester(openCourseDto.getSemester())
                    .setSchoolId(openCourseDto.getSchoolId())
                    .setSchoolName(schoolService.getName(_openCourse.getSchoolId())) // 翻译[学校名称]字段
                    .setGradeName(openCourseDto.getGradeName())
                    .setType(openCourseDto.getType())
                    .setOpenCourseNumber(openCourseDto.getOpenCourseNumber())
                    .setFreeCourseNumber(openCourseDto.getFreeCourseNumber())
                    .setCycle(openCourseDto.getCycle())
                    .setHours(openCourseDto.getHours())
                    .setWxGroupQRUrl(openCourseDto.getWxGroupQRUrl())
                    .setSignUpStartTime(openCourseDto.getSignUpStartTime())
                    .setSignUpEndTime(openCourseDto.getSignUpEndTime())
                    .setRemarks(openCourseDto.getRemarks())
                    .setOrganId(openCourseDto.getOrganId());
            mapper.insert(_openCourse);
        } else {
            Optional<OpenCourse> optional = findById(openCourseDto.getId());
            _openCourse = optional.get();
            _openCourse
                    .setCourseId(openCourseDto.getCourseId())
                    .setName(openCourseDto.getName())
                    .setPrice(openCourseDto.getPrice())
                    .setThumbnail(openCourseDto.getThumbnail())
                    .setBanner(openCourseDto.getBanner())
                    .setIntroduceUrl(openCourseDto.getIntroduceUrl())
                    .setSchoolYear(openCourseDto.getSchoolYear())
                    .setSemester(openCourseDto.getSemester())
                    .setSchoolId(openCourseDto.getSchoolId())
                    .setSchoolName(schoolService.getName(_openCourse.getSchoolId())) // 翻译[学校名称]字段
                    .setGradeName(openCourseDto.getGradeName())
                    .setType(openCourseDto.getType())
                    .setOpenCourseNumber(openCourseDto.getOpenCourseNumber())
                    .setFreeCourseNumber(openCourseDto.getFreeCourseNumber())
                    .setCycle(openCourseDto.getCycle())
                    .setHours(openCourseDto.getHours())
                    .setWxGroupQRUrl(openCourseDto.getWxGroupQRUrl())
                    .setSignUpStartTime(openCourseDto.getSignUpStartTime())
                    .setSignUpEndTime(openCourseDto.getSignUpEndTime())
                    .setRemarks(openCourseDto.getRemarks())
                    .setOrganId(openCourseDto.getOrganId());
            mapper.updateById(_openCourse);
        }

        return _openCourse;
    }

    /**
     * 功能描述：替换[开课]删除状态
     *
     * @param id
     */
    public void handleIsDel(String id) {
        Optional<OpenCourse> optional = findById(id);
        if (optional.isPresent()) {
            OpenCourse openCourse = optional.get();
            openCourse.setIsDel(!openCourse.getIsDel());
            mapper.updateById(openCourse);
        }
    }

    public Object[] findTimetable(SearchOpenCourseDto params) {
        LambdaQueryWrapper<OpenCourse> wrapper = new QueryWrapper<OpenCourse>().lambda();
        if (!StringUtils.isEmpty(params.getSchoolYear())) { // 学年
            wrapper.eq(OpenCourse::getSchoolYear, params.getSchoolYear());
        }
        if (!StringUtils.isEmpty(params.getSemester())) { // 学期
            wrapper.eq(OpenCourse::getSemester, params.getSemester());
        }
        if (!StringUtils.isEmpty(params.getSchoolId())) { // 学校标识
            wrapper.eq(OpenCourse::getSchoolId, params.getSchoolId());
        }
        if (!StringUtils.isEmpty(params.getName())) { // 课程名称
            wrapper.like(OpenCourse::getName, params.getName());
        }
        if (!StringUtils.isEmpty(params.getType())) { // 课程类型
            wrapper.eq(OpenCourse::getType, params.getType());
        }
        if (Optional.ofNullable(params.getIsDel()).isPresent()) {
            wrapper.eq(OpenCourse::getIsDel, params.getIsDel());
        }
        wrapper.orderByDesc(OpenCourse::getSchoolYear, OpenCourse::getSemester, OpenCourse::getSchoolId, OpenCourse::getCourseId);
        List<OpenCourse> openCoursePage = mapper.selectList(wrapper);

        List<TimetablesDto> list = new ArrayList<>();
        for (OpenCourse course : openCoursePage) {
            @NotEmpty String cycle = course.getCycle();
            int mark = 0;
            switch (cycle) {
                case "星期日":
                    mark = 0;
                    break;
                case "星期一":
                    mark = 1;
                    break;
                case "星期二":
                    mark = 2;
                    break;
                case "星期三":
                    mark = 3;
                    break;
                case "星期四":
                    mark = 4;
                    break;
                case "星期五":
                    mark = 5;
                    break;
                case "星期六":
                    mark = 6;
                    break;
            }
            SimpleDateFormat formatter;
            String format = "";
            Calendar calendar = Calendar.getInstance();
            int month = calendar.get(Calendar.MONTH) + 1;
            int year = calendar.get(Calendar.YEAR);
            String _year = String.valueOf(year);
            List<Integer> up = new ArrayList<>();
            Date parse = new Date();
            up.add(7);
            up.add(8);
            up.add(9);
            up.add(10);
            up.add(11);
            up.add(12);
            up.add(1);
            DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
            if (up.indexOf(month) == -1) {

                try {
                    parse = dateFormat.parse(_year + "-02-01");
                } catch (ParseException e) {
                    e.printStackTrace();
                }
            } else {
                try {
                    parse = dateFormat.parse(_year + "-09-01");
                } catch (ParseException e) {
                    e.printStackTrace();
                }
            }
            for (int i = 0; i < 150; i++) {
                Calendar instance = Calendar.getInstance();
                instance.setTime(parse);
                instance.add(Calendar.DATE, i);
                int i1 = instance.get(Calendar.DAY_OF_WEEK) - 1;
                Date _date;
                if (mark == i1) {
                    _date = instance.getTime();
                    formatter = new SimpleDateFormat("yyyy-MM-dd");
                    format = formatter.format(_date);
                    TimetablesDto timetablesDto = new TimetablesDto();
                    String substring = course.getHours().substring(0, 5);
                    timetablesDto.setTitle(substring + course.getName());
                    timetablesDto.setStart(format);
                    list.add(timetablesDto);
                }
            }
        }

        return list.toArray();
    }

}
