package com.yizhi.application.dashboard;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.plugins.Page;
import com.yizhi.core.application.cache.RedisCache;
import com.yizhi.core.application.context.ContextHolder;
import com.yizhi.core.application.context.RequestContext;
import com.yizhi.course.application.feign.CourseClient;
import com.yizhi.course.application.feign.CourseDashboardClient;
import com.yizhi.course.application.feign.CourseStudyHourClient;
import com.yizhi.course.application.vo.ApiListCourseVo;
import com.yizhi.library.application.feign.StudentCaseClient;
import com.yizhi.library.application.vo.FavoriteVO;
import com.yizhi.point.application.feign.PointDetailsFeignClients;
import com.yizhi.statistics.application.dashboard.vo.DashboardAccountStudyCourseChatVo;
import com.yizhi.statistics.application.dashboard.vo.DashboardAccountStudyCourseVo;
import com.yizhi.statistics.application.entity.AccountDashboard;
import com.yizhi.statistics.application.feign.DashboardClient;
import com.yizhi.statistics.application.refactor.course.CourseDashboardParam;
import com.yizhi.util.application.domain.Response;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

@Api(tags = "快捷菜单--学习大数据接口")
@RestController
@RequestMapping("/student/dashboard")
public class DashboardController {
    @Autowired
    private DashboardClient dashboardClient;
    @Autowired
    private CourseDashboardClient courseDashboardClient;
    @Autowired
    private CourseClient courseClient;
    @Autowired
    private StudentCaseClient studentCaseClient;
    @Autowired
    private PointDetailsFeignClients pointDetailsFeignClients;
    @Autowired
    private RedisCache redisCache;
    @Autowired
    private CourseStudyHourClient courseStudyHourClient;


    private SimpleDateFormat format2 = new SimpleDateFormat("MM-dd");
    private SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
    private SimpleDateFormat format1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    private Logger logger = LoggerFactory.getLogger(DashboardController.class);

    //redis的折线数据前缀
    private String DASHBOARD_STUDY_HOUR_CHART = "dashboard.study.hour.chart";
    //redis的详细数据前缀
    private String DASHBOARD_ACCOUNT_DETAILS = "dashboard.account.details";
    //redis的实时数据前缀
    private String DASHBOARD_ACCOUNT_DATA = "dashboard.account.data";

    //redis十秒失效
    private Long expireTime_ten_minute = 10 * 60L;

    //redis 十秒失效
    private Long expireTime_five_minute = 60 * 5L;


    @ApiOperation(value = "课程学习折线数据", response = DashboardAccountStudyCourseChatVo.class)
    @GetMapping("/course/studyHour/chart")
    public Response studyHourChart() {
        List<DashboardAccountStudyCourseChatVo> records = new ArrayList<>();
        String key = DASHBOARD_STUDY_HOUR_CHART;
        String item = ContextHolder.get().getAccountId().toString();
        Object o = redisCache.hget(key, item);
        if (o != null) {
            records = JSON.parseArray(o.toString(), DashboardAccountStudyCourseChatVo.class);
        } else {
            Date now = new Date();
            Map<String, Integer> dataMap = new LinkedHashMap<>();
            com.yizhi.statistics.application.refactor.course.CourseDashboardParam param = new com.yizhi.statistics.application.refactor.course.CourseDashboardParam();
            //获取前七天的学习数据
            DateTime endDate = DateUtil.endOfDay(DateUtil.offsetDay(now, -1));
            DateTime startDate = DateUtil.beginOfDay(DateUtil.offsetDay(now, -7));
            param.setStartDate(startDate);
            param.setEndDate(endDate);
            List<AccountDashboard> dashboards = dashboardClient.getRecords(param);
            BigDecimal bigDecimal2 = new BigDecimal(60);
            if (!CollectionUtils.isEmpty(dashboards)) {
                for (AccountDashboard vo : dashboards) {
                    String studyDate = this.format2.format(vo.getStudyRecordTime());
                    Long courseStudyTime = vo.getCourseStudyTime();
                    BigDecimal bigDecimal = new BigDecimal((courseStudyTime == null) ? 0L : courseStudyTime);
                    int studyTimeMinute = bigDecimal.divide(bigDecimal2, BigDecimal.ROUND_UP).intValue();
                    if (!dataMap.containsKey(studyDate)) {
                        dataMap.put(studyDate, studyTimeMinute);
                    }
                }
            }
            //初始化
            buildVo(now, records, dataMap);
            //实时获取今天的学习时间
            Long todayStudyTime = courseDashboardClient.todayStudyTime(format1.format(DateUtil.beginOfDay(now)), format1.format(DateUtil.endOfDay(now)));
            DashboardAccountStudyCourseChatVo vo = new DashboardAccountStudyCourseChatVo();
            BigDecimal bigDecimal = new BigDecimal((todayStudyTime == null) ? 0L : todayStudyTime);
            int todayStudyTimeMinute = bigDecimal.divide(bigDecimal2, BigDecimal.ROUND_UP).intValue();
            vo.setTotalStudyHour(Integer.valueOf(todayStudyTimeMinute));
            vo.setValue("今天");
            vo.setStudyTime(now);
            records.add(vo);
            if (!CollectionUtils.isEmpty(records)) {
                redisCache.hset(key, item, JSON.toJSONString(records), expireTime_ten_minute);
            }
        }

        return Response.ok(records);
    }

    /**
     * 构建折线vo
     *
     * @param now
     * @param records
     */
    public void buildVo(Date now, List<DashboardAccountStudyCourseChatVo> records, Map<String, Integer> dataMap) {
        //初始化
        for (Integer i = -7; i < 0; i++) {
            DateTime dateTime = DateUtil.offsetDay(now, i);
            String value = this.format2.format(dateTime);
            DashboardAccountStudyCourseChatVo vo = new DashboardAccountStudyCourseChatVo();
            vo.setTotalStudyHour(0);
            vo.setValue(value);
            if (dataMap != null) {
                Integer studyMinute = dataMap.get(value);
                vo.setTotalStudyHour(studyMinute == null ? 0 : studyMinute);
            }
            vo.setStudyTime(dateTime);
            records.add(vo);
        }
    }

    /**
     * 课程的前七天数据（完成课程数、完成课程时长、累计学习时间）支持时间筛选
     *
     * @param startDate
     * @param endDate
     * @return
     * @throws ParseException
     */
    @ApiOperation(value = "课程的前七天数据（完成课程数、完成课程时长、累计学习时间）", response = DashboardAccountStudyCourseVo.class)
    @GetMapping("/course/account/details")
    public Response courseAccountDetails(@ApiParam("yyyy-MM-dd HH:mm:ss") @RequestParam(value = "startDate") String startDate,
                                         @ApiParam("yyyy-MM-dd HH:mm:ss") @RequestParam("endDate") String endDate) throws ParseException {
        //获取前七天的学习数据
        Date startDate1 = format.parse(startDate);
        Date endDate1 = format.parse(endDate);
        DashboardAccountStudyCourseVo record = new DashboardAccountStudyCourseVo();

//        String key = DASHBOARD_ACCOUNT_DETAILS;
//        String item = ContextHolder.get().getAccountId().toString();
//        Object o = redisCache.hget(key, item);
//        if (o != null) {
//            record = JSONObject.parseObject(o.toString(), DashboardAccountStudyCourseVo.class);
//        } else {
        //获取前七天的学习数据
        startDate1 = DateUtil.beginOfDay(startDate1);
        endDate1 = DateUtil.endOfDay(endDate1);
        com.yizhi.statistics.application.refactor.course.CourseDashboardParam param = new CourseDashboardParam();
        param.setStartDate(startDate1);
        param.setEndDate(endDate1);
        List<AccountDashboard> dashboards = dashboardClient.getRecords(param);
        //完成课程数
        Integer totalFinishCourse = 0;
        //累计学习时长
        Float totalStudyTime = 0.0F;
        //完成课程时长（为课程内素材总时长)
        Float totalCourseTime = 0.0F;
    	// 考试累计时长(秒)
        Integer examDurationSecond = 0;
        if (!CollectionUtils.isEmpty(dashboards)) {
            for (AccountDashboard vo : dashboards) {
                totalFinishCourse += vo.getCourseFinishNum();
                totalStudyTime += vo.getCourseStudyTime();
                totalCourseTime += vo.getCourseTime();
                examDurationSecond += vo.getExamDurationSecond();
            }
        }

        BigDecimal bigDecimal1 = new BigDecimal(60);
        BigDecimal bigDecimal2 = new BigDecimal((totalStudyTime == null) ? 0L : totalStudyTime);
        BigDecimal bigDecimal3 = new BigDecimal((totalCourseTime == null) ? 0L : totalCourseTime);
        float studyTimeMinute = bigDecimal2.divide(bigDecimal1, BigDecimal.ROUND_UP).floatValue();
        float courseTimeMinute = bigDecimal3.divide(bigDecimal1, BigDecimal.ROUND_UP).floatValue();
        record.setTotalCourseTime(Float.valueOf(courseTimeMinute));
        record.setTotalStudyTime(Float.valueOf(studyTimeMinute));
        record.setTotalFinishCourse(totalFinishCourse);
        record.setExamDurationHour(second2hour(examDurationSecond));
//            if (record !=null) {
//                redisCache.hset(key, item, JSON.toJSONString(record), expireTime_ten_minute);
//            }
//        }


        return Response.ok(record);
    }
    
    private BigDecimal second2hour(Integer seconds) {
    	// 保留一位小数
    	return new BigDecimal(seconds).divide(new BigDecimal(3600), 1, RoundingMode.HALF_UP);
    }

    /**
     * 实时数据（我的收藏、浏览课程数、我的积分）
     *
     * @return
     * @throws ParseException
     */
    @ApiOperation(value = "实时数据", response = Map.class)
    @GetMapping("/account/data")
    public Response<Map> accountData() {
        //favoriteNum-我的收藏   viewRecordNum-浏览课程数  pointNum-我的积分 studyCourseDuration-我的学时
        Map<String, String> map = new HashMap<>();
        RequestContext context = ContextHolder.get();

        String key = DASHBOARD_ACCOUNT_DATA;
        String item = context.getAccountId().toString();
        Object o = redisCache.hget(key, item);
        if (o != null) {
            map = JSONObject.parseObject(o.toString(), Map.class);
        } else {
            map.put("viewRecordNum", "0");
            map.put("favoriteNum", "0");
            map.put("pointNum", "0");
            map.put("studyCourseDuration", "0");
//            try {
//            Integer viewRecordsCount = courseDashboardClient.getViewRecordsCount();
//            viewRecordsCount = viewRecordsCount == null ? 0 : viewRecordsCount;
//            map.put("viewRecordNum", viewRecordsCount);
//        } catch (Exception e) {
//            e.printStackTrace();
//            logger.info("查询浏览课程数异常");
//        }
            try {
                Page<FavoriteVO> caseFavorites = studentCaseClient.getFavorites(1, Integer.MAX_VALUE, null);
                Page<ApiListCourseVo> courseFavorite = courseClient.getPCMyFavoriteList(context.getAccountId(), null, context.getCompanyId(), context.getSiteId(), 1, Integer.MAX_VALUE);
                map.put("favoriteNum", caseFavorites.getTotal() + courseFavorite.getTotal() + "");
            } catch (Exception e) {
                e.printStackTrace();
                logger.info("查询收藏数异常");
            }
            // 我的积分统计
            try {
                Integer pointDetails = pointDetailsFeignClients.queryPiont(context.getAccountId(), context.getCompanyId(), context.getSiteId(), null);
                if (Objects.nonNull(pointDetails)) {
                    map.put("pointNum", pointDetails + "");
                }
            } catch (Exception e) {
                e.printStackTrace();
                logger.info("查询我的积分数异常");
            }
            // 我的学习总课时
            try {
                Float studyCourseDuration = courseStudyHourClient.hourStatistics(context.getSiteId()
                        , context.getAccountId(), null);
                map.put("studyCourseDuration", studyCourseDuration + "");
            } catch (Exception e) {
                e.printStackTrace();
                logger.info("查询我的学时数异常");
            }
            if (map != null) {
                redisCache.hset(key, item, JSON.toJSONString(map), expireTime_five_minute);
            }
        }
        return Response.ok(map);
    }


    @GetMapping("/asynchronous/dashboard")
    public void AsynchronousDashboard(@RequestParam("yesterday") String yesterday) {
        dashboardClient.AsynchronousDashboard(yesterday);
    }


    @GetMapping("/diy/asynchronous/dashboard")
    public void diyAsynchronousDashboard(@ApiParam("yyyy-MM-dd HH:mm:ss") @RequestParam("startDateString") String startDateString,
                                         @ApiParam("yyyy-MM-dd HH:mm:ss") @RequestParam("endDateString") String endDateString) {
        dashboardClient.diyAsynchronousDashboard(startDateString, endDateString);
    }

}
