package com.microservices.pms.common.service.impl;

import com.alibaba.fastjson2.JSONArray;
import com.microservices.common.core.constant.SecurityConstants;
import com.microservices.common.core.constant.UserConstants;
import com.microservices.common.core.enums.UserIdentityStatus;
import com.microservices.common.core.exception.ServiceException;
import com.microservices.common.core.utils.StringUtils;
import com.microservices.common.core.web.domain.BaseEntity;
import com.microservices.common.httpClient.util.GitLinkRequestHelper;
import com.microservices.common.security.utils.SecurityUtils;
import com.microservices.pms.common.service.IPmsCommonService;
import com.microservices.pms.enterprise.domain.PmsEnterprise;
import com.microservices.pms.enterprise.domain.vo.GitLinkUserSimpleInfoVo;
import com.microservices.pms.enterprise.domain.vo.GitlinkOrganizationTeamVo;
import com.microservices.pms.enterprise.service.IPmsEnterpriseService;
import com.microservices.pms.project.domain.vo.BaseEntityVo;
import com.microservices.pms.utils.PmsGitLinkRequestUrl;
import com.microservices.pms.utils.PmsUtils;
import com.microservices.system.api.RemoteDeptService;
import com.microservices.system.api.RemoteFileService;
import com.microservices.system.api.RemoteUserService;
import com.microservices.system.api.domain.*;
import com.microservices.system.api.utils.FeignUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 项目管理企业Service业务层处理
 *
 * @author otto
 * @date 2023-10-10
 */
@Service
public class PmsCommonServiceImpl implements IPmsCommonService {
    private static final Logger logger = LoggerFactory.getLogger(PmsCommonServiceImpl.class);
    @Autowired
    private RemoteFileService remoteFileService;
    @Autowired
    private RemoteUserService remoteUserService;
    @Autowired
    private GitLinkRequestHelper gitLinkRequestHelper;
    @Lazy
    @Autowired
    private IPmsEnterpriseService pmsEnterpriseService;

    @Autowired
    private RemoteDeptService remoteDeptService;

    @Override
    public Long getOrgTeamIdByAuthorize(Long orgId, String authorize) {
        List<GitlinkOrganizationTeamVo> gitlinkOrganizationTeamVoList = getAllGitlinkOrgTeams(orgId);
        return gitlinkOrganizationTeamVoList
                .stream()
                .filter(x -> authorize.equals(x.getAuthorize()))
                .map(GitlinkOrganizationTeamVo::getId)
                .findFirst()
                .orElse(null);
    }

    @Override
    public List<GitlinkOrganizationTeamVo> getAllGitlinkOrgTeams(Long orgId) {
        return gitLinkRequestHelper.getAllDataByPage(
                PmsGitLinkRequestUrl.TEAMS_BY_ORGANIZATION_URL(orgId), "teams", GitlinkOrganizationTeamVo.class
        );
    }

    @Override
    public List<GitLinkUserSimpleInfoVo> getAllGitlinkUsersByOrgTeam(String orgIdentify, Long teamId) {
        List<GitLinkUserSimpleInfoVo> gitLinkUserSimpleInfoVoList = new ArrayList<>();
        JSONArray allData = gitLinkRequestHelper.getAllDataByPage(
                PmsGitLinkRequestUrl.USER_LIST_BY_ORGANIZATION_TEAM_URL(orgIdentify, teamId), "team_users"
        );
        for (int i = 0; i < allData.size(); i++) {
            gitLinkUserSimpleInfoVoList.add(new GitLinkUserSimpleInfoVo(allData.getJSONObject(i), gitLinkRequestHelper.gitLinkUrl));
        }
        return gitLinkUserSimpleInfoVoList;
    }

    @Override
    public Boolean hasDocsManageRole(Long enterpriseId) {
        PmsEnterprise pmsEnterprise = pmsEnterpriseService.selectPmsEnterpriseById(enterpriseId);
        SysUserDeptRole userIdentifier = SecurityUtils.getUserIdentity();
        return FeignUtils.getReturnData(
                remoteDeptService.checkUserInDeptHasPerms(
                        pmsEnterprise.getDeptId()
                        , userIdentifier.getUserId()
                        , UserConstants.PMS_PERMS_DOCS_MANAGE
                        , SecurityConstants.INNER)
        );
    }

    @Override
    public List<SysFileInfo> getAllFileByFileIds(String fileIds) {
        if (StringUtils.isBlank(fileIds)) {
            return new ArrayList<>();
        }
        List<SysFileInfo> sysFileInfoList;
        try {
            sysFileInfoList = FeignUtils.getReturnData(
                    remoteFileService.getFileList(fileIds)
            );
        } catch (Exception e) {
            logger.error("从文件微服务获取附件列表时失败：{}", e.getMessage());
            throw new ServiceException("附件异常：" + e.getMessage());
        }
        return sysFileInfoList;
    }

    @Override
    public List<SysFileInfo> getAllFileByFileIdentifiers(String fileIdentifiers) {
        if (StringUtils.isBlank(fileIdentifiers)) {
            return new ArrayList<>();
        }
        List<SysFileInfo> sysFileInfoList;
        try {
            sysFileInfoList = FeignUtils.getReturnData(
                    remoteFileService.getFileListByIdentifier(fileIdentifiers)
            );
        } catch (Exception e) {
            logger.error("从文件微服务获取附件列表时失败：{}", e.getMessage());
            throw new ServiceException("附件异常：" + e.getMessage());
        }
        return sysFileInfoList;
    }

    @Override
    public List<SimpleGitlinkFileInfo> getAllGitlinkFileInfoByFileIdentifiers(String fileIdentifiers) {
        List<SysFileInfo> sysFileInfoList = getAllFileByFileIdentifiers(fileIdentifiers);
        return sysFileInfoList.stream().map(SysFileInfo::toSimpleGitlinkFileInfo).collect(Collectors.toList());
    }

    @Override
    public SimpleSysUser getSimpleSysUserByGitlinkUserId(Long gitlinkUserId) {
        SysUser sysUser = getSysUserByGitlinkId(gitlinkUserId);
        if (sysUser == null) {
            return null;
        }
        return sysUser.toSimpleSysUser(gitLinkRequestHelper.gitLinkUrl);
    }

    @Override
    public List<SimpleSysUser> getSimpleSysUserListByGitlinkUserIdsAndCache(String gitlinkUserIds, HashMap<String, Object> hashMap) {
        List<SimpleSysUser> userList = new ArrayList<>();
        if (StringUtils.isBlank(gitlinkUserIds)) {
            return userList;
        }
        String[] gitlinkUserIdStrList = gitlinkUserIds.split(",");
        for (String gitlinkUserIdStr : gitlinkUserIdStrList) {
            try {
                Long gitlinkUserId = Long.parseLong(gitlinkUserIdStr);
                SysUser sysUser = PmsUtils.getSelectObjectInCache(
                        hashMap
                        , this::getSysUserByGitlinkId
                        , gitlinkUserId);
                if (sysUser == null) {
                    continue;
                }
                userList.add(sysUser.toSimpleSysUser(gitLinkRequestHelper.gitLinkUrl));
            } catch (NumberFormatException e) {
                throw new ServiceException("该Gitlink用户Id格式错误(Gitlink用户id[%s])", gitlinkUserIdStr);
            }
        }
        return userList;
    }

    @Override
    public SysUser getSysUserByGitlinkId(Long gitlinkUserId) {
        if (gitlinkUserId == null) {
            return null;
        }
        SysUser sysUser = FeignUtils.getReturnData(
                remoteUserService.getSysUserByGitLinkUserId(gitlinkUserId, SecurityConstants.INNER)
        );
        if (sysUser == null) {
            sysUser = FeignUtils.getReturnData(
                    remoteUserService.createUserByGitLinkUserId(gitlinkUserId, SecurityConstants.INNER));
            if (sysUser == null) {
                throw new ServiceException("该用户不存在(用户Id[%d])", gitlinkUserId);
            }
        }

        setSysUserIdentifyStatus(sysUser);
        return sysUser;
    }

    private SysUser getSysUserByUsername(String username) {
        if (StringUtils.isEmpty(username)) {
            return null;
        }
        SysUser sysUser = FeignUtils.getReturnData(
                remoteUserService.getSysUserByUserName(username, SecurityConstants.INNER)
        );
        if (sysUser == null) {
            throw new ServiceException("该用户不存在(用户名[%s])", username);
        }
        setSysUserIdentifyStatus(sysUser);
        return sysUser;
    }

    private void setSysUserIdentifyStatus(SysUser sysUser) {
        SysUserDeptRole userIdentity = FeignUtils.getReturnData(
                remoteUserService.getAllStatusUserIdentityByDeptIdAndUserId(SecurityUtils.getDeptId(), sysUser.getUserId(), SecurityConstants.INNER)
        );
        if (userIdentity != null) {
            UserIdentityStatus abnormalState = UserIdentityStatus.getNonNormalState(userIdentity.getState());
            if (abnormalState != null) {
                sysUser.setNickName(sysUser.getNickName() + abnormalState.getStateInfo());
            }
        }
    }

    @Override
    public SimpleSysUser getSimpleSysUserByUsername(String username) {
        SysUser sysUser = getSysUserByUsername(username);
        if (sysUser == null) {
            return null;
        }
        return sysUser.toSimpleSysUser(gitLinkRequestHelper.gitLinkUrl);
    }

    @Override
    public String getNickNameByUsername(String username) {
        SysUser sysUser = getSysUserByUsername(username);
        if (sysUser == null) {
            return null;
        }
        return sysUser.getNickName();
    }

    @Override
    public SimpleGitlinkUser getSimpleGitlinkUserByGitlinkUserId(Long gitlinkUserId) {
        SysUser sysUser = getSysUserByGitlinkId(gitlinkUserId);
        if (sysUser == null) {
            return null;
        }
        return sysUser.toSimpleGitlinkUser();
    }

    @Override
    public SimpleGitlinkUser getSimpleGitlinkUserByUsername(String username) {
        SysUser sysUser = getSysUserByUsername(username);
        if (sysUser == null) {
            return null;
        }
        return sysUser.toSimpleGitlinkUser();
    }

    @Override
    public void setBaseEntityVo(BaseEntityVo baseEntityVo, BaseEntity baseEntity) {
        if (StringUtils.isNotEmpty(baseEntity.getCreateBy())) {
            SysUser sysUser = getSysUserByUsername(baseEntity.getCreateBy());
            if (sysUser != null) {
                baseEntityVo.setCreateBy(sysUser.getNickName());
            }

        }
        if (StringUtils.isNotEmpty(baseEntity.getUpdateBy())) {
            SysUser sysUser = getSysUserByUsername(baseEntity.getUpdateBy());
            if (sysUser != null) {
                baseEntityVo.setUpdateBy(sysUser.getNickName());
            }
        }
    }
}
