package com.malk.service.dingtalk.impl;

import cn.hutool.core.util.ObjectUtil;
import com.malk.server.dingtalk.DDConf;
import com.malk.server.dingtalk.DDR;
import com.malk.service.dingtalk.DDClient_Attendance;
import com.malk.utils.UtilHttp;
import com.malk.utils.UtilMap;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

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

/**
 * 考勤
 *
 * @apiNote https://open.dingtalk.com/document/orgapp/attendance-overview
 */
@Service
@Slf4j
public class DDImplClient_Attendance implements DDClient_Attendance {

    /**
     * 获取打卡结果
     *
     * @apiNote https://open.dingtalk.com/document/orgapp/open-attendance-clock-in-data
     */
    @Override
    public List<Map> listAttendanceResult(String access_token, String[] userIdList, String workDateFrom, String workDateTo, Number offset, Number limit) {
        Map param = UtilMap.map("access_token", access_token);
        Map body = UtilMap.map("userIdList, workDateFrom, workDateTo, offset, limit, isI18n", userIdList, workDateFrom, workDateTo, offset, limit, false);
        return DDR.doPost("https://oapi.dingtalk.com/attendance/list", null, param, body).getRecordresult();
    }

    /**
     * 获取打卡详情
     *
     * @param userIds       企业内的员工ID列表，最大值50;
     * @param checkDateFrom checkDateFrom 和workDateTo参数相隔最多7天（包含7天）; 注: 参数传"2021-12-01 18:00:00"，员工在19:00的打卡信息获取不到
     */
    @Override
    public List<Map> listAttendanceRecord(String access_token, List userIds, String checkDateFrom, String checkDateTo) {
        Map param = UtilMap.map("access_token", access_token);
        Map body = UtilMap.map("userIds, checkDateFrom, checkDateTo, isI18n", userIds, checkDateFrom, checkDateTo, false);
        return DDR.doPost("https://oapi.dingtalk.com/attendance/listRecord", null, param, body).getRecordresult();
    }

    /**
     * 获取打卡详情
     *
     * @apiNote https://open.dingtalk.com/document/isvapp/upload-punch-records
     */
    @Override
    public boolean uploadAttendanceRecord(String access_token, String userId, String deviceName, String deviceId, String photoUrl, long userCheckTime) {
        Map param = UtilMap.map("access_token", access_token);
        Map body = UtilMap.map("userid, device_name, device_id, photo_url, user_check_time", userId, deviceName, deviceId, photoUrl, userCheckTime);
        return DDR.doPost("https://oapi.dingtalk.com/topapi/attendance/record/upload", null, param, body).isSuccess();
    }

    /**
     * 查询假期余额 [分页是根据游标控制]
     *
     * @apiNote https://open.dingtalk.com/document/isvapp-server/query-holiday-balance
     */
    @Override
    public List<Map> queryVacationQuota(String access_token, String op_userid, String leave_code, String userids, int offset, int size) {
        return _queryVacationQuota(access_token, op_userid, leave_code, userids, offset + size, size, null);
    }

    /**
     * 查询假期余额_全部
     */
    @Override
    public List<Map> queryVacationQuota_all(String access_token, String op_userid, String leave_code, String userids, int offset, int size) {
        return _queryVacationQuota(access_token, op_userid, leave_code, userids, offset + size, size, new ArrayList<>());
    }

    // 递归查询 | 单次查询
    private List<Map> _queryVacationQuota(String access_token, String op_userid, String leave_code, String userids, int offset, int size, List<Map> records) {
        Map body = new HashMap();
        body.put("leave_code", leave_code);
        body.put("op_userid", op_userid);
        body.put("userids", userids);
        body.put("offset", offset);
        body.put("size", size);
        DDR ddr = (DDR) UtilHttp.doPost("https://oapi.dingtalk.com/topapi/attendance/vacation/quota/list", null, DDConf.initTokenParams(access_token), body, DDR.class);
        List<Map> list = (List<Map>) ((Map) ddr.getResult()).get("leave_quotas");
        if (ObjectUtil.isNull(records)) {
            return list;
        }
        records.addAll(list);
        if (Boolean.TRUE.equals(((Map<?, ?>) ddr.getResult()).get("has_more"))) {
            _queryVacationQuota(access_token, op_userid, leave_code, userids, offset + size, size, records);
        }
        return records;
    }

    /**
     * 批量查询人员排班信息
     *
     * @apiNote https://open.dingtalk.com/document/orgapp/query-batch-scheduling-information
     */
    @Override
    public List<Map> listScheduleUsers(String access_token, String op_user_id, List<String> userids, long from_date_time, long to_date_time) {
        Map params = UtilMap.map("op_user_id, userids, from_date_time, to_date_time", op_user_id, String.join(",", userids), from_date_time, to_date_time);
        DDR ddr = DDR.doPost("https://oapi.dingtalk.com/topapi/attendance/schedule/listbyusers", null, DDConf.initTokenParams(access_token), params);
        if (ObjectUtil.isNull(ddr.getResult())) {
            return new ArrayList<>();
        }
        return (List<Map>) ddr.getResult();
    }

    /**
     * 查询是否启用智能统计报表
     */
    @Override
    public boolean isOpenSmartReport(String access_token) {
        DDR ddr = DDR.doPost("https://oapi.dingtalk.com/topapi/attendance/isopensmartreport", null, DDConf.initTokenParams(access_token), null);
        return UtilMap.getBoolean(((Map) ddr.getResult()), "smart_report");
    }

    /**
     * 获取考勤报表列定义
     *
     * @apiNote https://open.dingtalk.com/document/orgapp/queries-the-enterprise-attendance-report-column
     */
    @Override
    public List<Map> getAttColumns(String access_token) {
        DDR ddr = DDR.doPost("https://oapi.dingtalk.com/topapi/attendance/getattcolumns", null, DDConf.initTokenParams(access_token), null);
        return (List<Map>) ((Map) (ddr.getResult())).get("columns");
    }

    /**
     * 获取考勤报表列值
     *
     * @apiNote https://open.dingtalk.com/document/orgapp/queries-the-column-value-of-the-attendance-report
     */
    @Override
    public List<Map> getAttColumnVal(String access_token, String userid, List<String> column_id_list, String from_date, String to_date) {
        Map boyds = UtilMap.map("userid, column_id_list, from_date, to_date", userid, String.join(",", column_id_list), from_date, to_date);
        DDR ddr = DDR.doPost("https://oapi.dingtalk.com/topapi/attendance/getcolumnval", null, DDConf.initTokenParams(access_token), boyds);
        return (List<Map>) ((Map) (ddr.getResult())).get("column_vals");
    }

    /**
     * 获取报表假期数据
     *
     * @apiNote https://open.dingtalk.com/document/orgapp/obtains-the-holiday-data-from-the-smart-attendance-report
     */
    @Override
    public List<Map> getLeaveTimeByNames(String access_token, String userid, List<String> leave_names, String from_date, String to_date) {
        Map boyds = UtilMap.map("userid, leave_names, from_date, to_date", userid, String.join(",", leave_names), from_date, to_date);
        DDR ddr = DDR.doPost("https://oapi.dingtalk.com/topapi/attendance/getleavetimebynames", null, DDConf.initTokenParams(access_token), boyds);
        return (List<Map>) ((Map) (ddr.getResult())).get("columns");
    }

    /**
     * 获取用户考勤数据
     *
     * @apiNote https://open.dingtalk.com/document/orgapp/obtain-the-attendance-update-data
     */
    @Override
    public Map getAttendanceRecord(String access_token, String userid, String work_date) {
        Map bodys = UtilMap.map("userid, work_date", userid, work_date);
        DDR ddr = DDR.doPost("https://oapi.dingtalk.com/topapi/attendance/getupdatedata", null, DDConf.initTokenParams(access_token), bodys);
        return (Map) ddr.getResult();
    }


    /**
     * 获取班次详情
     *
     * @apiNote https://open.dingtalk.com/document/orgapp/shift-query
     */
    @Override
    public Map getAttendanceShiftDetail(String access_token, String op_user_id, String shift_id) {
        Map boyds = UtilMap.map("op_user_id, shift_id", op_user_id, shift_id);
        return (Map) DDR.doPost("https://oapi.dingtalk.com/topapi/attendance/shift/query", null, DDConf.initTokenParams(access_token), boyds).getResult();
    }

    /**
     * 查询企业考勤排班详情
     */

    /**
     * @apiNote https://open.dingtalk.com/document/isvapp/query-a-single-attendance-group
     */
    @Override
    public Map getAttendanceGroupDetail(String access_token, String op_user_id, String group_id) {
        Map boyds = UtilMap.map("op_user_id, group_id", op_user_id, group_id);
        return (Map) DDR.doPost("https://oapi.dingtalk.com/topapi/attendance/group/query", null, DDConf.initTokenParams(access_token), boyds).getResult();
    }

    /**
     * 搜索考勤组摘要
     *
     * @apiNote https://open.dingtalk.com/document/isvapp/query-a-single-attendance-group
     */
    @Override
    public List<Map> getAttendanceGroupSearch(String access_token, String op_user_id, String group_name) {
        Map boyds = UtilMap.map("op_user_id, group_name", op_user_id, group_name);
        return (List<Map>) DDR.doPost("https://oapi.dingtalk.com/topapi/attendance/group/search", null, DDConf.initTokenParams(access_token), boyds).getResult();
    }
}
