package com.microservices.dms.achievementLibrary.service.impl;

import java.util.*;
import java.util.stream.Collectors;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.alibaba.fastjson2.JSONObject;
import com.microservices.common.core.utils.DateUtils;
import com.microservices.common.core.utils.StringUtils;
import com.microservices.common.httpClient.service.HttpAPIService;
import com.microservices.common.security.utils.SecurityUtils;
import com.microservices.dms.achievementLibrary.domain.*;
import com.microservices.dms.behaviorImage.domain.AchievementBehaviorSumVo;
import com.microservices.dms.behaviorImage.domain.AchievementImageVo;
import com.microservices.dms.behaviorImage.service.IBehaviorImageService;
import com.microservices.dms.resourceLibrary.domain.Clicker;
import com.microservices.dms.resourceLibrary.domain.CompetitionResourceLibrary;
import com.microservices.dms.resourceLibrary.domain.Searcher;
import com.microservices.dms.resourceLibrary.domain.TaskResourceLibrary;
import com.microservices.dms.resourceLibrary.domain.vo.KeyValVo;
import com.microservices.dms.resourceLibrary.mapper.ExpertResourceLibraryMapper;
import com.microservices.dms.resourceLibrary.mapper.ProjectResourceLibraryMapper;
import com.microservices.dms.resourceLibrary.mapper.TaskResourceLibraryMapper;
import com.microservices.dms.utils.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import com.microservices.dms.achievementLibrary.mapper.AchievementsMapper;
import com.microservices.dms.achievementLibrary.service.IAchievementsService;

import static com.microservices.dms.constant.BlockChainFunConstants.QUERY_REPO;
import static com.microservices.dms.utils.UrlUtil.getUrlPath;

/**
 * 成果Service业务层处理
 *
 * @author microservices
 * @date 2025-04-02
 */
@Service
@Slf4j
public class AchievementsServiceImpl implements IAchievementsService {
    @Autowired
    private AchievementsMapper achievementsMapper;

    @Autowired
    private TaskResourceLibraryMapper taskResourceLibraryMapper;

    @Autowired
    private ExpertResourceLibraryMapper expertResourceLibraryMapper;

    @Autowired
    private ProjectResourceLibraryMapper projectResourceLibraryMapper;

    @Autowired
    private IBehaviorImageService behaviorImageService;

    @Value("${markerSpaceUrl}")
    public String markerSpaceUrl;

    @Value("${http.gitLinkUrl}")
    public String gitLinkUrl;

    @Value("${http.gatewayUrl}")
    public String gatewayUrl;

//    @Value("${gitlink.fiscobcosUrl}")
    public String fiscobcosUrl;

    @Autowired
    private HttpAPIService httpAPIService;

    /**
     * 查询成果
     *
     * @param id 成果主键
     * @return 成果
     */
    @Override
    public Achievements selectAchievementsById(Long id) {
        Achievements a = achievementsMapper.selectAchievementsById(id);
        if (StringUtils.isNotNull(a)) {
            String gender = a.getGender();
            String img = "";
            if (StringUtils.isNotEmpty(gender) && gender.equals("1")) {
                img = "images/avatars/User/girl.jpg";
            } else if (StringUtils.isNotEmpty(gender) && gender.equals("0")) {
                img = "images/avatars/User/boy.jpg";
            }
            a.setUserImg(img);
            if (StringUtils.isNotEmpty(a.getField1())) {
                String field1Name = achievementsMapper.getField1NameByParam(a.getSource(), a.getId());
                if (StringUtils.isNotNull(field1Name)) {
                    a.setField1Name(field1Name);
                }
            }
            a.setUserImg(img);

            a.setImages(buildFileInfoByIdents(a.getImages(), a.getSource()));
            a.setAttachments(buildFileInfoByIdents(a.getAttachments(), a.getSource()));
        }
        return a;
    }

    /**
     * 查询成果列表
     *
     * @param achievements 成果
     * @return 成果
     */
    @Override
    public List<Achievements> selectAchievementsList(Achievements achievements) {
        List<Achievements> list = achievementsMapper.selectAchievementsList(achievements);
        for (Achievements a : list) {
            String gender = a.getGender();
            String img = "";
            if (StringUtils.isNotEmpty(gender) && gender.equals("1")) {
                img = "images/avatars/User/girl.jpg";
            } else if (StringUtils.isNotEmpty(gender) && gender.equals("0")) {
                img = "images/avatars/User/boy.jpg";
            }
            a.setUserImg(img);
            //根据id获取领域名称
            if (StringUtils.isNotEmpty(a.getField1())) {
                String field1Name = achievementsMapper.getField1NameByParam(a.getSource(), a.getId());
                if (StringUtils.isNotNull(field1Name)) {
                    a.setField1Name(field1Name);
                }
            }
            a.setImages(buildFileInfoByIdents(a.getImages(), a.getSource()));
            a.setAttachments(buildFileInfoByIdents(a.getAttachments(), a.getSource()));

            //拼接对接的用户信息
            List<Map<String,Object>> dockingUserInfo =  achievementsMapper.getDockingUserInfo(achievements.getId());
            achievements.setDockingUserInfo(dockingUserInfo);
        }
        return list;
    }


    @Override
    public List<Achievements> selectAchievementsFrontList(Achievements achievements) {
        List<Achievements> list = achievementsMapper.selectAchievementsList(achievements);
        for (Achievements a : list) {
            a.setDetails(null);
            a.setImages(buildFileInfoByIdents(a.getImages(), a.getSource()));
            a.setAttachments(buildFileInfoByIdents(a.getAttachments(), a.getSource()));
        }
        return list;
    }

    /**
     * 新增成果
     *
     * @param achievements 成果
     * @return 结果
     */
    @Override
    public int insertAchievements(Achievements achievements) {
        achievements.setCreateTime(DateUtils.getNowDate());
        achievements.setCreateBy(SecurityUtils.getUsername());
        return achievementsMapper.insertAchievements(achievements);
    }

    /**
     * 修改成果
     *
     * @param achievements 成果
     * @return 结果
     */
    @Override
    public int updateAchievements(Achievements achievements) {
        achievements.setUpdateTime(DateUtils.getNowDate());
        achievements.setUpdateBy(SecurityUtils.getUsername());
        return achievementsMapper.updateAchievements(achievements);
    }

    /**
     * 批量删除成果
     *
     * @param ids 需要删除的成果主键
     * @return 结果
     */
    @Override
    public int deleteAchievementsByIds(Long[] ids) {
        return achievementsMapper.deleteAchievementsByIds(ids);
    }

    /**
     * 删除成果信息
     *
     * @param id 成果主键
     * @return 结果
     */
    @Override
    public int deleteAchievementsById(Long id) {
        return achievementsMapper.deleteAchievementsById(id);
    }

    @Override
    public String buildFileInfoByIdents(String aStr, String source) {
        if (StringUtils.isEmpty(aStr) || StringUtils.isEmpty(source)) {
            return aStr;
        }

        List<Map<String, String>> list = JSON.parseObject(aStr, new TypeReference<List<Map<String, String>>>() {
        });

        if (Objects.equals(source, "1") || Objects.equals(source, "3")) {
            concatUrl(list, gitLinkUrl);
        }

        if (Objects.equals(source, "2")) {
            concatUrl(list, markerSpaceUrl);
        }

        if (Objects.equals(source, "4")) {
            concatUrl(list, gatewayUrl);
        }

        return JSON.toJSONString(list);
    }

    private void concatUrl(List<Map<String, String>> list, String url) {
        for (Map<String, String> map : list) {
            String v = map.getOrDefault("v", "");
            String urlPath = getUrlPath(v);
            map.put("v", url + urlPath);
        }
    }


    @Override
    public List<Achievements> getChoiceImport() {
        return achievementsMapper.getChoiceImport();
    }

    @Override
    public List<KeyValueVo> getTjBySources() {
        return achievementsMapper.getTjBySources();
    }

    @Override
    public List<KeyValueVo> getTjByAreas() {
        return achievementsMapper.getTjByAreas();
    }

    @Override
    public List<Achievements> getAllResult(AchQueryVo achQueryVo) {
        //根据查询条件获取所有的成果数据
        List<Achievements> list = achievementsMapper.selectAchievementsByParam(achQueryVo);
        //遍历成果数据，获取对应成果的点击数
        for (Achievements a : list) {
            String gender = a.getGender();
            String img = "";
            if (StringUtils.isNotEmpty(gender) && gender.equals("1")) {
                img = "images/avatars/User/girl.jpg";
            } else if (StringUtils.isNotEmpty(gender) && gender.equals("0")) {
                img = "images/avatars/User/boy.jpg";
            }
            a.setUserImg(img);
            //根据id获取领域名称
            if (StringUtils.isEmpty(achQueryVo.getSource()) && StringUtils.isNotEmpty(a.getField1())) {
                String field1Name = achievementsMapper.getField1NameByParam(a.getSource(), a.getId());
                if (StringUtils.isNotNull(field1Name)) {
                    a.setField1Name(field1Name);
                }
            }
            Long clickSum = achievementsMapper.getAchievementClickSum(a.getId());
            a.setClickSum(clickSum);
        }
        return list;
    }

    @Override
    public Map<String, Object> getUerActionData() {
        Date[] days = DateUtil.getDays(0, 6);
        Map<String, Long> w = achievementsMapper.getaWatcher(days[0], days[1], "Achievements")
                .stream().collect(Collectors.toMap(KeyValVo::getK, KeyValVo::getV));

        Map<String, Long> g = achievementsMapper.getFavorite(days[0], days[1], "Achievements")
                .stream().collect(Collectors.toMap(KeyValVo::getK, KeyValVo::getV));

        List<String> dateStr = DateUtil.getDateStrMMDD(days[0], days[1]);
        List<KeyValVo<String, Long>> wRes = new ArrayList<>();
        List<KeyValVo<String, Long>> gRes = new ArrayList<>();
        for (String s : dateStr) {
            Long a = w.getOrDefault(s, 0L);
            Long b = g.getOrDefault(s, 0L);
            KeyValVo<String, Long> k1 = new KeyValVo<>();
            k1.setK(s);
            k1.setV(a);
            KeyValVo<String, Long> k2 = new KeyValVo<>();
            k2.setK(s);
            k2.setV(b);

            wRes.add(k1);
            gRes.add(k2);
        }
        Map<String, Object> res = new HashMap<>();
        res.put("watcher", wRes);
        res.put("favorite", gRes);
        return res;
    }

    @Override
    public List<HotAchVo> getHotAchievement() {
        //根据查询条件获取所有的成果数据
        List<HotAchVo> resultList = achievementsMapper.getHotAchievement();
        //遍历成果数据，获取对应成果的点击数
        for (HotAchVo a : resultList) {
            String gender = a.getGender();
            String img = "";
            if (StringUtils.isNotEmpty(gender) && gender.equals("1")) {
                img = "images/avatars/User/girl.jpg";
            } else if (StringUtils.isNotEmpty(gender) && gender.equals("0")) {
                img = "images/avatars/User/boy.jpg";
            }
            a.setUserImg(img);
        }
        return resultList;
    }

    @Override
    public List<KeyValVo<String, Long>> get7DayAdd(AchQueryVo achQueryVo) {
        Date[] days = DateUtil.getDays(0, 6);
        Map<String, Long> w = achievementsMapper.getAchievement(days[0], days[1], achQueryVo.getSource())
                .stream().collect(Collectors.toMap(KeyValVo::getK, KeyValVo::getV));

        List<String> dateStr = DateUtil.getDateStrMMDD(days[0], days[1]);
        List<KeyValVo<String, Long>> res = new ArrayList<>();

        for (String s : dateStr) {
            Long a = w.getOrDefault(s, 0L);
            KeyValVo<String, Long> k1 = new KeyValVo<>();
            k1.setK(s);
            k1.setV(a);
            res.add(k1);
        }
        return res;
    }

    @Override
    public Map<String, Long> indexProjectStatistic() {
        Map<String, Long> res = achievementsMapper.indexProjectStatistic();
        return res;
    }

    @Override
    public Map<String, Object> indexTaskStatistic() {
        Map<String, Object> res = achievementsMapper.indexTaskStatistic();
        double convertedTaskAmount = taskResourceLibraryMapper.getConvertedTaskAmount2();
        res.put("convertedTaskAmount", convertedTaskAmount);
        return res;
    }

    @Override
    public Map<String, Long> indexCompetitionStatistic() {
        Map<String, Long> res = achievementsMapper.indexCompetitionStatistic();
        return res;
    }

    @Override
    public Map<String, Long> indexSchoolEnterpriseStatistic() {
        Map<String, Long> res = new HashMap<>();
        Long schoolEnterpriseCount = achievementsMapper.indexSchoolEnterpriseStatistic("4", "");
        res.put("schoolEnterpriseCount", schoolEnterpriseCount);
        Long schoolCount = achievementsMapper.indexSchoolEnterpriseStatistic("4", "1");
        res.put("schoolCount", schoolCount);
        Long enterpriseCount = achievementsMapper.indexSchoolEnterpriseStatistic("4", "2");
        res.put("enterpriseCount", enterpriseCount);
        Clicker clicker = new Clicker();
        clicker.setClickType("Achievements");
        long clickCount = taskResourceLibraryMapper.countClicker(clicker);
        res.put("clickCount", clickCount);
        return res;
    }

    @Override
    public Map<String, Long> indexExpertStatistic() {
        Map<String, Long> res = new HashMap<>();
        Long expertResourceCount = expertResourceLibraryMapper.expertResourceCount();
        res.put("expertResourceCount", expertResourceCount);
        Long auditTaskAuditExpertCount = expertResourceLibraryMapper.auditTaskAuditExpertCount();
        res.put("auditTaskAuditExpertCount", auditTaskAuditExpertCount);
        Long auditCompetitionAuditExpertCount = expertResourceLibraryMapper.auditCompetitionAuditExpertCount();
        res.put("auditCompetitionAuditExpertCount", auditCompetitionAuditExpertCount);
        Clicker clicker = new Clicker();
        clicker.setClickType("Experts");
        long clickCount = taskResourceLibraryMapper.countClickerSimple(clicker);
        res.put("clickCount", clickCount);
        return res;
    }

    @Override
    public List<KeyValueVo> getAreasByName(String areaName) {
        return achievementsMapper.getAreasByName(areaName);
    }

    @Override
    public AchievementBehaviorSumVo getActDataStatisticById(Long id) {
        return achievementsMapper.getActDataStatisticById(id);
    }

    @Override
    public List<KeyValVo<String, Long>> get7AddClickById(String id, String clickType) {

        if (StringUtils.isEmpty(clickType)) {
            clickType = "Achievements";
        }
        Date[] days = DateUtil.getDays(0, 6);
        Map<String, Long> w = achievementsMapper.get7AddClickById(days[0], days[1], clickType, id)
                .stream().collect(Collectors.toMap(KeyValVo::getK, KeyValVo::getV));

        List<String> dateStr = DateUtil.getDateStrMMDD(days[0], days[1]);
        List<KeyValVo<String, Long>> res = new ArrayList<>();

        for (String s : dateStr) {
            Long a = w.getOrDefault(s, 0L);
            KeyValVo<String, Long> k1 = new KeyValVo<>();
            k1.setK(s);
            k1.setV(a);
            res.add(k1);
        }
        return res;
    }

    @Override
    public AchievementBehaviorSumVo getWatchFavoriteStatusById(Long id, Long userId) {
        return achievementsMapper.getWatchFavoriteStatusById(id, userId);
    }


    @Scheduled(cron = "${cron.calculateHotRank}")
    public void timingCalcHotRank() {
        List<Long> ids = achievementsMapper.getAllId();
        for (Long id : ids) {
            AchievementImageVo image = behaviorImageService.getAchievementImageById(id);
            float score = image.getScore();
            Achievements u = new Achievements();
            u.setId(id);
            u.setHotRank(score);
            achievementsMapper.updateAchievements(u);
        }
    }

    @Override
    public List<AreaStatisticVo> getAreaStatistic(String areaKey) {
        return achievementsMapper.getAreaStatistic(areaKey);
    }

    @Override
    public List<AchRelatedResult> getRelatedAch(Long id, Long sourceId) {
        List<AchRelatedResult> relatedResultList = new ArrayList<>();
        //想根据开源项目id，获取对应的年度信息
        List<Long> allSourceId = achievementsMapper.getAllSourceId(id, sourceId);
        List<String> allYear = achievementsMapper.getDistinctYear(id, allSourceId);
        if (StringUtils.isNotNull(allYear)) {
            //遍历年度信息，获取年度成果数据
            for (String paramYear : allYear) {
                AchRelatedResult relatedResult = new AchRelatedResult();
                relatedResult.setYear(paramYear);
                List<AchRelatedVo> tmpList = achievementsMapper.getRelatedAch(id, allSourceId, paramYear);
                relatedResult.setAchRelatedVoList(tmpList);
                relatedResultList.add(relatedResult);
            }
        }
        return relatedResultList;
    }

    @Override
    public List<AchRelatedResult> getRelatedAchCompetition(Long id, Long sourceId) {
        List<AchRelatedResult> relatedResultList = new ArrayList<>();
        //想根据开源项目id，获取对应的年度信息
        List<Long> allSourceId = achievementsMapper.getAllSourceIdCompetition(id, sourceId);
        List<String> allYear = achievementsMapper.getDistinctYear(id, allSourceId);
        if (StringUtils.isNotNull(allYear)) {
            //遍历年度信息，获取年度成果数据
            for (String paramYear : allYear) {
                AchRelatedResult relatedResult = new AchRelatedResult();
                relatedResult.setYear(paramYear);
                List<AchRelatedVo> tmpList = achievementsMapper.getRelatedAch(id, allSourceId, paramYear);
                relatedResult.setAchRelatedVoList(tmpList);
                relatedResultList.add(relatedResult);
            }
        }
        return relatedResultList;
    }

    @Override
    public List<AchRelatedResult> getRelatedAchTask(Long id, Long sourceId) {
        List<AchRelatedResult> relatedResultList = new ArrayList<>();
        //想根据开源项目id，获取对应的年度信息
        List<Long> allSourceId = achievementsMapper.getAllSourceIdTask(id, sourceId);
        List<String> allYear = achievementsMapper.getDistinctYear(id, allSourceId);
        if (StringUtils.isNotNull(allYear)) {
            //遍历年度信息，获取年度成果数据
            for (String paramYear : allYear) {
                AchRelatedResult relatedResult = new AchRelatedResult();
                relatedResult.setYear(paramYear);
                List<AchRelatedVo> tmpList = achievementsMapper.getRelatedAch(id, allSourceId, paramYear);
                relatedResult.setAchRelatedVoList(tmpList);
                relatedResultList.add(relatedResult);
            }
        }
        return relatedResultList;
    }

    @Override
    public List<TaskResourceLibrary> getRelatedAchTaskOfExpert(Long id) {
        return achievementsMapper.getRelatedAchTaskOfExpert(id);
    }

    @Override
    public List<CompetitionResourceLibrary> getRelatedAchCompetitionOfExpert(Long id) {
        return achievementsMapper.getRelatedAchCompetitionOfExpert(id);
    }


    /**
     * 根据查询内容，调用搜索行为接口
     *
     * @param achName
     * @param userId
     */
    @Override
    public int getSearchResult(String achName, Long userId) {
        int num = 0;
        if (StringUtils.isEmpty(achName)) {
            return num;
        }
        List<Long> idList = achievementsMapper.selectAchievementsByName(achName);
        if (StringUtils.isNotNull(idList)) {
            for (Long searchId : idList) {
                Searcher e = new Searcher();
                e.setCreatedAt(DateUtils.getNowDate());
                e.setUserId(userId);
                e.setSearchId(searchId);
                e.setExtInfo(achName);
                e.setSearchType("Achievements");
                num = taskResourceLibraryMapper.insertSearcher(e);
                num++;
            }
        }
        return num;
    }

    @Override
    public List<KeyValueVo> getProjectAreasByName(String areaName) {
        return achievementsMapper.getProjectAreasByName(areaName);
    }

    @Override
    public List<String> getExpertAreasByName(String areaName) {
        return achievementsMapper.getExpertAreasByName(areaName);
    }


    @Override
    public List<TokenListVo> projectTokenList() {
        List<TokenListVo> list = projectResourceLibraryMapper.selectProjectInfos();
        for (TokenListVo v : list) {
           Long totalToken =  queryTotalToken(v);
           Long issueTokenSum =  projectResourceLibraryMapper.sumProjectIssueToken(v.getId());
           v.setCurrentToken(totalToken - issueTokenSum);
           v.setTotalToken(totalToken);
        }
        return list;
    }

    private Long queryTotalToken(TokenListVo v) {
        JSONObject param = new JSONObject();
        param.put("request-type",QUERY_REPO);
        param.put("token_name",v.getId());

        try {
            JSONObject reps = httpAPIService.doPost(fiscobcosUrl,param);
            if (reps.containsKey("status") && reps.getString("status").equals("0")) {
                //                Long curSupply = reps.getLong("cur_supply");
                return reps.getLong("total_supply");
            }
        } catch (Exception e) {
            log.error("区块链信息查询失败", e);
            return -1L;
        }

        return -1L;
    }
}
