package com.template.controller;


import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.seewo.open.sdk.DefaultSeewoClient;
import com.seewo.open.sdk.SeewoClient;
import com.seewo.open.sdk.auth.Account;
import com.template.annotation.DESRespondSecret;
import com.template.api.SmartAttendanceControllerAPI;
import com.template.common.utils.*;
import com.template.config.ControlConfig;
import com.template.config.SeewoConfig;
import com.template.model.enumModel.eAttendanceStatu;
import com.template.model.enumModel.eIdentityStatu;
import com.template.model.enumModel.eXwApproveStatu;
import com.template.model.pojo.*;
import com.template.model.request.askForLeaveRequest;
import com.template.model.result.CommonResult;
import com.template.model.seewo.PersonalLeaveListSchoolPeriodRecordsParam;
import com.template.model.seewo.PersonalLeaveListSchoolPeriodRecordsRequest;
import com.template.model.seewo.PersonalLeaveListSchoolPeriodRecordsResult;
import com.template.model.vo.*;
import com.template.services.SmartAttendanceService;
import com.template.services.SmartUserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindingResult;

import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

import static com.template.common.utils.AesTestOne.decrypt;

/**
 * <p>
 * 楼栋表 前端控制器
 * </p>
 *
 * @author ceshi
 * @since 2023-12-25
 */
@RestController
//返回参数加密注解
@DESRespondSecret
public class SmartAttendanceController implements SmartAttendanceControllerAPI {
    private static Logger logger = LoggerFactory.getLogger(SmartAttendanceController.class);

    @Resource
    private SeewoConfig seewoConfig;
    @Resource
    private ControlConfig controlConfig;
    @Autowired
    private SmartUserService smartUserService;
    @Autowired
    private SmartAttendanceService smartAttendanceService;


    @Override
    @DESRespondSecret(validated = true)
    public CommonResult insertSmartAttendance(SmartAttendance smartApply, BindingResult bindingResult) {
        return null;
    }

    @Override
    @DESRespondSecret(validated = true)
    public CommonResult updateSmartAttendanceById(SmartAttendance ra, BindingResult bindingResult) {
        return null;
    }

    @Override
    @DESRespondSecret(validated = true)
    public CommonResult queryPageSmartAttendances(int currentPage, int pageCount, String name) {
        return null;
    }

    @Override
    @DESRespondSecret(validated = true)
    public CommonResult deleteSmartAttendanceById(int id) {
        return null;
    }

    @Override
    @DESRespondSecret(validated = true)
    public CommonResult queryLeaveRecords() {
        int findPageSize = 20;

        PersonalLeaveListSchoolPeriodRecordsResult result = getXwAttendance(TimeExchange.getDate(), TimeExchange.getDate(), 1, findPageSize);
        if (result == null) {
            return CommonResult.fail("当天不存在请假数据！");
        }

        if (!result.getResponseBody().getCode().equals("000000")) {
            return CommonResult.fail(result.getResponseBody().getMessage());
        }

        List<SmartAttendance> attendances = new ArrayList<>();
        for (int i = 0; i < result.getResponseBody().getData().getTotalCount(); i++) {
            if (result.getResponseBody().getData().getResult().get(i).getLeaveStatus().intValue() == eXwApproveStatu.Passed.getValue()) {
                SmartAttendance attendance = new SmartAttendance();
                attendance.setXwuid(result.getResponseBody().getData().getResult().get(i).getUid());
                attendance.setUserUid(result.getResponseBody().getData().getResult().get(i).getUserUid());
                attendance.setXwUserName(result.getResponseBody().getData().getResult().get(i).getUserName());
                attendance.setReason(result.getResponseBody().getData().getResult().get(i).getReason());
                attendance.setStartTime(TimeExchange.StringToDate(result.getResponseBody().getData().getResult().get(i).getStartTime(), "yyyy-MM-dd HH:mm:ss"));
                attendance.setEndTime(TimeExchange.StringToDate(result.getResponseBody().getData().getResult().get(i).getEndTime(), "yyyy-MM-dd HH:mm:ss"));
                attendance.setInitiateTime(TimeExchange.StringToDate(result.getResponseBody().getData().getResult().get(i).getCreateTime(), "yyyy-MM-dd HH:mm:ss"));
                attendance.setInitiateXwuid(result.getResponseBody().getData().getResult().get(i).getApplyUserUid());
                attendance.setInitiateXwname(result.getResponseBody().getData().getResult().get(i).getApplyUserName());
                attendance.setInitiateXwphone(result.getResponseBody().getData().getResult().get(i).getApplyUserPhone());
                attendance.setStatus(eAttendanceStatu.AskLeave.getValue());
                attendances.add(attendance);
            }
        }
        //如果总条数大于第二条 那说明还有第二页
        if (result.getResponseBody().getData().getTotalCount().intValue() > result.getResponseBody().getData().getTotalCount().intValue()) {
            int totalCount = result.getResponseBody().getData().getTotalCount().intValue();
            int pageSize = result.getResponseBody().getData().getPageSize().intValue();
            int totalPage = (totalCount + pageSize - 1) / pageSize;
            for (int i = 2; i <= totalPage; i++) {
                PersonalLeaveListSchoolPeriodRecordsResult nextResult = getXwAttendance(TimeExchange.getDate(), TimeExchange.getDate(), i, findPageSize);
                if (nextResult == null) {
                    return CommonResult.fail("当天不存在请假数据！");
                }

                if (!nextResult.getResponseBody().getCode().equals("000000")) {
                    return CommonResult.fail(result.getResponseBody().getMessage());
                }
                for (int j = 0; j < result.getResponseBody().getData().getTotalCount(); j++) {
                    if (result.getResponseBody().getData().getResult().get(j).getLeaveStatus().intValue() == eXwApproveStatu.Passed.getValue()) {
                        SmartAttendance attendance = new SmartAttendance();
                        attendance.setXwuid(result.getResponseBody().getData().getResult().get(j).getUid());
                        attendance.setUserUid(result.getResponseBody().getData().getResult().get(j).getUserUid());
                        attendance.setXwUserName(result.getResponseBody().getData().getResult().get(j).getUserName());
                        attendance.setReason(result.getResponseBody().getData().getResult().get(j).getReason());
                        attendance.setStartTime(TimeExchange.StringToDate(result.getResponseBody().getData().getResult().get(j).getStartTime(), "yyyy-MM-dd HH:mm:ss"));
                        attendance.setEndTime(TimeExchange.StringToDate(result.getResponseBody().getData().getResult().get(j).getEndTime(), "yyyy-MM-dd HH:mm:ss"));
                        attendance.setInitiateTime(TimeExchange.StringToDate(result.getResponseBody().getData().getResult().get(j).getCreateTime(), "yyyy-MM-dd HH:mm:ss"));
                        attendance.setInitiateXwuid(result.getResponseBody().getData().getResult().get(j).getApplyUserUid());
                        attendance.setInitiateXwname(result.getResponseBody().getData().getResult().get(j).getApplyUserName());
                        attendance.setInitiateXwphone(result.getResponseBody().getData().getResult().get(j).getApplyUserPhone());
                        attendance.setStatus(eAttendanceStatu.AskLeave.getValue());
                        attendances.add(attendance);
                    }
                }
            }
        }
        //获取当天的请假数据中是否存在重复的
        List<SmartAttendance> oldAttendances = smartAttendanceService.queryExistAttendances(TimeExchange.getStartDate(), TimeExchange.getEndDate());
        if (oldAttendances != null && oldAttendances.size() > 0) {
            if (attendances != null && attendances.size() > 0) {
                for (SmartAttendance oldAttendance : oldAttendances) {
                    attendances = attendances.stream().filter(e -> !e.getXwuid().equals(oldAttendance.getXwuid())).collect(Collectors.toList());
                }
            }
        }

        //新增请假数据
        if (attendances != null && attendances.size() > 0) {
            //获取用户数据
            List<String> xwuids = attendances.stream().map(SmartAttendance::getUserUid).collect(Collectors.toList());
            List<SmartUser> users = smartUserService.getSmartUserByxwuids(xwuids);
            if (users != null && users.size() > 0) {
                for (SmartAttendance attendance : attendances) {
                    Optional<SmartUser> user = users.stream().filter(e -> e.getXwStudentUid().equals(attendance.getUserUid())).findFirst();
                    if (user != null && user.isPresent()) {
                        attendance.setUserId(user.get().getId());
                        attendance.setClassId(user.get().getSchoolClass());
                    }
                }
            }

            boolean insertResult = smartAttendanceService.insertAttendanceBatch(attendances);
            if (!insertResult) {
                return CommonResult.fail("请假数据获取失败");
            }
        }

        return CommonResult.ok("操作成功");
    }

    @Override
    @DESRespondSecret(validated = true)
    public CommonResult queryAttendanceList() {
        List<HomePageAttendanceVo> result = new ArrayList<>();
        Date startMonth = TimeExchange.getToMonthBeginDate(TimeExchange.DateToString(new Date()));
        Date endMonth = TimeExchange.getToMonthEndDate(TimeExchange.DateToString(new Date()));

        List<SmartAttendance> datas = smartAttendanceService.queryAttendanceList(startMonth, endMonth);

        if (datas == null) {
            return CommonResult.ok(result);
        }

        List<Integer> status = eAttendanceStatu.attendanceStatus();
        for (int statu : status) {
            HomePageAttendanceVo data = new HomePageAttendanceVo();
            data.setName(eAttendanceStatu.stringOf(statu));
            //百分比
            long count = datas.stream().filter(e -> e.getStatus().intValue() == statu).count();
            if (count == 0) {
                data.setProportion(0.0);
            } else {
                double restData = (double) count / datas.size() * 100;
                data.setProportion(restData);
            }
            result.add(data);
        }

        return CommonResult.ok(result);
    }

    @Override
    public CommonResult askForLeave(askForLeaveRequest request, BindingResult bindingResult) throws Exception {

        SmartStudentVo student = smartUserService.querySmartStudentById(request.getId());
        if (student == null) {
            return CommonResult.fail("学生数据无效，请假失败！");
        }

        if (student.getIdentityId().intValue() != eIdentityStatu.Student.getValue()) {
            return CommonResult.fail("当前用户身份不是学生，无法请假！");
        }

        String reason = request.getReason() == null ? "学生请假" : request.getReason();

        //region 学生请假
        String appId = controlConfig.getAppId();
        String schoolno = controlConfig.getSchoolCode();
        String timestamp = TimeExchange.DateNowTimeStamo();
        String appSecret = controlConfig.getAppSecret();
        String url = controlConfig.getUrl() + "student/addleavebill";

        JSONObject jsonobject = new JSONObject();
        jsonobject.put("appid", appId);
        String str = "{\"student_no\":\"" + student.getBsStudentNo() + "\",\"grade_no\":\"" + student.getBsGradeNo() + "\",\"classtab_no\":\"" + student.getBsClassNo() + "\",\"leavebill_content\":\"" + reason + "\",\"leavebill_begindate\":\"" + request.getStartTime() + "\",\"leavebill_enddate\":\"" + request.getEndTime() + "\",\"leavebill_remark\":\"" + "" + "\"}";
        String aesStr = URLEncoder.encode(AesTestOne.encrypt(str, controlConfig.getAppSecret()), "UTF-8");
        jsonobject.put("data", aesStr);
        jsonobject.put("schoolno", schoolno);
        jsonobject.put("timestamp", timestamp);

        String md5Str = "appid=" + appId + "&data={\"student_no\":\"" + student.getBsStudentNo() + "\",\"grade_no\":\"" + student.getBsGradeNo()  + "\",\"classtab_no\":\"" + student.getBsClassNo() + "\",\"leavebill_content\":\"" + reason + "\",\"leavebill_begindate\":\"" + request.getStartTime()  + "\",\"leavebill_enddate\":\"" + request.getEndTime() + "\",\"leavebill_remark\":\"" + "" + "\"}" + "&schoolno=" + schoolno + "&timestamp=" + timestamp + "&key=" + appSecret;
        String sign = CommonUtil.MD5(md5Str);
        //sign签名
        jsonobject.put("sign", sign);

        //返回的结果中 code为1表示成功
        String bsResult = RequestUtils.httpPost(url, jsonobject.toJSONString());

        ObjectMapper objectMapper = new ObjectMapper();
        BsLeaveVo leave = objectMapper.readValue(bsResult, BsLeaveVo.class);

        if (!bsResult.contains("添加成功")) {
            return CommonResult.fail(leave.getMsg());
        }

        // URL解码
        String decodedUrl = URLDecoder.decode(leave.getData(), "UTF-8");

        BsLeaveNoVo leaveNo = objectMapper.readValue(decrypt(decodedUrl, controlConfig.getAppSecret()), BsLeaveNoVo.class);

        return CommonResult.ok("200", "操作成功", leaveNo.getLeavebill_no());
        //endregion

    }

    public PersonalLeaveListSchoolPeriodRecordsResult getXwAttendance(String startDate, String endDate, Integer currentPage, Integer pageSize) {
        //初始化客户端
        SeewoClient seewoClient = new DefaultSeewoClient(new Account(seewoConfig.getAppId(), seewoConfig.getAppSecret()));
        PersonalLeaveListSchoolPeriodRecordsParam param = new PersonalLeaveListSchoolPeriodRecordsParam();
        //请求体，MimeType为 application/json
        PersonalLeaveListSchoolPeriodRecordsParam.RequestBody requestBody = PersonalLeaveListSchoolPeriodRecordsParam.RequestBody.builder()
                .build();
        param.setRequestBody(requestBody);
        //query
        PersonalLeaveListSchoolPeriodRecordsParam.Query query = PersonalLeaveListSchoolPeriodRecordsParam.Query.builder()
                .schoolUid(seewoConfig.getSchoolId())//学校ID
                .startDate(startDate)//开始日期
                .endDate(endDate)//结束日期
                .page(currentPage)//当前页
                .pageSize(pageSize)//分页条数
                .appId(seewoConfig.getAppId())
                .build();
        requestBody.setQuery(query);
        param.setRequestBody(requestBody);
        PersonalLeaveListSchoolPeriodRecordsRequest request = new PersonalLeaveListSchoolPeriodRecordsRequest(param);
        logger.info("入参：" + request);
        //如果想要调用沙箱环境，请通过设置 request 对象的 serverUrl 属性，如：
        //request.setServerUrl("https://openapi.test.seewo.com")
        //执行请求，如果想获取到com.seewo.open.sdk.HttpResponse对象，请调用 seewoClient.execute 方法
        PersonalLeaveListSchoolPeriodRecordsResult result = seewoClient.invoke(request);
        logger.info("出参：" + result);


        return result;
    }

}

