package com.jiayue.ssi.controller;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jiayue.ssi.annotation.OperateLog;
import com.jiayue.ssi.annotation.PreventReplay;
import com.jiayue.ssi.backenum.AuditType;
import com.jiayue.ssi.backenum.BusinessType;
import com.jiayue.ssi.constant.CustomException;
import com.jiayue.ssi.entity.SysLogininfor;
import com.jiayue.ssi.service.SysLogininforService;
import com.jiayue.ssi.util.DateUtils;
import com.jiayue.ssi.util.ResponseVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 系统访问记录
 *
 * @author ruoyi
 */
@RestController
@RequestMapping("/sysLogininforController")
@Slf4j
public class SysLogininforController {
    @Autowired
    SysLogininforService sysLogininforService;

    /**
     * 获取列表分页信息
     *
     * @return 列表信息
     */
    @GetMapping(value = "/getAll")
    @PreAuthorize("@ss.hasPermi('auditManager:logininfor:list')")
    @PreventReplay
    public ResponseVO getAll(String currentPage, String pageSize, String ipaddr, String userName,
                             String status, String startLoginTime, String endLoginTime, String sortOrder) throws CustomException {
        try {
            Integer cp;
            if (StringUtils.isNotEmpty(currentPage)) {
                if (NumberUtil.isInteger(currentPage)){
                    cp = Integer.parseInt(currentPage);
                }
                else{
                    return ResponseVO.fail("currentPage不是整数！");
                }
            }
            else{
                return ResponseVO.fail("currentPage不能是空！");
            }

            Integer ps;
            if (StringUtils.isNotEmpty(pageSize)) {
                if (NumberUtil.isInteger(pageSize)){
                    ps = Integer.parseInt(pageSize);
                }
                else{
                    return ResponseVO.fail("pageSize不是整数！");
                }
            }
            else{
                return ResponseVO.fail("pageSize不能是空！");
            }

            if (StringUtils.isNotEmpty(ipaddr)) {
                if (ipaddr.length() > 128) {
                    return ResponseVO.fail("登录地址长度不能超过128个字符！");
                }
            }
            if (StringUtils.isNotEmpty(userName)) {
                if (userName.length() > 50) {
                    return ResponseVO.fail("用户账号长度不能超过50个字符！");
                }
            }
            QueryWrapper<SysLogininfor> wrapper = new QueryWrapper<>();
            if (StringUtils.isNotEmpty(ipaddr)) {
                wrapper.eq("ipaddr", ipaddr);
            }
            if (StringUtils.isNotEmpty(userName)) {
                wrapper.eq("user_name", userName);
            }
            if (StringUtils.isNotEmpty(status)) {
                wrapper.eq("status", status);
            }
            if (StringUtils.isNotEmpty(startLoginTime)) {
                wrapper.ge("login_time", DateUtils.getDayStartTime(DateUtil.parseDate(startLoginTime)));
            }
            if (StringUtils.isNotEmpty(endLoginTime)) {
                wrapper.le("login_time", DateUtils.getDayLastTime(DateUtil.parseDate(endLoginTime)));
            }

            if (StringUtils.isNotEmpty(sortOrder)) {
                String[] orders = sortOrder.replaceAll("＆","&").split("&");
                String sortDbField = "";
                if ("loginTime".equals(orders[0])) {
                    sortDbField = "login_time";
                } else if ("userName".equals(orders[0])) {
                    sortDbField = "user_name";
                }

                if ("asc".equals(orders[1])) {
                    wrapper.orderByAsc(sortDbField);
                } else {
                    wrapper.orderByDesc(sortDbField);
                }
            }

            Page<SysLogininfor> result = sysLogininforService.page(new Page<>(cp, ps), wrapper);
            return ResponseVO.success(result);
        } catch (Exception e) {
            throw new CustomException("获取登录日志列表异常", e);
        }
    }

    /**
     * 删除登录信息
     */
    @PostMapping(value = "/delLoginInfo")
    @OperateLog(title = "登录日志", businessType = BusinessType.DELETE, auditType = AuditType.SYS)
    @PreAuthorize("@ss.hasPermi('auditManager:logininfor:remove')")
    public ResponseVO delLoginInfo(String infoId) throws CustomException {
        try {
            if (StringUtils.isEmpty(infoId)) {
                return ResponseVO.fail("id不能为空!");
            }

            boolean bo = sysLogininforService.removeLoginInfoById(Long.parseLong(infoId));
            if (bo) {
                return ResponseVO.success("删除登录信息成功");
            } else {
                log.error("删除用户信息失败");
                return ResponseVO.fail("删除登录信息失败");
            }
        } catch (Exception e) {
            throw new CustomException("删除登录信息异常", e);
        }
    }

    /**
     * 清空登录信息
     */
    @PostMapping("/cleanLogininfor")
    @OperateLog(title = "登录日志", businessType = BusinessType.CLEAN, auditType = AuditType.SYS)
    @PreAuthorize("@ss.hasPermi('auditManager:logininfor:remove')")
    public ResponseVO cleanLogininfor() throws CustomException {
        try {
            boolean bo = sysLogininforService.cleanLogininfor();
            if (bo) {
                return ResponseVO.success("登录日志清空成功");
            } else {
                log.error("登录日志清空失败");
                return ResponseVO.fail("登录日志清空失败");
            }
        } catch (Exception e) {
            throw new CustomException("登录日志清空异常", e);
        }
    }

    /**
     * 登录日志统计分析
     *
     * @return 列表信息
     */
    @GetMapping(value = "/logininforTotal")
    @PreAuthorize("@ss.hasPermi('auditManager:logininforTotal:list')")
    @PreventReplay
    public ResponseVO logininforTotal(String startLoginTime, String endLoginTime) throws CustomException {
        try {
            QueryWrapper<SysLogininfor> wrapper = new QueryWrapper<>();
            if (StringUtils.isNotEmpty(startLoginTime)) {
                wrapper.ge("login_time", DateUtils.getDayStartTime(DateUtil.parseDate(startLoginTime)));
            }
            if (StringUtils.isNotEmpty(endLoginTime)) {
                wrapper.le("login_time", DateUtils.getDayLastTime(DateUtil.parseDate(endLoginTime)));
            }
            List<SysLogininfor> sysLogininforList = sysLogininforService.list(wrapper);
            Map<String, List<SysLogininfor>> map = sysLogininforList.stream().collect(Collectors.groupingBy(item -> DateUtil.format(item.getLoginTime(), "yyyy-MM-dd")));
            List<Map<String, String>> resultList = new ArrayList<>();
            map.forEach((key, value) -> {
                List<SysLogininfor> list = value;
                Map<String, String> recordMap = new HashMap<>();
                recordMap.put("day", key);
                recordMap.put("count", list.size() + "");
                // 登录成功统计
                List<SysLogininfor> successList = list.stream().filter(sysLogininfor -> "0".equals(sysLogininfor.getStatus())).collect(Collectors.toList());
                recordMap.put("success", successList.size() + "");
                // 登录失败统计
                List<SysLogininfor> failList = list.stream().filter(sysLogininfor -> "1".equals(sysLogininfor.getStatus())).collect(Collectors.toList());
                recordMap.put("fail", failList.size() + "");
                // 登录ip个数统计
                int ips = list.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(s -> s.getIpaddr()))), ArrayList::new)).size();
                recordMap.put("ips", ips + "");
                resultList.add(recordMap);
            });
            Collections.sort(resultList, new Comparator<Map<String, String>>() {
                @Override
                public int compare(Map<String, String> o1, Map<String, String> o2) {
                    return o1.get("day").compareTo(o2.get("day"));
                }
            });
            return ResponseVO.success(resultList);
        } catch (Exception e) {
            throw new CustomException("获取登录日志统计列表异常", e);
        }
    }
}
