package com.xiang.xservice.application.script.glados.service;

import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.TypeReference;
import com.google.common.collect.Maps;
import com.xiang.xmc.service.http.helper.BaseHttpHelp;
import com.xiang.xmc.service.http.helper.HttpHelperFactory;
import com.xiang.xservice.application.script.glados.common.GladosConstants;
import com.xiang.xservice.application.script.glados.common.URLConstants;
import com.xiang.xservice.application.script.glados.entity.GladosRunLog;
import com.xiang.xservice.application.script.glados.entity.resp.CheckInResp;
import com.xiang.xservice.application.script.glados.entity.resp.GLaDOSResponse;
import com.xiang.xservice.application.script.glados.repository.GladosMapper;
import com.xiang.xservice.application.script.xb.entity.pojo.User;
import com.xiang.xservice.basic.utils.HttpUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @Author: xiang
 * @Date: 2025-05-08 14:38
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class GLaDOSServiceImpl implements GLaDOSService{

    private final GladosMapper gladosMapper;

    private final DingTalkScriptGladosService dingTalkService;

    private final BaseHttpHelp httpHelp = HttpHelperFactory.createSimpleHttp();

    /**
     * 签到
     */
    @Override
    public String checkIn() {

        List<User> users = gladosMapper.listAllUser();
        if (CollectionUtils.isEmpty(users)) {
            return "user is empty";
        }
        StringBuffer sb = new StringBuffer();
        users.parallelStream().forEach(user -> {
            try {
                for (int i = 0; i < 3; i++) {
                    if (checkIn(user, sb)) {
                        break;
                    }
                    try {
                        Thread.sleep(10000);
                    } catch (InterruptedException e) {
                        log.error("线程暂停10s失败");
                    }
                }
            } catch (Exception e) {
                log.error("签到失败，", e);
            }
        });
        return sb.toString();
    }

    @Override
    public void checkInV2() {
        List<User> users = gladosMapper.listAllUser();
        if (CollectionUtils.isEmpty(users)) {
            return;
        }
        for (User user : users) {
            try {
                for (int i = 0; i < 3; i++) {
                    if (checkInV2(user)) {
                        break;
                    }
                    try {
                        Thread.sleep(10000);
                    } catch (InterruptedException e) {
                        log.error("线程暂停10s失败");
                    }
                }
            } catch (Exception e) {
                log.error("签到失败，", e);
            }
        }
    }

    public boolean checkInV2(User user) {
        Map<String, String> header = Maps.newHashMap();
        header.put("Cookie", user.getCookie());

        String response = null;

        try {
            response = httpHelp.doPost(URLConstants.GLADOS_CHECK_IN_URL, header, GladosConstants.GLADOS_CHECK_IN_BODY);
        } catch (Exception e) {
            log.error("http请求异常:{}", user.getEmail());
            return false;
        }
        if (org.apache.commons.lang3.StringUtils.isBlank(response)) {
            return false;
        }

        GLaDOSResponse<CheckInResp> gLaDOSResponse = JSONObject.parseObject(response, new TypeReference<GLaDOSResponse<CheckInResp>>() {
        });
        if (Objects.isNull(gLaDOSResponse)) {
            return false;
        }

        if (0 == gLaDOSResponse.getCode()) {
            // 成功请求
            if (Objects.nonNull(gLaDOSResponse.getPoints()) && 0 != gLaDOSResponse.getPoints()) {
                // 签到成功
                dingTalkService.sendScriptMsg("[时间：" + LocalDateTime.now() + "] 用户: " +
                        user.getEmail() + "签到成功，获得积分：" + gLaDOSResponse.getPoints());
                GladosRunLog build = GladosRunLog.builder().time(LocalDateTime.now()).status(1).code(Integer.valueOf(gLaDOSResponse.getCode().toString())).response(response).user(user.getEmail()).userId(user.getId()).build();
                gladosMapper.insertScriptRunLog(build);
                return Boolean.TRUE;
            }
        }

        if (gLaDOSResponse.getMessage().contains("Repeats")) {
            if (!CollectionUtils.isEmpty(gLaDOSResponse.getList())) {
                dingTalkService.sendScriptMsg("用户:" + user.getEmail() + "当前已签到。结果：" + gLaDOSResponse.getList().get(0));
                GladosRunLog build = GladosRunLog.builder().time(LocalDateTime.now()).status(1).code(Integer.valueOf(gLaDOSResponse.getCode().toString())).response(response).user(user.getEmail()).userId(user.getId()).build();
                gladosMapper.insertScriptRunLog(build);
                return true;
            }
        }

        if (-2 == gLaDOSResponse.getCode()) {
            log.warn("签到失败，用户:{}, cookie过期:{}", user.getEmail(), gLaDOSResponse.getMessage());
            String message = "[时间：" + LocalDateTime.now() + "] 用户: " + user.getEmail() + "，签到消息: " + gLaDOSResponse.getMessage() + "手动请求：http://general.xiangtech.xyz:30026/system/glados/checkIn";
            try {
                dingTalkService.sendScriptMsg(message);
                return true;
            } catch (Exception e) {
                log.error("发送钉钉消息失败", e);
            }
        }

        // 请求异常
        dingTalkService.sendScriptMsg("用户:" + user.getEmail() + "请求异常，响应结果:" + gLaDOSResponse.getMessage());
        GladosRunLog build = GladosRunLog.builder().time(LocalDateTime.now()).status(0).code(Integer.valueOf(gLaDOSResponse.getCode().toString())).response(response).user(user.getEmail()).userId(user.getId()).build();
        gladosMapper.insertScriptRunLog(build);
        return false;
    }

    private boolean checkIn(User user, StringBuffer sb) {

        Map<String, String> header = Maps.newHashMap();
        header.put("Cookie", user.getCookie());

        String response = null;

        try {
            response = HttpUtils.doPost(URLConstants.GLADOS_CHECK_IN_URL, header, GladosConstants.GLADOS_CHECK_IN_BODY);
        } catch (Exception e) {
            log.error("http do post error, header:{}, jsonParams:{}", JSONObject.toJSONString(header), GladosConstants.GLADOS_CHECK_IN_BODY, e);
        }
        if (StringUtils.isEmpty(response)) {
            log.error("http do post error, header:{}, jsonParams:{}", JSONObject.toJSONString(header), GladosConstants.GLADOS_CHECK_IN_BODY);
        }
        GLaDOSResponse gLaDOSResponse =JSONObject.parseObject(response, GLaDOSResponse.class);
        if (Objects.nonNull(gLaDOSResponse)) {
            log.info("http do post success, response:{}", response);

            // 成功签到记录
            if (0 == gLaDOSResponse.getCode()) {
                if (Objects.nonNull(gLaDOSResponse.getPoints())) {
                    log.info("签到成功, 签到积分:{}, 签到消息:{}", gLaDOSResponse.getPoints(), gLaDOSResponse.getMessage());
                    sb.append(user.getEmail()).append("签到成功，获得积分：").append(gLaDOSResponse.getPoints()).append("\n");
                    try {
                        dingTalkService.sendScriptMsg("[时间：" + LocalDateTime.now() + "] 用户: " +
                                user.getEmail() + "签到成功，获得积分：" + gLaDOSResponse.getPoints());
                    } catch (Exception e) {
                        log.error("发送钉钉消息失败", e);
                    }
                    GladosRunLog build = GladosRunLog.builder().time(LocalDateTime.now()).status(1).code(Integer.valueOf(gLaDOSResponse.getCode().toString())).response(response).user(user.getEmail()).userId(user.getId()).build();
                    gladosMapper.insertScriptRunLog(build);
                    return Boolean.TRUE;
                } else {
                    log.info("签到异常, 签到消息:{}", gLaDOSResponse.getMessage());
                    sb.append(user.getEmail()).append("签到异常，消息：").append(gLaDOSResponse.getMessage());
                    GladosRunLog build = GladosRunLog.builder().time(LocalDateTime.now()).status(0).code(Integer.valueOf(gLaDOSResponse.getCode().toString())).response(response).user(user.getEmail()).userId(user.getId()).build();
                    gladosMapper.insertScriptRunLog(build);
                    return Boolean.FALSE;
                }
            }

            // 重复签到，表示当日签到成功
            if (1 == gLaDOSResponse.getCode()) {
                log.warn("签到失败，重复签到，用户:{}, 签到消息:{}", user.getEmail(), gLaDOSResponse.getMessage());
                sb.append(user).append("签到失败，重复签到，用户:").append(user).append("，签到消息:").append(gLaDOSResponse.getMessage());
                try {
                    dingTalkService.sendScriptMsg("[时间：" + LocalDateTime.now() + "] 用户: " +
                            user.getEmail() + "当天已经签到成功！获得积分" + gLaDOSResponse.getList().get(0));
                } catch (Exception e) {
                    log.error("发送钉钉消息失败", e);
                }
                GladosRunLog build = GladosRunLog.builder().time(LocalDateTime.now()).status(1).code(Integer.valueOf(gLaDOSResponse.getCode().toString())).response(response).user(user.getEmail()).userId(user.getId()).build();
                gladosMapper.insertScriptRunLog(build);
                return Boolean.TRUE;
            }

            // cookie过期
            if (-2 == gLaDOSResponse.getCode()) {
                log.warn("签到失败，用户:{}, cookie过期:{}", user.getEmail(), gLaDOSResponse.getMessage());
                String message = "[时间：" + LocalDateTime.now() + "] 用户: " + user.getEmail() + "，签到消息: " + gLaDOSResponse.getMessage();
                try {
                    dingTalkService.sendScriptMsg(message);
                } catch (Exception e) {
                    log.error("发送钉钉消息失败", e);
                }
            }

            // 其余的异常情况
            if (gLaDOSResponse.getCode() != 1) {
                log.warn("签到异常，返回的消息:{}", gLaDOSResponse.getMessage());
                sb.append(user.getEmail()).append("签到异常，返回的消息:").append(gLaDOSResponse.getMessage()).append("\n");
            }
            GladosRunLog build = GladosRunLog.builder().time(LocalDateTime.now()).status(0).code(Integer.valueOf(gLaDOSResponse.getCode().toString())).response(response).user(user.getEmail()).userId(user.getId()).build();
            gladosMapper.insertScriptRunLog(build);
            return Boolean.FALSE;
        } else {
            try {
                String mes = "[时间：" + LocalDateTime.now() + "] 用户: " + user.getEmail() + "，签到异常，请求结果为空。";
                dingTalkService.sendScriptMsg(mes);
            } catch (Exception e) {
                log.error("发送钉钉消息失败", e);
            }
        }
        GladosRunLog build = GladosRunLog.builder().time(LocalDateTime.now()).status(0).response(response).user(user.getEmail()).userId(user.getId()).build();
        gladosMapper.insertScriptRunLog(build);
        return Boolean.FALSE;
    }
}
