package com.ruoyi.web.controller.system;

import java.text.SimpleDateFormat;
import java.util.*;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.common.utils.*;
import com.ruoyi.framework.web.domain.server.Sys;
import com.ruoyi.system.domain.IndexProjectStatusSumModel;
import com.ruoyi.system.domain.IndexProjectSummaryModel;
import com.ruoyi.system.domain.ProjectSumModel;
import com.ruoyi.system.domain.UserLastWeekSumModel;
import com.ruoyi.system.mapper.SystemReportMapper;
import com.ruoyi.system.service.impl.TblProjectCostServiceImpl;
import com.ruoyi.system.service.impl.TblProjectServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.constant.ShiroConstants;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysMenu;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.framework.shiro.service.SysPasswordService;
import com.ruoyi.system.service.ISysConfigService;
import com.ruoyi.system.service.ISysMenuService;
import springfox.documentation.spring.web.json.Json;

/**
 * 首页 业务处理
 *
 * @author ruoyi
 */
@Controller
public class SysIndexController extends BaseController {
    @Autowired
    private ISysMenuService menuService;

    @Autowired
    private ISysConfigService configService;

    @Autowired
    private SysPasswordService passwordService;

    @Autowired
    private SystemReportMapper systemReportMapper;

    // 系统首页
    @GetMapping("/index")
    public String index(ModelMap mmap) {
        // 取身份信息
        SysUser user = ShiroUtils.getSysUser();
        // 根据用户id取出菜单
        List<SysMenu> menus = menuService.selectMenusByUser(user);
        mmap.put("menus", menus);
        mmap.put("user", user);
        mmap.put("sideTheme", configService.selectConfigByKey("sys.index.sideTheme"));
        mmap.put("skinName", configService.selectConfigByKey("sys.index.skinName"));
        mmap.put("ignoreFooter", configService.selectConfigByKey("sys.index.ignoreFooter"));
        mmap.put("copyrightYear", RuoYiConfig.getCopyrightYear());
        mmap.put("demoEnabled", RuoYiConfig.isDemoEnabled());
        mmap.put("isDefaultModifyPwd", initPasswordIsModify(user.getPwdUpdateDate()));
        mmap.put("isPasswordExpired", passwordIsExpiration(user.getPwdUpdateDate()));

        // 菜单导航显示风格
        String menuStyle = configService.selectConfigByKey("sys.index.menuStyle");
        // 移动端，默认使左侧导航菜单，否则取默认配置
        String indexStyle = ServletUtils.checkAgentIsMobile(ServletUtils.getRequest().getHeader("User-Agent")) ? "index" : menuStyle;

        // 优先Cookie配置导航菜单
        Cookie[] cookies = ServletUtils.getRequest().getCookies();
        for (Cookie cookie : cookies) {
            if (StringUtils.isNotEmpty(cookie.getName()) && "nav-style".equalsIgnoreCase(cookie.getName())) {
                indexStyle = cookie.getValue();
                break;
            }
        }
        String webIndex = "topnav".equalsIgnoreCase(indexStyle) ? "index-topnav" : "index";
        return webIndex;
    }

    // 锁定屏幕
    @GetMapping("/lockscreen")
    public String lockscreen(ModelMap mmap) {
        mmap.put("user", ShiroUtils.getSysUser());
        ServletUtils.getSession().setAttribute(ShiroConstants.LOCK_SCREEN, true);
        return "lock";
    }

    // 解锁屏幕
    @PostMapping("/unlockscreen")
    @ResponseBody
    public AjaxResult unlockscreen(String password) {
        SysUser user = ShiroUtils.getSysUser();
        if (StringUtils.isNull(user)) {
            return AjaxResult.error("服务器超时，请重新登陆");
        }
        if (passwordService.matches(user, password)) {
            ServletUtils.getSession().removeAttribute(ShiroConstants.LOCK_SCREEN);
            return AjaxResult.success();
        }
        return AjaxResult.error("密码不正确，请重新输入。");
    }

    // 切换主题
    @GetMapping("/system/switchSkin")
    public String switchSkin() {
        return "skin";
    }

    // 切换菜单
    @GetMapping("/system/menuStyle/{style}")
    public void menuStyle(@PathVariable String style, HttpServletResponse response) {
        CookieUtils.setCookie(response, "nav-style", style);
    }

    // 系统介绍
    @GetMapping("/system/main")
    public String main(ModelMap mmap) {
        //依据权限显示不同的首页
        if(!ShiroUtils.isPermitted("system:index:summary")){
            return "main/blank";
        }


        mmap.put("version", RuoYiConfig.getVersion());

        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Calendar scb = Calendar.getInstance();
        scb.setTime(new Date());
        int dow = scb.get(Calendar.DAY_OF_WEEK);
        boolean showThisWeek = false;
        if (dow == Calendar.FRIDAY || dow == Calendar.SATURDAY) { //周五、周六显示当周统计
            showThisWeek = true;
        }
        Calendar sc = Calendar.getInstance();
        sc.set(Calendar.DAY_OF_WEEK, Calendar.SATURDAY);
        sc.add(Calendar.DAY_OF_MONTH, showThisWeek ? -7 : -14);
        Date sd = sc.getTime();
        Calendar ec = Calendar.getInstance();
        ec.set(Calendar.DAY_OF_WEEK, Calendar.SATURDAY);
        ec.add(Calendar.DAY_OF_MONTH, showThisWeek ? 0 : -7);
        Date ed = ec.getTime();
        ec.add(Calendar.DATE, -1);
        Date showED = ec.getTime();
        String sdStr = format.format(sd);
        String edStr = format.format(ed);
        String showEDStr = format.format(showED);
        UserLastWeekSumModel lastWeekSum = systemReportMapper.selectUserLastWeekSummary(sdStr, edStr);
        List<ProjectSumModel> lastWeekProjectSum = systemReportMapper.selectProjectLastWeekSummary(sdStr, edStr, true);
        List<ProjectSumModel> projectSummary = systemReportMapper.selectProjectCostSummary(true);
        List<IndexProjectStatusSumModel> projectSum = systemReportMapper.selectProjectSummaryByStatus();
        List<SysDictData> projectStatus = DictUtils.getDictCache("project_status");
        List<IndexProjectSummaryModel> indexProjectSum = new ArrayList<IndexProjectSummaryModel>();
        Long projectCount = (long) 0;
        if (projectStatus != null) {
            for (SysDictData dic : projectStatus) {
                IndexProjectSummaryModel sum = new IndexProjectSummaryModel();
                sum.setName(dic.getDictLabel());
                Optional<IndexProjectStatusSumModel> res = projectSum.stream().filter(x ->
                        x.getStatusCode().equals(dic.getDictValue())
                ).findFirst();
                if (res.isPresent()) {
                    sum.setCount(res.get().getCount());
                } else {
                    sum.setCount((long) 0);
                }
                projectCount += sum.getCount();
                indexProjectSum.add(sum);
            }
        }
        mmap.put("startDate", sdStr);
        mmap.put("endDate", showEDStr);
        mmap.put("lastWeekSum", lastWeekSum);
        mmap.put("projectCount", projectCount);
        mmap.put("indexProjectSum", indexProjectSum);
        mmap.put("lastWeekProjectSum", lastWeekProjectSum);
        mmap.put("projectSummary", projectSummary);
//        mmap.put("lastWeekProjectSum", JSON.toJSONString(lastWeekProjectSum));
        return "main";
    }

    // 检查初始密码是否提醒修改
    public boolean initPasswordIsModify(Date pwdUpdateDate) {
        Integer initPasswordModify = Convert.toInt(configService.selectConfigByKey("sys.account.initPasswordModify"));
        return initPasswordModify != null && initPasswordModify == 1 && pwdUpdateDate == null;
    }

    // 检查密码是否过期
    public boolean passwordIsExpiration(Date pwdUpdateDate) {
        Integer passwordValidateDays = Convert.toInt(configService.selectConfigByKey("sys.account.passwordValidateDays"));
        if (passwordValidateDays != null && passwordValidateDays > 0) {
            if (StringUtils.isNull(pwdUpdateDate)) {
                // 如果从未修改过初始密码，直接提醒过期
                return true;
            }
            Date nowDate = DateUtils.getNowDate();
            return DateUtils.differentDaysByMillisecond(nowDate, pwdUpdateDate) > passwordValidateDays;
        }
        return false;
    }
}
