package com.reyun.controller;

import com.reyun.dic.LogEnumType;
import com.reyun.dic.OperateObjectEnumType;
import com.reyun.model.Account;
import com.reyun.model.VirtualEvent;
import com.reyun.repository.AppRepository;
import com.reyun.security.annotation.CurrentAccount;
import com.reyun.service.RetentionService;
import com.reyun.service.UserLogService;
import com.reyun.service.VirtualEventService;
import com.reyun.util.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Controller
@RequestMapping("/retention")
public class RetentionController {

    protected Logger logger = LoggerFactory.getLogger(RetentionController.class);

    @Autowired
    AppRepository appRepository;

    @Autowired
    RetentionService retentionService;

    @Autowired
    UserLogService userLogService;

    @Autowired
    VirtualEventService virtualEventService;

    @RequestMapping(value = "reportdetail/{app}", method = RequestMethod.GET)
    @ResponseBody
    public ResultModel reportDetail(HttpServletRequest request, @PathVariable Long app, @CurrentAccount Account loginAccount) {

        String start = request.getParameter("startdate");
        String end = request.getParameter("enddate");
        String reportView = request.getParameter("reportview");
        String userGroupStr = request.getParameter("usergroupid");
        String eventInfo = request.getParameter("eventinfo");
        String dimensionStr = request.getParameter("dimention");
        String isDeviceStr = request.getParameter("isdevice");
        String retentiontype = request.getParameter("retentiontype");

        if (!StringUtil.isEmpty(eventInfo)) {
            try {
                eventInfo = URLDecoder.decode(eventInfo, "UTF-8");
            } catch (UnsupportedEncodingException e) {

            }
        }

        String eventType = request.getParameter("eventType");
        boolean isProfile=false;
        if(!StringUtils.isEmpty(eventType) && "profile".equals(eventType)){
            isProfile=true;
        }

        boolean isDevice = !StringUtil.isEmpty(isDeviceStr) && "true".equals(isDeviceStr);
        boolean isList = request.getParameter("datatype") != null && "list".equals(request.getParameter("datatype"));

        if (StringUtil.isEmpty(reportView)) {
            reportView = "day";
        }

        //日期间隔
        int interval = this.getIntervalByReportView(start, end, reportView);
        //开始结束日期
        String startDate = this.getStartDateByReportView(start, reportView);
        String endDate = this.getEndDateByReportView(end, reportView);

        Map<String, List> result = retentionService.retentionDetailReport(loginAccount, startDate, endDate, isList, eventInfo, app,
                userGroupStr, dimensionStr, reportView, interval, isDevice, retentiontype,isProfile);

        userLogService.insertLog(loginAccount, LogEnumType.FIND.getCode(), LogEnumType.FIND.getName() + "留存明细报表",
                "{\"eventinfo\":\"" + eventInfo + "\"}", app, OperateObjectEnumType.REPORT.getCode());

        if (result.isEmpty()) {
            return ResultModel.ERROR(ResultStatus.NETWORK_ERROR);
        } else {
            return ResultModel.OK(result);
        }
    }

    @RequestMapping(value = "report/{app}", method = RequestMethod.GET)
    @ResponseBody
    public ResultModel report(HttpServletRequest request, @PathVariable Long app, @CurrentAccount Account loginAccount) {

        String start = request.getParameter("startdate");
        String end = request.getParameter("enddate");
        String isDeviceStr = request.getParameter("isdevice");
        boolean isDevice = !StringUtil.isEmpty(isDeviceStr) && "true".equals(isDeviceStr);
        String reportView = request.getParameter("reportview");
        String retentiontype = request.getParameter("retentiontype");

        if (StringUtil.isEmpty(reportView)) {
            reportView = "day";
        }

        //日期间隔
        int interval = this.getIntervalByReportView(start, end, reportView);
        //开始结束日期
        String startDate = this.getStartDateByReportView(start, reportView);
        String endDate = this.getEndDateByReportView(end, reportView);

        String eventInfo = request.getParameter("eventinfo");
        if (!StringUtil.isEmpty(eventInfo)) {
            try {
                eventInfo = URLDecoder.decode(eventInfo, "UTF-8");
            } catch (UnsupportedEncodingException e) {

            }
        }

        String userGroupStr = request.getParameter("usergroupid");
        String dimensionStr = request.getParameter("dimention");
        boolean isList = request.getParameter("datatype") != null && "list".equals(request.getParameter("datatype"));

        String eventType = request.getParameter("eventType");
        boolean isProfile=false;
        if(!StringUtils.isEmpty(eventType) && "profile".equals(eventType)){
            isProfile=true;
        }


        Map<String, List> result = retentionService.retentionReport(startDate, endDate, isList, eventInfo, app, userGroupStr,
                dimensionStr, reportView, interval, isDevice, loginAccount.getId(), retentiontype,isProfile);

        if (retentiontype.equals("define")) {
            userLogService.insertLog(loginAccount, LogEnumType.FIND.getCode(), LogEnumType.FIND.getName() + "留存报表",
                    "{\"eventinfo\":" + eventInfo + "}", app, OperateObjectEnumType.REPORT.getCode());
        } else {
            userLogService.insertLog(loginAccount, LogEnumType.FIND.getCode(), LogEnumType.FIND.getName() + "留存报表",
                    "{\"eventinfo\":\"" + eventInfo + "\"}", app, OperateObjectEnumType.REPORT.getCode());
        }


        if (result.isEmpty()) {
            return ResultModel.ERROR(ResultStatus.NETWORK_ERROR);
        } else {
            return ResultModel.OK(result);
        }
    }

    /**
     * 获取开始时间
     */
    private String getStartDateByReportView(String startDate, String reportView) {

        String resultDate = startDate;

        switch (reportView) {
            case "day":
                resultDate = startDate;
                break;
            case "week":
                resultDate = DateUtil.getFirstDayStrOfWeek(DateUtil.parseDate(startDate));
                break;
            case "month":
                resultDate = DateUtil.getFirstDayOfMonth(DateUtil.parseDate(startDate));
                break;
        }

        return resultDate;
    }

    /**
     * 获取结束时间
     */
    private String getEndDateByReportView(String endDate, String reportView) {

        String resultDate = endDate;

        switch (reportView) {
            case "day":
                resultDate = endDate;
                break;
            case "week":
                resultDate = DateUtil.getLastDayStrOfWeek(DateUtil.parseDate(endDate));
                break;
            case "month":
                resultDate = DateUtil.getLastDayOfMonth(DateUtil.parseDate(endDate));
                break;
        }

        return resultDate;
    }

    /**
     * 根据报表显示类型获取日期间隔
     */
    private int getIntervalByReportView(String startDate, String endDate, String reportView) {

        int interval = 0;

        switch (reportView) {
            case "day":
                interval = DateUtil.getDateInterval(startDate, endDate).size();
                break;
            case "week":
                interval = DateUtil.getEveryWeek(startDate, endDate).size();
                break;
            case "month":
                interval = DateUtil.getEveryMonth(startDate, endDate).size();
                break;
        }

        return interval;
    }
}
