package com.ruoyi.system.service.impl;

import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.common.enums.LoginPolicyType;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.SysLoginPolicy;
import com.ruoyi.system.mapper.SysLoginPolicyMapper;
import com.ruoyi.system.service.ISysLoginPolicyService;

/**
 * 登录策略配置服务实现。
 * <p>
 * 根据部署网络区域（{@code login.network-zone}）、用户角色、用户级 {@code sys_user.login_policy}
 * 解析最终登录方式，供 {@link com.ruoyi.framework.web.service.LoginSmsService} 判断是否强制短信双因子。
 * </p>
 * <p>
 * <b>策略匹配优先级（高 → 低）</b>
 * <ol>
 *   <li>用户表 {@code login_policy} 非空且合法</li>
 *   <li>{@code sys_login_policy} 中 {@code role_key} 命中用户任一角色</li>
 *   <li>{@code sys_login_policy} 中 {@code role_key} 为空的默认行</li>
 *   <li>回退为 {@link LoginPolicyType#PASSWORD}</li>
 * </ol>
 * </p>
 *
 * @see com.ruoyi.system.domain.SysLoginPolicy
 * @see sql/crypto_phase1.sql
 */
@Service
public class SysLoginPolicyServiceImpl implements ISysLoginPolicyService
{
    @Autowired
    private SysLoginPolicyMapper loginPolicyMapper;

    @Override
    public List<SysLoginPolicy> selectEnabledByNetworkZone(String networkZone)
    {
        return loginPolicyMapper.selectEnabledByNetworkZone(networkZone);
    }

    /**
     * 解析用户在当前网络区域下应使用的登录策略类型。
     *
     * @param networkZone     INTERNAL 或 INTERNET，来自 application.yml
     * @param roleKeys        用户拥有的角色权限字符列表（sys_role.role_key）
     * @param userLoginPolicy 用户级覆盖策略，来自 sys_user.login_policy，可为 null
     * @return 最终策略，默认 PASSWORD
     */
    @Override
    public LoginPolicyType resolvePolicyType(String networkZone, List<String> roleKeys, String userLoginPolicy)
    {
        // 1. 用户级策略优先（管理员可为单个账号指定 CERT / SMS_2FA / PASSWORD）
        if (StringUtils.isNotEmpty(userLoginPolicy))
        {
            LoginPolicyType userPolicy = parsePolicyType(userLoginPolicy);
            if (userPolicy != null)
            {
                return userPolicy;
            }
        }

        // 2. 按角色匹配 sys_login_policy（如 admin + INTERNET → SMS_2FA）
        List<SysLoginPolicy> policies = selectEnabledByNetworkZone(networkZone);
        if (roleKeys != null)
        {
            for (SysLoginPolicy policy : policies)
            {
                if (StringUtils.isNotEmpty(policy.getRoleKey()) && roleKeys.contains(policy.getRoleKey()))
                {
                    LoginPolicyType matched = parsePolicyType(policy.getPolicyType());
                    if (matched != null)
                    {
                        return matched;
                    }
                }
            }
        }

        // 3. 网络区域默认策略（role_key 为空的行）
        SysLoginPolicy defaultPolicy = loginPolicyMapper.selectDefaultByNetworkZone(networkZone);
        if (defaultPolicy != null)
        {
            LoginPolicyType matched = parsePolicyType(defaultPolicy.getPolicyType());
            if (matched != null)
            {
                return matched;
            }
        }

        return LoginPolicyType.PASSWORD;
    }

    /** 将库中策略字符串转为枚举，非法值返回 null */
    private LoginPolicyType parsePolicyType(String policyType)
    {
        if (StringUtils.isEmpty(policyType))
        {
            return null;
        }
        try
        {
            return LoginPolicyType.valueOf(policyType.trim().toUpperCase());
        }
        catch (IllegalArgumentException ex)
        {
            return null;
        }
    }
}
