package com.ruoyi.platform.service.impl;

import com.ruoyi.common.security.utils.SecurityUtils;
import com.ruoyi.platform.service.GitService;
import com.ruoyi.platform.utils.JacksonUtil;
import com.ruoyi.platform.utils.JsonUtils;
import com.ruoyi.platform.utils.NewHttpUtils;
import com.ruoyi.platform.vo.GitProjectVo;
import com.ruoyi.system.api.constant.Constant;
import com.ruoyi.system.api.domain.SysUser;
import com.ruoyi.system.api.model.LoginUser;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import redis.clients.jedis.Jedis;

import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.ruoyi.common.security.utils.SecurityUtils.decrypt;

@Service
public class GitServiceImpl implements GitService {

    @Value("${spring.redis.host}")
    private String redisHost;
    @Value("${spring.redis.port}")
    private Integer redisPort;
    @Value("${git.endpoint}")
    String gitendpoint;
    @Value("${git.clientId}")
    String clientId;
    @Value("${git.clientSecret}")
    String clientSecret;
    @Resource
    private NewHttpUtils httpUtils;
    private static final Logger log = LoggerFactory.getLogger(GitServiceImpl.class);

    @Override
    public String login(String username, String password) {
        // 构建请求参数
        Map<String, Object> params = new HashMap<>();
        params.put("grant_type", "password");
        params.put("username", username);
        params.put("password", decrypt(password));
        params.put("client_id", clientId);
        params.put("client_secret", clientSecret);
        try {
            // 发送POST请求
            String req = httpUtils.sendPost(gitendpoint + "/oauth/token", null, JsonUtils.mapToJson(params));
            // 解析响应JSON
            if (StringUtils.isEmpty(req)) {
                throw new RuntimeException("gitlink用户信息出错");
            }
            // 将响应的JSON字符串转换为Map对象
            Map<String, Object> runResMap = JsonUtils.jsonToMap(req);
            // 提取access_token
            // 提取access_token
            String accessToken = (String) runResMap.get("access_token");

            //通过access_token获取用户信息
            String userReq = httpUtils.sendGetWithToken(gitendpoint + "/api/users/get_user_info.json", null, accessToken);
            if (StringUtils.isEmpty(userReq)) {
                throw new RuntimeException("gitlink用户信息出错");
            }
            // 将access_token存入Redis
            Jedis jedis = new Jedis(redisHost, redisPort);
            jedis.set(username + "_gitToken", accessToken);
            jedis.set(username + "_gitUserInfo", userReq);
            return accessToken;
        } catch (Exception e) {
            throw new RuntimeException("gitlink用户信息出错");
        }
    }

    public String checkoutToken() {
        Jedis jedis = new Jedis(redisHost, redisPort);
        LoginUser loginUser = SecurityUtils.getLoginUser();
        String ci4sUsername = loginUser.getUsername();
        String token = jedis.get(ci4sUsername + "_gitToken");
        String gitLinkPassword = loginUser.getSysUser().getOriginPassword();

        if (StringUtils.isEmpty(token)) {
            login(ci4sUsername, gitLinkPassword);
            token = jedis.get(ci4sUsername + "_gitToken");
        } else {
            try {
                Map userInfo = getUserInfo(token);
                if (userInfo == null || (userInfo.get("status") != null && 401 == (Integer) userInfo.get("status"))) {
                    login(ci4sUsername, gitLinkPassword);
                    token = jedis.get(ci4sUsername + "_gitToken");
                }
            } catch (Exception e) {
                throw new RuntimeException(e.getMessage());
            }
        }
        return token;
    }

    @Override
    public Map createProject(String token, GitProjectVo gitProjectVo) throws Exception {
        String userReq = httpUtils.sendPostWithToken(gitendpoint + "/api/projects.json", null, token, JsonUtils.objectToJson(gitProjectVo));
        return JsonUtils.jsonToMap(userReq);
    }

    @Override
    public void createBranch(String token, String owner, String projectName, String branchName, String oldBranchName) throws Exception {
        //https://www.gitlink.org.cn/api/v1/fanshuai/testdssa8755/branches.json
//        {
//            "new_branch_name": "SsS",
//                "old_branch_name": "master"
//        }
        String createBranchUrl = gitendpoint + "/api/v1/" + owner + "/" + projectName + "/branches.json";
        Map<String, Object> resMap = new HashMap<>();
        resMap.put("new_branch_name", branchName);
        resMap.put("old_branch_name", oldBranchName);
        String req = httpUtils.sendPostWithToken(createBranchUrl, null, token, JsonUtils.objectToJson(resMap));
        System.out.println(req);
    }

    @Override
    public void createTopic(String token, Integer id, String topicName) throws Exception {
        // https://www.gitlink.org.cn/api/v1/project_topics.json
        Map<String, Object> resMap = new HashMap<>();
        resMap.put("project_id", id);
        resMap.put("name", topicName);
        String req = httpUtils.sendPostWithToken(gitendpoint + "/api/v1/project_topics.json", null, token, JsonUtils.objectToJson(resMap));
    }

    @Override
    public List<Map<String, Object>> getBrancheList(String token, String owner, String projectName) throws Exception {
        String req = httpUtils.sendGetWithToken(gitendpoint + "/api/v1/" + owner + "/" + projectName + "/branches/all.json", null, token);
        // 解析响应JSON
        if (StringUtils.isEmpty(req)) {
            throw new RuntimeException("终止响应内容为空");
        }
        // 将响应的JSON字符串转换为List<Map>对象
        List<Map<String, Object>> mapList = JacksonUtil.parseJSONStr2MapList(req);
        return mapList;
    }

    @Override
    public void deleteProject(String token, String owner, String projectName) throws Exception {
        httpUtils.sendDeleteWithToken(gitendpoint + "/api/" + owner + "/" + projectName + ".json", null, token, null);
    }

    @Override
    public void deleteBranch(String token, String owner, String projectName, String branchName, String localPath) throws Exception {
        try (Git git = Git.open(new File(localPath))) {
            git.checkout().setName("master").call();
            git.branchDelete().setBranchNames(branchName).setForce(true).call();
        } catch (IOException | GitAPIException e) {
            log.error("Exception occurred while creating local branch based on master", e);
        }
        httpUtils.sendDeleteWithToken(gitendpoint + "/api/v1/" + owner + "/" + projectName + "/branches/" + branchName + ".json", null, token, null);
    }

    @Override
    public Map getUserInfo(String token) throws Exception {
        String userReq = httpUtils.sendGetWithToken(gitendpoint + "/api/users/get_user_info.json", null, token);
        if (StringUtils.isEmpty(userReq)) {
            return null;
        }
        Map<String, Object> runResMap = JsonUtils.jsonToMap(userReq);
        return runResMap;
    }

    @Override
    public Map getProjectDetail(String owner, String identifier, String token) throws Exception {
        String userReq = httpUtils.sendGetWithToken(gitendpoint + "/api/" + owner + "/" + identifier + "/detail.json", null, token);
        if (StringUtils.isEmpty(userReq)) {
            return null;
        }
        Map<String, Object> runResMap = JsonUtils.jsonToMap(userReq);
        return runResMap;
    }

    @Override
    public void createUser(SysUser sysUser) throws Exception {
        String token = checkoutToken();
        Map<String, Object> resMap = new HashMap<>();
        resMap.put("phone", sysUser.getPhonenumber());
        resMap.put("email", sysUser.getEmail());
        resMap.put("username", sysUser.getUserName());
        resMap.put("password", sysUser.getPassword());
        resMap.put("password_confirmation", sysUser.getPassword());
        httpUtils.sendPostWithToken(gitendpoint + "/api/accounts/remote_register.json", null, token, JsonUtils.objectToJson(resMap));
    }

    @Override
    public void resetPwd(SysUser sysUser) throws Exception {
        String token = login(sysUser.getUserName(), sysUser.getOriginPassword());
        Map<String, Object> resMap = new HashMap<>();
        resMap.put("login", sysUser.getUserName());
        resMap.put("password", sysUser.getPassword());
        resMap.put("new_password_repeat", sysUser.getPassword());
        resMap.put("old_password", decrypt(sysUser.getOriginPassword()));
        httpUtils.sendPostWithToken(gitendpoint + "/api/accounts/change_password.json", null, token, JsonUtils.objectToJson(resMap));
    }

    @Override
    public void resetEmail(SysUser sysUser) throws Exception {
        String token = login(sysUser.getUserName(), sysUser.getOriginPassword());
        Map<String, Object> resMap = new HashMap<>();
        resMap.put("email", sysUser.getEmail());
        resMap.put("password", decrypt(sysUser.getOriginPassword()));
        resMap.put("code", Constant.Code);
        httpUtils.sendPatchWithToken(gitendpoint + "/api/v1/" + sysUser.getUserName() + "/update_email.json", null, token, JsonUtils.objectToJson(resMap));
    }

    @Override
    public void resetPhoneNum(SysUser sysUser) throws Exception {
        String token = login(sysUser.getUserName(), sysUser.getOriginPassword());
        Map<String, Object> resMap = new HashMap<>();
        resMap.put("phone", sysUser.getPhonenumber());
        resMap.put("password", decrypt(sysUser.getOriginPassword()));
        resMap.put("code", Constant.Code);
        httpUtils.sendPatchWithToken(gitendpoint + "/api/v1/" + sysUser.getUserName() + "/update_phone.json", null, token, JsonUtils.objectToJson(resMap));
    }

    @Override
    public void deleteUser(SysUser sysUser) throws Exception {
        String token = login(sysUser.getUserName(), sysUser.getOriginPassword());
        String result = httpUtils.sendPostWithToken(gitendpoint + "/api/v1/" + sysUser.getUserName() + "/check_user_can_delete.json", null, token, null);
        Map<String, Object> resultMap = JsonUtils.jsonToMap(result);
        if ((boolean) resultMap.get("can_delete")) {
            Map<String, Object> resMap = new HashMap<>();
            resMap.put("memo", "用户注销");
            resMap.put("password", decrypt(sysUser.getOriginPassword()));
            httpUtils.sendDeleteWithToken(gitendpoint + "/api/v1/" + sysUser.getUserName() + ".json", null, token, JsonUtils.objectToJson(resMap));
        } else {
            throw new Exception("用户不可删除：" + resultMap.get("message"));
        }
    }
}
