package com.jeeplus.test.dingding.controller;

import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.*;
import com.dingtalk.api.response.*;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.jeeplus.logging.annotation.ApiLog;
import com.jeeplus.test.dingding.dto.AddUserDTO;
import com.jeeplus.test.dingding.dto.DeptDTO;
import com.jeeplus.test.dingding.dto.DdUserDTO;
import com.jeeplus.test.dingding.dto.UserRequestDTO;
import com.jeeplus.utils.StringUtils;
import com.taobao.api.ApiException;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@RestController
@RequestMapping(value = "/test/addressBook")
public class DingdingAddressBookController {

    @Value("dingtk0peibzdlxdmojz")
    private String appKey;

    @Value("NWFAu2fcfKlW3GxlvrGEwMjvJ7jyCPq0Q70XzptUsxE5PYs9cx5wTBWL0wjxKBtf")
    private String appSecret;

    /**
     * 获取token
     */
//    @ApiLog("获取token")
//    @ApiOperation(value = "获取token")
//    @GetMapping("getToken")
    public String getToken() throws ApiException {
        // 创建钉钉客户端
        DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/gettoken");
        // 配置请求参数
        OapiGettokenRequest req = new OapiGettokenRequest();
        req.setAppkey(appKey); // 确保 appKey 已正确初始化
        req.setAppsecret(appSecret); // 确保 appSecret 已正确初始化
        req.setHttpMethod("GET");
        // 执行请求，获取响应
        OapiGettokenResponse rsp = client.execute(req);
        String accessToken = rsp.getAccessToken();
        return accessToken;
    }

    /**
     * 获取用户列表
     */
    @ApiLog("获取用户列表")
    @ApiOperation(value = "获取用户列表")
    @PostMapping("list")
    public ResponseEntity list(@RequestBody UserRequestDTO userRequestDTO) {
        try {
            ArrayList<DdUserDTO> userDTOS = new ArrayList<>();

            String token = getToken();
            DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/list");
            OapiV2UserListRequest req = new OapiV2UserListRequest();
            Long deptId = userRequestDTO.getDeptId();
            String dateFrom = userRequestDTO.getDateFrom();
            String dateTo = userRequestDTO.getDateTo();
            // 设置部门 ID（传递具体部门 ID 值）
            req.setDeptId(deptId); // 替换为你需要的部门 ID
            // 设置分页参数（可选）
            req.setCursor(0L); // 起始点
            req.setSize(50L);  // 每页返回数量，建议不要超过 50
            OapiV2UserListResponse rsp = client.execute(req, token);
            List<OapiV2UserListResponse.ListUserResponse> list = rsp.getResult().getList();

            //获取考勤信息列
            DingTalkClient client1 = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/attendance/getattcolumns");
            OapiAttendanceGetattcolumnsRequest req1 = new OapiAttendanceGetattcolumnsRequest();
            OapiAttendanceGetattcolumnsResponse rsp1 = client1.execute(req1, token);
            ArrayList<OapiAttendanceGetattcolumnsResponse.ColumnForTopVo> arrayList = new ArrayList<>();
            for (OapiAttendanceGetattcolumnsResponse.ColumnForTopVo column : rsp1.getResult().getColumns()) {
                if (column.getName().equals("应出勤天数") || column.getName().equals("出勤天数") || column.getName().equals("休息天数") || column.getName().equals("迟到次数")) {
                    arrayList.add(column);
                }
            }
            String typeIds = arrayList.stream().map(column -> String.valueOf(column.getId())).collect(Collectors.joining(","));
            //获取用户考勤信息
            for (OapiV2UserListResponse.ListUserResponse user : list) {
                DdUserDTO ddUserDTO = new DdUserDTO();
                ddUserDTO.setUserid(user.getUserid());
                ddUserDTO.setMobile(user.getMobile());
                ddUserDTO.setName(user.getName());
                String requiredAttDays = "";//应出勤天数
                String attDays = "";//出勤天数
                String restDays = "";//休息天数
                String lateTimes = "";//迟到次数
                OapiAttendanceGetcolumnvalResponse attRsp = getAttById(user.getUserid(), typeIds, dateFrom, dateTo);
                //根据考勤信息列获取里面的数据
                for (OapiAttendanceGetcolumnvalResponse.ColumnValForTopVo columnVal : attRsp.getResult().getColumnVals()) {
                    for (OapiAttendanceGetattcolumnsResponse.ColumnForTopVo columnForTopVo : arrayList) {
                        //对考勤信息列进行汇总
                        if (columnForTopVo.getId().equals(columnVal.getColumnVo().getId()) && columnForTopVo.getName().equals("应出勤天数")) {
                            double days = 0;
                            for (OapiAttendanceGetcolumnvalResponse.ColumnDayAndVal val : columnVal.getColumnVals()) {
                                double v = Double.parseDouble(val.getValue());
                                days += v;
                            }
                            requiredAttDays = String.valueOf(days);
                        }
                        if (columnForTopVo.getId().equals(columnVal.getColumnVo().getId()) && columnForTopVo.getName().equals("出勤天数")) {
                            double days = 0;
                            for (OapiAttendanceGetcolumnvalResponse.ColumnDayAndVal val : columnVal.getColumnVals()) {
                                double v = Double.parseDouble(val.getValue());
                                days += v;
                            }
                            attDays = String.valueOf(days);
                        }
                        if (columnForTopVo.getId().equals(columnVal.getColumnVo().getId()) && columnForTopVo.getName().equals("休息天数")) {
                            double days = 0;
                            for (OapiAttendanceGetcolumnvalResponse.ColumnDayAndVal val : columnVal.getColumnVals()) {
                                double v = Double.parseDouble(val.getValue());
                                days += v;
                            }
                            restDays = String.valueOf(days);
                        }
                        if (columnForTopVo.getId().equals(columnVal.getColumnVo().getId()) && columnForTopVo.getName().equals("迟到次数")) {
                            double days = 0;
                            for (OapiAttendanceGetcolumnvalResponse.ColumnDayAndVal val : columnVal.getColumnVals()) {
                                double v = Double.parseDouble(val.getValue());
                                days += v;
                            }
                            lateTimes = String.valueOf(days);
                        }
                    }
                }
                ddUserDTO.setAttDays(attDays);
                ddUserDTO.setRequiredAttDays(requiredAttDays);
                ddUserDTO.setRestDays(restDays);
                ddUserDTO.setLateTimes(lateTimes);
                userDTOS.add(ddUserDTO);
            }

            // 返回 JSON 响应
            return ResponseEntity.ok(userDTOS);
        } catch (ApiException e) {
            e.printStackTrace(); // 打印错误日志（开发调试用）
            return ResponseEntity.badRequest().body("接口异常，请重试!");
        } catch (Exception e) {
            e.printStackTrace(); // 打印错误日志（开发调试用）
            return ResponseEntity.badRequest().body("接口异常，请重试!");
        }
    }


    public OapiAttendanceGetcolumnvalResponse getAttById(String userId, String leaveTypes, String dateFrom, String dateTo) throws ApiException, ParseException {
        String access_token = getToken();

        DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/attendance/getcolumnval");
        OapiAttendanceGetcolumnvalRequest req = new OapiAttendanceGetcolumnvalRequest();
        req.setUserid(userId);
        req.setColumnIdList(leaveTypes);
        Date from;
        Date to;
        //日期必须传,当没有日期的时候获取当前的日期
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        if (StringUtils.isBlank(dateFrom) && StringUtils.isBlank(dateTo)) {
            LocalDate today = LocalDate.now();
            LocalDate firstDayOfMonth = today.withDayOfMonth(1);
            // 将 LocalDate 转换为 Date 对象
            Date date = Date.from(today.atStartOfDay(ZoneId.systemDefault()).toInstant());
            Date fromDate = Date.from(firstDayOfMonth.atStartOfDay(ZoneId.systemDefault()).toInstant());

            // 使用 SimpleDateFormat 格式化 Date 对象
            String toattedDate = sdf.format(date);
            String formattedDate = sdf.format(fromDate);
            from = sdf.parse(formattedDate);
            to = sdf.parse(toattedDate);
        } else {
            from = sdf.parse(dateFrom);
            to = sdf.parse(dateTo);
        }
        req.setFromDate(from);
        req.setToDate(to);
        OapiAttendanceGetcolumnvalResponse rsp = client.execute(req, access_token);


        return rsp;
    }


    /**
     * 获取部门列表
     */
    @ApiLog("获取部门列表")
    @ApiOperation(value = "获取部门列表")
    @GetMapping("deptList")
    public ResponseEntity deptList(Long deptId) {
        List<OapiV2DepartmentListsubResponse.DeptBaseResponse> allDepartments = new ArrayList<>();
        Long rootDeptId = deptId; // 钉钉根部门 ID 一般是 1
        fetchAllDepartments(rootDeptId, allDepartments);
        return ResponseEntity.ok(allDepartments);
    }
    // 假设有一个方法可以调用 API 获取子部门列表
    public static List<OapiV2DepartmentListsubResponse.DeptBaseResponse> getSubDepartments(Long parentDeptId) {
        try {
            // 创建钉钉客户端
            DingTalkClient tokenClient = new DefaultDingTalkClient("https://oapi.dingtalk.com/gettoken");
            // 配置请求参数
            OapiGettokenRequest tokenReq = new OapiGettokenRequest();
            tokenReq.setAppkey("dingtk0peibzdlxdmojz"); // 确保 appKey 已正确初始化
            tokenReq.setAppsecret("NWFAu2fcfKlW3GxlvrGEwMjvJ7jyCPq0Q70XzptUsxE5PYs9cx5wTBWL0wjxKBtf"); // 确保 appSecret 已正确初始化
            tokenReq.setHttpMethod("GET");
            // 执行请求，获取响应
            OapiGettokenResponse tokenRsp = tokenClient.execute(tokenReq);
            String accessToken = tokenRsp.getAccessToken();
            DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/department/listsub");
            OapiV2DepartmentListsubRequest req = new OapiV2DepartmentListsubRequest();
            // 检查 deptId 是否为空
            if (parentDeptId != null) {
                req.setDeptId(parentDeptId);
            }
            OapiV2DepartmentListsubResponse rsp = client.execute(req, accessToken);
            List<OapiV2DepartmentListsubResponse.DeptBaseResponse> result = rsp.getResult();
            // 返回 JSON 响应
            return result;
        } catch (ApiException e) {
            e.printStackTrace(); // 打印错误日志（开发调试用）
            return null;
        } catch (Exception e) {
            e.printStackTrace(); // 打印错误日志（开发调试用）
            return null;
        }
    }


    // 递归获取所有子部门
    public static void fetchAllDepartments(Long parentDeptId, List<OapiV2DepartmentListsubResponse.DeptBaseResponse> allDepts) {
        List<OapiV2DepartmentListsubResponse.DeptBaseResponse> subDepts = getSubDepartments(parentDeptId);
        for (OapiV2DepartmentListsubResponse.DeptBaseResponse dept : subDepts) {
            allDepts.add(dept); // 先添加当前部门
            fetchAllDepartments(dept.getDeptId(), allDepts); // 递归获取子部门
        }
    }


    /**
     * 创建用户
     */
    @ApiLog("创建用户")
    @ApiOperation(value = "创建用户")
    @PostMapping("addUser")
    public ResponseEntity addUser(@RequestBody AddUserDTO addUserDTO) {
        try {
            String token = getToken();
            DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/create");
            OapiV2UserCreateRequest req = new OapiV2UserCreateRequest();
            String name = addUserDTO.getName();
            String mobile = addUserDTO.getMobile();
            boolean hideMobile = addUserDTO.isHideMobile();
            String jobNumber = addUserDTO.getJobNumber();
            String title = addUserDTO.getTitle();
            String email = addUserDTO.getEmail();
            String workPlace = addUserDTO.getWorkPlace();
            String deptIdList = addUserDTO.getDeptIdList();
            Long hiredDate = addUserDTO.getHiredDate();
            req.setName(name);

            req.setDeptIdList(deptIdList);
            req.setEmail(email);
            req.setHideMobile(hideMobile);
            req.setHiredDate(hiredDate);
            req.setJobNumber(jobNumber);
            req.setMobile(mobile);
            req.setTitle(title);
            req.setWorkPlace(workPlace);
            OapiV2UserCreateResponse rsp = client.execute(req, token);
            // 返回 JSON 响应
            return ResponseEntity.ok(rsp);
        } catch (ApiException e) {
            e.printStackTrace(); // 打印错误日志（开发调试用）
            return ResponseEntity.badRequest().body("接口异常，请重试!");
        } catch (Exception e) {
            e.printStackTrace(); // 打印错误日志（开发调试用）
            return ResponseEntity.badRequest().body("接口异常，请重试!");
        }
    }



    /**
     * 更新用户数据
     */
    @ApiLog("更新用户数据")
    @ApiOperation(value = "更新用户数据")
    @PostMapping("updateUser")
    public ResponseEntity updateUser(@RequestBody AddUserDTO addUserDTO) {
        try {
            String token = getToken();
            DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/update");
            OapiV2UserUpdateRequest req = new OapiV2UserUpdateRequest();
            String name = addUserDTO.getName();
            String mobile = addUserDTO.getMobile();
            boolean hideMobile = addUserDTO.isHideMobile();
            String jobNumber = addUserDTO.getJobNumber();
            String title = addUserDTO.getTitle();
            String email = addUserDTO.getEmail();
            String workPlace = addUserDTO.getWorkPlace();
            String deptIdList = addUserDTO.getDeptIdList();
            Long hiredDate = addUserDTO.getHiredDate();
            String userId = addUserDTO.getUserid();
            req.setUserid(userId);
            req.setName(name);
            req.setDeptIdList(deptIdList);
            req.setEmail(email);
            req.setHideMobile(hideMobile);
            req.setHiredDate(hiredDate);
            req.setJobNumber(jobNumber);
            req.setMobile(mobile);
            req.setTitle(title);
            req.setWorkPlace(workPlace);
            OapiV2UserUpdateResponse rsp = client.execute(req, token);
            // 返回 JSON 响应
            return ResponseEntity.ok(rsp);
        } catch (ApiException e) {
            e.printStackTrace(); // 打印错误日志（开发调试用）
            return ResponseEntity.badRequest().body("接口异常，请重试!");
        } catch (Exception e) {
            e.printStackTrace(); // 打印错误日志（开发调试用）
            return ResponseEntity.badRequest().body("接口异常，请重试!");
        }
    }

    /**
     * 查看用户详情
     */
    @ApiLog("查看用户详情")
    @ApiOperation(value = "查看用户详情")
    @GetMapping("selectUserById")
    public ResponseEntity selectUserById(String id) {
        try {
            String token = getToken();
            DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/get");
            OapiV2UserGetRequest req = new OapiV2UserGetRequest();
            req.setUserid(id);
            req.setLanguage("zh_CN");
            OapiV2UserGetResponse rsp = client.execute(req, token);
            // 返回 JSON 响应
            return ResponseEntity.ok(rsp);
        } catch (ApiException e) {
            e.printStackTrace(); // 打印错误日志（开发调试用）
            return ResponseEntity.badRequest().body("接口异常，请重试!");
        } catch (Exception e) {
            e.printStackTrace(); // 打印错误日志（开发调试用）
            return ResponseEntity.badRequest().body("接口异常，请重试!");
        }
    }


    /**
     * 删除部门
     */
    @ApiLog("删除部门")
    @ApiOperation(value = "删除部门")
    @PostMapping("delDept")
    public ResponseEntity delDept(@RequestBody DeptDTO deptDTO) {
        try {
            String token = getToken();
            DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/department/delete");
            OapiV2DepartmentDeleteRequest req = new OapiV2DepartmentDeleteRequest();
            req.setDeptId(deptDTO.getDeptId());
            OapiV2DepartmentDeleteResponse rsp = client.execute(req, token);
            return ResponseEntity.ok(rsp);
        } catch (ApiException e) {
            e.printStackTrace(); // 打印错误日志（开发调试用）
            return ResponseEntity.badRequest().body("接口异常，请重试!");
        } catch (Exception e) {
            e.printStackTrace(); // 打印错误日志（开发调试用）
            return ResponseEntity.badRequest().body("接口异常，请重试!");
        }
    }


    /**
     * 创建部门
     */
    @ApiLog("创建部门")
    @ApiOperation(value = "创建部门")
    @PostMapping("addDept")
    public ResponseEntity addDept(@RequestBody DeptDTO deptDTO) {
        try {
            String token = getToken();
            DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/department/create");
            OapiV2DepartmentCreateRequest req = new OapiV2DepartmentCreateRequest();
            req.setParentId(deptDTO.getParentId());
            req.setName(deptDTO.getName());
            OapiV2DepartmentCreateResponse rsp = client.execute(req, token);
            System.out.println(rsp.getBody());
            return ResponseEntity.ok(rsp);
        } catch (ApiException e) {
            e.printStackTrace(); // 打印错误日志（开发调试用）
            return ResponseEntity.badRequest().body("接口异常，请重试!");
        } catch (Exception e) {
            e.printStackTrace(); // 打印错误日志（开发调试用）
            return ResponseEntity.badRequest().body("接口异常，请重试!");
        }
    }


    /**
     * 修改部门信息
     */
    @ApiLog("修改部门信息")
    @ApiOperation(value = "修改部门信息")
    @PostMapping("updateDept")
    public ResponseEntity updateDept(@RequestBody DeptDTO deptDTO) {
        try {
            String token = getToken();
            DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/department/update");
            OapiV2DepartmentUpdateRequest req = new OapiV2DepartmentUpdateRequest();
            req.setDeptId(deptDTO.getDeptId());
            req.setName(deptDTO.getName());
            req.setParentId(deptDTO.getParentId());
            OapiV2DepartmentUpdateResponse rsp = client.execute(req, token);
            return ResponseEntity.ok("修改成功");
        } catch (ApiException e) {
            e.printStackTrace(); // 打印错误日志（开发调试用）
            return ResponseEntity.badRequest().body("接口异常，请重试!");
        } catch (Exception e) {
            e.printStackTrace(); // 打印错误日志（开发调试用）
            return ResponseEntity.badRequest().body("接口异常，请重试!");
        }
    }


    /**
     * 根据部门id查询数据
     */
    @ApiLog("根据部门id查询数据")
    @ApiOperation(value = "根据部门id查询数据")
    @GetMapping("queryById")
    public ResponseEntity queryById(Long deptId) {
        try {
            String token = getToken();
            DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/department/get");
            OapiV2DepartmentGetRequest req = new OapiV2DepartmentGetRequest();
            req.setDeptId(deptId);
            OapiV2DepartmentGetResponse rsp = client.execute(req, token);
            return ResponseEntity.ok(rsp);
        } catch (ApiException e) {
            e.printStackTrace(); // 打印错误日志（开发调试用）
            return ResponseEntity.badRequest().body("接口异常，请重试!");
        } catch (Exception e) {
            e.printStackTrace(); // 打印错误日志（开发调试用）
            return ResponseEntity.badRequest().body("接口异常，请重试!");
        }
    }


    public <T> T jsonToObject(String json, Class<T> clazz) {
        try {
            ObjectMapper objectMapper = new ObjectMapper();
            return objectMapper.readValue(json, clazz);
        } catch (Exception e) {
            throw new RuntimeException("Error converting JSON to Object: " + e.getMessage(), e);
        }
    }
}
