package ink.wgink.login.base.service.count.impl;

import ink.wgink.common.base.DefaultBaseService;
import ink.wgink.interfaces.position.IPositionBaseService;
import ink.wgink.interfaces.role.IRoleBaseService;
import ink.wgink.login.base.service.count.ICountService;
import ink.wgink.login.base.service.log.ILoginLogService;
import ink.wgink.service.department.service.IDepartmentService;
import ink.wgink.service.user.enums.UserStateEnum;
import ink.wgink.service.user.enums.UserTypeEnum;
import ink.wgink.service.user.service.IUserService;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * When you feel like quitting. Think about why you started
 * 当你想要放弃的时候，想想当初你为何开始
 *
 * @ClassName: CountServiceImpl
 * @Description: 统计
 * @Author: wanggeng
 * @Date: 2021/2/28 9:37 上午
 * @Version: 1.0
 */
@Service
public class CountServiceImpl extends DefaultBaseService implements ICountService {

    @Autowired
    private IUserService userService;
    @Autowired
    private IDepartmentService departmentService;
    @Autowired
    private ILoginLogService loginLogService;
    @Autowired(required = false)
    private IRoleBaseService roleBaseService;
    @Autowired(required = false)
    private IPositionBaseService positionBaseService;

    @Override
    public Map<String, Object> countNewUserByWeek(Map<String, Object> params) {
        DateTime now = DateTime.now();
        DateTimeFormatter dayDateTimeFormatter = DateTimeFormat.forPattern(DAY_FORMATTER);
        int weekNewUserCount = userService.countDateRange(now.dayOfWeek().withMinimumValue().toString(dayDateTimeFormatter), now.dayOfWeek().withMaximumValue().toString(dayDateTimeFormatter));
        int totalUserCount = userService.count();

        Map<String, Object> result = getHashMap(4);
        result.put("count", weekNewUserCount);
        result.put("percentage", new BigDecimal(getPercentage(weekNewUserCount, totalUserCount)).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
        return result;
    }

    @Override
    public Map<String, Object> countUser(Map<String, Object> params) {
        DateTime now = DateTime.now();
        DateTimeFormatter dayDateTimeFormatter = DateTimeFormat.forPattern(DAY_FORMATTER);
        int monthUserCount = userService.countDateRange(now.dayOfMonth().withMinimumValue().toString(dayDateTimeFormatter), now.dayOfMonth().withMaximumValue().toString(dayDateTimeFormatter));
        int totalUserCount = userService.count();

        Map<String, Object> result = getHashMap(4);
        result.put("count", totalUserCount);
        result.put("newCount", monthUserCount);
        return result;
    }

    @Override
    public Map<String, Object> countLogin(Map<String, Object> params) {
        DateTime now = DateTime.now();
        DateTimeFormatter dayDateTimeFormatter = DateTimeFormat.forPattern(DAY_FORMATTER);
        int loginLoggerCount = loginLogService.countDay(now.toString(dayDateTimeFormatter));
        int yesterdayLoggerCount = loginLogService.countDay(now.minusDays(1).toString(dayDateTimeFormatter));

        Map<String, Object> result = getHashMap(4);
        result.put("count", loginLoggerCount);
        result.put("percentage", new BigDecimal(getPercentage((loginLoggerCount - yesterdayLoggerCount), yesterdayLoggerCount)).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
        return result;
    }

    @Override
    public Map<String, Object> countLoginForDays(Integer days) {
        DateTime now = DateTime.now();
        DateTimeFormatter dayDateTimeFormatter = DateTimeFormat.forPattern(DAY_FORMATTER);
        List<String> dateArray = new ArrayList<>();
        List<String> loginCountArray = new ArrayList<>();
        for (int i = days - 1; i >= 0; i--) {
            String currentDay = now.minusDays(i).toString(dayDateTimeFormatter);
            dateArray.add(currentDay);
            loginCountArray.add("" + loginLogService.countDay(currentDay));
        }
        Map<String, Object> result = new HashMap<>(2);
        result.put("dateArray", dateArray);
        result.put("loginCountArray", loginCountArray);
        return result;
    }

    @Override
    public Integer countDepartment() {
        Map<String, Object> params = getHashMap(0);
        return departmentService.count(params);
    }

    @Override
    public Integer countRole() {
        Map<String, Object> params = getHashMap(0);
        if (roleBaseService != null) {
            return roleBaseService.count(params);
        }
        return 0;
    }

    @Override
    public Integer countPosition() {
        Map<String, Object> params = getHashMap(0);
        if (positionBaseService != null) {
            return positionBaseService.count(params);
        }
        return 0;
    }

    @Override
    public List<Map<String, Object>> countUserTypeProportion() {
        Integer systemUserCount = userService.countType(UserTypeEnum.SYSTEM.getValue());
        Integer normalUserCount = userService.countType(UserTypeEnum.NORMAL.getValue());
        Integer errorLoginTypeCount = userService.countErrorType();

        Map<String, Object> systemUserCountResult = getHashMap(6);
        systemUserCountResult.put("name", "系统用户");
        systemUserCountResult.put("value", systemUserCount);
        systemUserCountResult.put("color", "#009688");

        Map<String, Object> normalUserCountResult = getHashMap(6);
        normalUserCountResult.put("name", "普通用户");
        normalUserCountResult.put("value", normalUserCount);
        normalUserCountResult.put("color", "#FFB800");

        Map<String, Object> errorLoginTypeCountResult = getHashMap(6);
        errorLoginTypeCountResult.put("name", "类型错误");
        errorLoginTypeCountResult.put("value", errorLoginTypeCount);
        errorLoginTypeCountResult.put("color", "#FF5722");

        List<Map<String, Object>> result = new ArrayList<>();
        result.add(systemUserCountResult);
        result.add(normalUserCountResult);
        result.add(errorLoginTypeCountResult);
        return result;
    }

    @Override
    public List<Map<String, Object>> countUserStateProportion() {
        Integer normalUserCount = userService.countState(UserStateEnum.NORMAL.getValue());
        Integer lockingUserCount = userService.countState(UserStateEnum.LOCK.getValue());

        Map<String, Object> normalUserCountResult = getHashMap(3);
        normalUserCountResult.put("name", "正常用户");
        normalUserCountResult.put("value", normalUserCount);
        normalUserCountResult.put("color", "#009688");

        Map<String, Object> lockingUserCountResult = getHashMap(3);
        lockingUserCountResult.put("name", "锁定用户");
        lockingUserCountResult.put("value", lockingUserCount);
        lockingUserCountResult.put("color", "#1E9FFF");

        List<Map<String, Object>> result = new ArrayList<>();
        result.add(normalUserCountResult);
        result.add(lockingUserCountResult);
        return result;
    }

    /**
     * 计算占比
     *
     * @param count
     * @param totalCount
     * @return
     */
    private double getPercentage(int count, int totalCount) {
        if (totalCount == 0) {
            return 100D;
        }
        return (count * 1.0) / totalCount * 100;
    }
}
