package com.hdkj.lt.bf.aspect;

import cn.hutool.core.collection.CollUtil;
import com.hdkj.lt.base.exception.BusinessException;
import com.hdkj.lt.bf.service.StruService;
import com.hdkj.lt.core.bizms.modle.po.DwdShbDsFeederBase;
import com.hdkj.lt.core.sys.model.dto.StruTreeCacheDTO;
import com.hdkj.lt.core.sys.service.DwdShbDsFeederBaseService;
import com.hdkj.lt.core.sys.service.ISysStruService;
import com.ruoyi.common.security.utils.SecurityUtils;
import com.ruoyi.system.api.model.LoginUser;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @author rj
 * @date 2026/4/1 14:37
 * @description
 */
@Slf4j
@Component
@Aspect
@RequiredArgsConstructor
public class CountryPermissionAspect {


    private final StruService struService;
    private final ISysStruService sysStruService;

    private final DwdShbDsFeederBaseService dwdShbDsFeederBaseService;

    private static final String PROVINCE = "1";//省
    private static final String CITY = "4";//市
    private static final String COUNTY = "5";//区县
    private static final String FEEDER = "0";//线路
    private static final String STATION = "10";//变电站

    @Before("@annotation(requiresCountryPermissions)")
    public void beforeCountryPermissions(JoinPoint joinPoint, RequiresCountryPermissions requiresCountryPermissions) {
        List<String> countyList = this.getCountyList();
        List<Long> deptList = this.getDeptList();
        String countryFields = requiresCountryPermissions.countryFields();
        String lineFields = requiresCountryPermissions.lineFields();
        String deptCodeFields = requiresCountryPermissions.deptCodeFields();

        String lineId = "";
        String countryId = "";
        Long deptId = -1L;
        Object[] args = joinPoint.getArgs();
        for (Object arg : args) {
            try {
                if (StringUtils.isNotEmpty(lineFields)) {
                    String getterName = "get" + lineFields.substring(0, 1).toUpperCase() + lineFields.substring(1);
                    Method method = arg.getClass().getMethod(getterName);
                    lineId = (String) method.invoke(arg);
                }
                if (StringUtils.isNotEmpty(countryFields)) {
                    String getterName2 = "get" + countryFields.substring(0, 1).toUpperCase() + countryFields.substring(1);
                    Method method2 = arg.getClass().getMethod(getterName2);
                    countryId = (String) method2.invoke(arg);
                }
                if (StringUtils.isNotEmpty(deptCodeFields)) {
                    String getterName2 = "get" + deptCodeFields.substring(0, 1).toUpperCase() + deptCodeFields.substring(1);
                    Method method2 = arg.getClass().getMethod(getterName2);
                    deptId = (Long) method2.invoke(arg);
                }
            } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
                throw new BusinessException("系统异常，请联系管理员");
            }
        }
        DwdShbDsFeederBase feederBase = dwdShbDsFeederBaseService.getByPsrId(lineId);
        String feederCountryId = "";
        if (feederBase != null) {
            feederCountryId = feederBase.getMaintOrg();
        }
        if (StringUtils.isNotEmpty(countryId) && !countyList.contains(countryId)) {
            throw new BusinessException("当前用户无权限访问");
        }
        if (StringUtils.isNotEmpty(feederCountryId) && !countyList.contains(feederCountryId)) {
            throw new BusinessException("当前用户无权限访问");
        }
        if (deptId != null && deptId != -1L && !deptList.contains(deptId)) {
            throw new BusinessException("当前用户无权限访问");
        }
    }

    //查询登录人的所有机构区县信息
    private List<String> getCountyList() {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        if (loginUser == null) {
            throw new BusinessException("请先登录");
        }
        Long struId = loginUser.getSysUser().getDeptId();
        return this.getCountyCodeListByStruId(struId);
    }

    //查询登录人的所有机构区县信息
    private List<Long> getDeptList() {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        if (loginUser == null) {
            throw new BusinessException("请先登录");
        }
        Long struId = loginUser.getSysUser().getDeptId();
        return struService.getCountyCodeListByStruId(struId);
    }

    public List<String> getCountyCodeListByStruId(Long struId) {
        List<String> result = new ArrayList<>();
        if (Objects.isNull(struId)) {
            return result;
        }
        StruTreeCacheDTO struTreeCacheDTO = sysStruService.getStruTreeByCache(struId);
        if (Objects.isNull(struTreeCacheDTO)) {
            return result;
        }
        String struType = struTreeCacheDTO.getStruType();
        switch (struType) {
            case PROVINCE:
                // 1.用户如果是省公司，获取所有市所有区县
                List<StruTreeCacheDTO> children = struTreeCacheDTO.getChildren();
                Optional.ofNullable(children).ifPresent(child -> {
                    List<String> childrenStruIdList = child.stream().filter(e -> e != null && CollUtil.isNotEmpty(e.getChildren()))
                            .flatMap(grand -> grand.getChildren().stream())
                            .filter(grand -> !Objects.isNull(grand.getStruId()))
                            .map(StruTreeCacheDTO::getIscOrgId)
                            .distinct().collect(Collectors.toList());
                    Optional.of(childrenStruIdList).ifPresent(result::addAll);
                });
                break;
            case CITY:
                // 2.用户如果是市公司，获取市下级所有区县
                Optional.ofNullable(struTreeCacheDTO.getChildren()).ifPresent(e -> {
                    List<String> childrenStruIdList = e.stream().filter(child -> !Objects.isNull(child.getIscOrgId())).map(StruTreeCacheDTO::getIscOrgId)
                            .distinct().collect(Collectors.toList());
                    Optional.of(childrenStruIdList).ifPresent(result::addAll);
                });
                break;
            case COUNTY:
                // 3.用户如果是区县 只查询当前区县
                result.add(struTreeCacheDTO.getIscOrgId());
                break;
            default:
                log.error("当前组织类型不正确!");
                throw new BusinessException("当前组织类型不正确！");
        }
        return result;
    }

}

