package com.malk.fengkaili.controller;

/**
 * 错误抛出与拦截详见 CatchException
 */

import com.malk.fengkaili.repository.entity.FKLDdContactPo;
import com.malk.fengkaili.service.FKLService;
import com.malk.server.common.McException;
import com.malk.server.common.McPage;
import com.malk.server.common.McR;
import com.malk.service.dingtalk.DDService;
import com.malk.utils.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@RestController
@RequestMapping
public class FKLController {

    @Autowired
    private FKLService fklService;

    /**
     * 同步用户 & 部门
     */
    @PostMapping("syncUserInfo")
    McR syncUserInfo() {
        fklService.syncUserInfo();
        return McR.success();
    }

    /// 考勤汇总
    private McPage _getAttendanceList(Map data, List<String> days, HttpServletRequest request) {
        log.info("考勤汇总, {}", UtilServlet.getHeaders(request).get("authorization"));
        log.info("考勤汇总, {}", UtilServlet.getHeaders(request));
        McException.assertParamException_Null(data, "startTime", "endTime");
        McException.assertAccessException(StringUtils.isBlank(UtilServlet.getHeaders(request).get("authorization")), "该账户无操作权限");

        List<Long> dpetIds = (List<Long>) data.get("deptId");
        // 基于用户分页
        Date sDate = UtilDateTime.parseDate(UtilMap.getString(data, "startTime"));
        Page page = fklService.queryUserInfos(UtilMap.getInt(data, "page"), UtilMap.getInt(data, "size"), UtilMap.getString(data, "name"), dpetIds, sDate);
        McException.assertAccessException(page.getTotalElements() == 0, "查询用户为空!");

        List<FKLDdContactPo> userInfos = page.getContent();
        List<Map> dataList = fklService.queryAttendanceList(data.get("startTime").toString(), data.get("endTime").toString(), userInfos, days);
        log.info("汇总数量, {}", dataList.size());
        return McPage.page(page, dataList);
    }

    /**
     * 查询考勤汇总
     */
    @PostMapping("queryAttendanceList")
    McR queryAttendanceList(@RequestBody Map data, HttpServletRequest request) {
        return McR.success(_getAttendanceList(data, null, request));
    }

    /**
     * 查询考勤汇总 [天]
     */
    @PostMapping("queryAttendanceDays")
    McR queryAttendanceDays(@RequestBody Map data, HttpServletRequest request) {
        List<String> days = new ArrayList<>();
        return McR.success(UtilMap.map("page, prop", _getAttendanceList(data, days, request), days));
    }

    /**
     * 导出考勤汇总
     */
    @PostMapping("exportAttendanceList")
    void exportAttendanceList(@RequestBody Map data, HttpServletResponse response, HttpServletRequest request) {

        data.put("page", 1);
        data.put("size", Integer.MAX_VALUE);
        List<Map> dataList = _getAttendanceList(data, null, request).getList();
        //  获取出现最多次作为法定应出勤天数, 考勤应出勤天数和班组 + 人员挂钩 [班次详情应出勤不准确]
        float workdays = (Float) UtilList.maxFrequencyObject(dataList.stream().map(item -> {
            float val = 0.f;
            // 数据内0字段被忽略, 兼容处理
            if (item.containsKey("出勤天数")) {
                val = UtilMap.getFloat(item, "出勤天数");
            }
            return val;
        }).collect(Collectors.toList()));
        String range = ("核算周期: " + data.get("startTime").toString().split(" ")[0].replace("-", ".") + "-" + data.get("endTime").toString().split(" ")[0].replace("-", "."));
        String attendance = workdays + "天*8小时*60分钟=";
        Map dataMain = UtilMap.map("核算周期, 应出勤天数, 应出勤分钟", range, attendance, workdays * 8f * 60f);
        dataMain.put("date", UtilDateTime.format(UtilDateTime.parseDateTime(UtilMap.getString(data, "endTime")), "yyyy年MM月"));
        UtilExcel.exportMapAndListByTemplate(response, dataMain, dataList, Map.class, "月度汇总", "Template_month.xlsx");
    }

    /**
     * 导出考勤汇总 [天]
     */
    @PostMapping("exportAttendanceDays")
    void exportAttendanceDays(@RequestBody Map data, HttpServletResponse response, HttpServletRequest request) {
        data.put("page", 1);
        data.put("size", Integer.MAX_VALUE);

        // 动态表头模板导出
        List<String> days = new ArrayList<>();
        List<Map> dataList = _getAttendanceList(data, days, request).getList();
        Map dataMain = new HashMap();
        days.forEach(UtilMc.consumerWithIndex((item, index) -> {
            dataMain.put("day" + (index + 1), item);
        }));
        dataMain.put("date", UtilDateTime.format(UtilDateTime.parseDateTime(UtilMap.getString(data, "endTime")), "yyyy年MM月"));
        UtilExcel.exportMapAndListByTemplate(response, dataMain, dataList, Map.class, "月度明细", "Template_days.xlsx");
    }

    @Autowired
    private DDService ddService;

    public static String jsApi_nonceStr = "720F4HNA579C0ZHEDR";
    public static String jsApi_url = "http://localhost:8001";

    /**
     * jsApi 注册
     */
    @PostMapping("register")
    McR register() {
        return McR.success(ddService.registerJsApi(jsApi_url, jsApi_nonceStr));
    }

    /**
     * jsApi 免登
     */
    @PostMapping("user/code")
    McR userCodeAuth(@RequestBody Map<String, String> data) {
        McException.assertParamException_Null(data, "code");
        return McR.success(ddService.getUserInfoByCode(data.get("code")));
    }

    @PostMapping("test")
    McR test() {
        return McR.success();
    }
}
