package com.zjrs.zwnw.portal.blo.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zjrs.zwnw.sxgl.entity.FwRight2ResourceMapper;
import com.zjrs.zwnw.sxgl.entity.FwrightMapper;
import com.zjrs.zwnw.sxgl.po.FwRight2ResourcePO;
import com.zjrs.zwnw.sxgl.po.FwrightPO;
import org.apache.commons.lang.StringUtils;
import org.mohrss.leaf.core.framework.domain.bpo.impl.BPOImpl;
import org.mohrss.leaf.core.framework.util.CurrentUser;
import com.zjrs.zwnw.portal.blo.DhyyBLO;
import com.zjrs.zwnw.portal.dto.ChangeUseAppDTO;
import com.zjrs.zwnw.portal.entity.VRsSyYydhInfoMapper;
import com.zjrs.zwnw.portal.entity.VRsSyYydhSzMapper;
import com.zjrs.zwnw.portal.po.VRsSyYydhInfoPO;
import com.zjrs.zwnw.portal.po.VRsSyYydhSzPO;
import org.mohrss.leaf.core.framework.web.exception.AppException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import jakarta.annotation.Resource;

import java.util.*;


@Service
public class DhyyBLOimpl extends BPOImpl implements DhyyBLO {
    @Resource
    private VRsSyYydhInfoMapper vRsSyYydhInfoMapper;

    @Resource
    private VRsSyYydhSzMapper vRsSyYydhSzMapper;

    @Autowired
    private FwrightMapper fwrightMapper;

    @Autowired
    private FwRight2ResourceMapper fwRight2ResourceMapper;

    @Override
    public List<VRsSyYydhInfoPO> getuserApp() {
        String userid = resolveUserid(getCurrentUser());
        List<VRsSyYydhInfoPO> result = vRsSyYydhInfoMapper.selectList(new QueryWrapper<VRsSyYydhInfoPO>().eq("userid", userid));

        if (result != null && !result.isEmpty()) {
            List<String> cdids = new ArrayList<>();
            List<String> appNames = new ArrayList<>();
            Map<String, List<String>> nameToCdids = new HashMap<>();
            for (VRsSyYydhInfoPO app : result) {
                if (StringUtils.isNotBlank(app.getCdid())) {
                    cdids.add(app.getCdid().trim());
                }
                if (StringUtils.isNotBlank(app.getLname())) {
                    String appName = app.getLname().trim();
                    appNames.add(appName);
                    nameToCdids.computeIfAbsent(appName, k -> new ArrayList<>()).add(app.getCdid() == null ? "" : app.getCdid().trim());
                }
            }

            Map<String, String> rightUrlMap = new HashMap<>();
            Set<String> repairableCdids = new HashSet<>();
            if (!cdids.isEmpty()) {
                List<FwRight2ResourcePO> resourcesByRightId = fwRight2ResourceMapper.selectList(
                        new QueryWrapper<FwRight2ResourcePO>().in("RIGHTID", cdids)
                );
                for (FwRight2ResourcePO res : resourcesByRightId) {
                    if (StringUtils.isNotBlank(res.getUrl()) && StringUtils.isNotBlank(res.getRightid())) {
                        rightUrlMap.put(res.getRightid().trim(), res.getUrl().trim());
                    }
                }

                List<String> missingCdids = new ArrayList<>();
                for (String cdid : cdids) {
                    if (!rightUrlMap.containsKey(cdid)) {
                        missingCdids.add(cdid);
                    }
                }

                if (!missingCdids.isEmpty()) {
                    List<FwRight2ResourcePO> resourcesBySubsystem = fwRight2ResourceMapper.selectList(
                            new QueryWrapper<FwRight2ResourcePO>().in("SUBSYSTYPE", missingCdids)
                    );
                    for (FwRight2ResourcePO res : resourcesBySubsystem) {
                        if (StringUtils.isNotBlank(res.getUrl()) && StringUtils.isNotBlank(res.getSubsystype())) {
                            rightUrlMap.put(res.getSubsystype().trim(), res.getUrl().trim());
                        }
                    }
                }

                List<String> stillMissingCdids = new ArrayList<>();
                for (String cdid : cdids) {
                    if (!rightUrlMap.containsKey(cdid)) {
                        stillMissingCdids.add(cdid);
                    }
                }

                if (!stillMissingCdids.isEmpty()) {
                    List<FwrightPO> rights = fwrightMapper.selectList(new QueryWrapper<FwrightPO>().in("RIGHTID", stillMissingCdids));
                    for (FwrightPO right : rights) {
                        if (StringUtils.isNotBlank(right.getUrl()) && StringUtils.isNotBlank(right.getRightid())) {
                            rightUrlMap.putIfAbsent(right.getRightid().trim(), right.getUrl().trim());
                            repairableCdids.add(right.getRightid().trim());
                        }
                    }
                }

                stillMissingCdids = new ArrayList<>();
                for (String cdid : cdids) {
                    if (!rightUrlMap.containsKey(cdid)) {
                        stillMissingCdids.add(cdid);
                    }
                }

                if (!stillMissingCdids.isEmpty()) {
                    List<FwrightPO> subsystemRights = fwrightMapper.selectList(
                            new QueryWrapper<FwrightPO>().in("SUBSYSTYPE", stillMissingCdids)
                    );
                    for (FwrightPO right : subsystemRights) {
                        if (StringUtils.isNotBlank(right.getUrl()) && StringUtils.isNotBlank(right.getSubsystype())) {
                            rightUrlMap.putIfAbsent(right.getSubsystype().trim(), right.getUrl().trim());
                            repairableCdids.add(right.getSubsystype().trim());
                        }
                    }
                }

                stillMissingCdids = new ArrayList<>();
                for (String cdid : cdids) {
                    if (!rightUrlMap.containsKey(cdid)) {
                        stillMissingCdids.add(cdid);
                    }
                }

                if (!stillMissingCdids.isEmpty() && !appNames.isEmpty()) {
                    List<FwrightPO> nameRights = fwrightMapper.selectList(
                            new QueryWrapper<FwrightPO>().in("RIGHTNAME", appNames)
                    );
                    Set<String> missingCdidSet = new HashSet<>(stillMissingCdids);
                    for (FwrightPO right : nameRights) {
                        if (StringUtils.isBlank(right.getUrl()) || StringUtils.isBlank(right.getRightname())) {
                            continue;
                        }
                        List<String> mappedCdids = nameToCdids.get(right.getRightname().trim());
                        if (mappedCdids == null || mappedCdids.isEmpty()) {
                            continue;
                        }
                        for (String mappedCdid : mappedCdids) {
                            if (missingCdidSet.contains(mappedCdid)) {
                                rightUrlMap.putIfAbsent(mappedCdid, right.getUrl().trim());
                                repairableCdids.add(mappedCdid);
                            }
                        }
                    }
                }

                stillMissingCdids = new ArrayList<>();
                for (String cdid : cdids) {
                    if (!rightUrlMap.containsKey(cdid)) {
                        stillMissingCdids.add(cdid);
                    }
                }

                if (!stillMissingCdids.isEmpty()) {
                    List<FwRight2ResourcePO> allResources = fwRight2ResourceMapper.selectList(
                            new QueryWrapper<FwRight2ResourcePO>().isNotNull("URL")
                    );
                    Map<String, String> normalizedRightIdUrlMap = new HashMap<>();
                    Map<String, String> normalizedSubsysUrlMap = new HashMap<>();
                    for (FwRight2ResourcePO res : allResources) {
                        if (StringUtils.isBlank(res.getUrl())) {
                            continue;
                        }
                        String url = res.getUrl().trim();
                        String normalizedRightId = normalizeKey(res.getRightid());
                        if (StringUtils.isNotBlank(normalizedRightId)) {
                            normalizedRightIdUrlMap.putIfAbsent(normalizedRightId, url);
                        }
                        String normalizedSubsys = normalizeKey(res.getSubsystype());
                        if (StringUtils.isNotBlank(normalizedSubsys)) {
                            normalizedSubsysUrlMap.putIfAbsent(normalizedSubsys, url);
                        }
                    }
                    for (String cdid : stillMissingCdids) {
                        String normalizedCdid = normalizeKey(cdid);
                        if (StringUtils.isBlank(normalizedCdid)) {
                            continue;
                        }
                        String url = pickFirstText(normalizedRightIdUrlMap.get(normalizedCdid), normalizedSubsysUrlMap.get(normalizedCdid));
                        if (StringUtils.isNotBlank(url)) {
                            rightUrlMap.put(cdid, url);
                        }
                    }
                }

                repairMissingRight2Resource(cdids, rightUrlMap, repairableCdids);
            }

            for (VRsSyYydhInfoPO app : result) {
                String cdid = app.getCdid() != null ? app.getCdid().trim() : "";
                String path = rightUrlMap.get(cdid);
                if (StringUtils.isNotBlank(path)) {
                    app.setPath(path);
                    if (StringUtils.isBlank(app.getOpenType())) {
                        if (path.startsWith("http://") || path.startsWith("https://")) {
                            app.setOpenType("2");
                        } else {
                            app.setOpenType("1");
                        }
                    }
                }
            }
        }

        return result;
    }

    @Override
    public void changeUseApp(ChangeUseAppDTO dto) {
        List<Map<String, Object>> data = dto.getData();
        String userid = resolveUserid(getCurrentUser());
        for (int i = 0; i < data.size(); i++) {
            VRsSyYydhSzPO po = new VRsSyYydhSzPO();
            po.setCdid(data.get(i).get("id").toString());
            po.setUserid(userid);
            vRsSyYydhSzMapper.insert(po);
        }
    }

    private String resolveUserid(CurrentUser currentUser) {
        String userid = trimToNull(currentUser == null ? null : currentUser.getUserid());
        if (StringUtils.isBlank(userid)) {
            userid = trimToNull(currentUser == null ? null : currentUser.getUsername());
        }
        if (StringUtils.isBlank(userid)) {
            throw new AppException("获取不到该用户信息");
        }
        return userid;
    }

    private void repairMissingRight2Resource(List<String> cdids, Map<String, String> rightUrlMap, Set<String> repairableCdids) {
        if (cdids == null || cdids.isEmpty() || repairableCdids == null || repairableCdids.isEmpty()) {
            return;
        }
        List<FwRight2ResourcePO> existedResources = fwRight2ResourceMapper.selectList(
                new QueryWrapper<FwRight2ResourcePO>().in("RIGHTID", cdids)
        );
        Set<String> existedRightIds = new HashSet<>();
        for (FwRight2ResourcePO resource : existedResources) {
            if (StringUtils.isNotBlank(resource.getRightid())) {
                existedRightIds.add(resource.getRightid().trim());
            }
        }
        for (String cdid : cdids) {
            if (!repairableCdids.contains(cdid) || existedRightIds.contains(cdid)) {
                continue;
            }
            String url = rightUrlMap.get(cdid);
            if (StringUtils.isBlank(url)) {
                continue;
            }
            FwRight2ResourcePO toInsert = new FwRight2ResourcePO();
            toInsert.setRightid(cdid);
            toInsert.setSubsystype(cdid);
            toInsert.setUrl(url);
            fwRight2ResourceMapper.insert(toInsert);
            existedRightIds.add(cdid);
        }
    }

    private String pickFirstText(String... values) {
        if (values == null) {
            return null;
        }
        for (String value : values) {
            if (StringUtils.isNotBlank(value)) {
                return value;
            }
        }
        return null;
    }

    private String normalizeKey(String value) {
        if (StringUtils.isBlank(value)) {
            return null;
        }
        return value.replaceAll("[^0-9A-Za-z]", "").toLowerCase();
    }

    private String trimToNull(String value) {
        if (StringUtils.isBlank(value)) {
            return null;
        }
        return value.trim();
    }
}
