import random
import re
import requests
from datetime import datetime, timedelta
from typing import Dict, Any, Tuple

# ==========================================
# 1. 常量与国家配置区
# ==========================================

DEFAULT_PASSWORD = "Visafly@111"
VISA_TYPE = "Short stay (<90 days) - Tourism"
TRAVEL_PURPOSE = "Tourism / Private visit"
PASSPORT_TYPE = "Ordinary passport"

# 国家专属配置字典，将差异化数据隔离，极大提升可维护性
COUNTRY_CONFIGS = {
    "CN-Shanghai": {
        "nat_code": None,  # randomuser 不支持 CN，置为 None
        "pool_name": "tls.cn.sha.fr.sentinel",
        "location": "Shanghai",
        "province_residence": "Shanghai",
        "nationality": "China",
        "phone_country_code": "86",
        # --- 本地化生成规则（针对 API 不支持的国家） ---
        "local_first_names": ["Wei", "Fang", "Jian", "Hui", "Lei", "Ting", "Peng", "Xia", "Bin", "Jie", "San", "Ming"],
        "local_last_names": ["Wang", "Li", "Zhang", "Liu", "Chen", "Yang", "Huang", "Zhao", "Wu", "Zhou"],
        "phone_prefix": ["138", "139", "150", "151", "180", "189"], # 中国手机号前缀
        "phone_length": 11,
        # -----------------------------------------------
        "default_first_name": "San",
        "default_last_name": "Zhang",
        "default_phone": "13800000000",
        "fra1": "FRA1SH",
    },
    "CN-Hangzhou": {
        "nat_code": None,  # randomuser 不支持 CN，置为 None
        "pool_name": "tls.cn.hgh.fr.sentinel",
        "location": "Hangzhou",
        "province_residence": "Jiangsu",
        "nationality": "China",
        "phone_country_code": "86",
        # --- 本地化生成规则（针对 API 不支持的国家） ---
        "local_first_names": ["Wei", "Fang", "Jian", "Hui", "Lei", "Ting", "Peng", "Xia", "Bin", "Jie", "San", "Ming"],
        "local_last_names": ["Wang", "Li", "Zhang", "Liu", "Chen", "Yang", "Huang", "Zhao", "Wu", "Zhou"],
        "phone_prefix": ["138", "139", "150", "151", "180", "189"], # 中国手机号前缀
        "phone_length": 11,
        # -----------------------------------------------
        "default_first_name": "San",
        "default_last_name": "Zhang",
        "default_phone": "13800000000",
        "fra1": "FRA1HN",
    },
    "CN-Beijing": {
        "nat_code": None,  # randomuser 不支持 CN，置为 None
        "pool_name": "tls.cn.bjs.fr.sentinel",
        "location": "Beijing",
        "province_residence": "Beijing",
        "nationality": "China",
        "phone_country_code": "86",
        # --- 本地化生成规则（针对 API 不支持的国家） ---
        "local_first_names": ["Wei", "Fang", "Jian", "Hui", "Lei", "Ting", "Peng", "Xia", "Bin", "Jie", "San", "Ming"],
        "local_last_names": ["Wang", "Li", "Zhang", "Liu", "Chen", "Yang", "Huang", "Zhao", "Wu", "Zhou"],
        "phone_prefix": ["138", "139", "150", "151", "180", "189"], # 中国手机号前缀
        "phone_length": 11,
        # -----------------------------------------------
        "default_first_name": "San",
        "default_last_name": "Zhang",
        "default_phone": "13800000000",
        "fra1": "FRA1PB",
    },
    "CN-Guangzhou": {
        "nat_code": None,  # randomuser 不支持 CN，置为 None
        "pool_name": "tls.cn.can.fr.sentinel",
        "location": "Guangzhou",
        "province_residence": "Guangdong",
        "nationality": "China",
        "phone_country_code": "86",
        # --- 本地化生成规则（针对 API 不支持的国家） ---
        "local_first_names": ["Wei", "Fang", "Jian", "Hui", "Lei", "Ting", "Peng", "Xia", "Bin", "Jie", "San", "Ming"],
        "local_last_names": ["Wang", "Li", "Zhang", "Liu", "Chen", "Yang", "Huang", "Zhao", "Wu", "Zhou"],
        "phone_prefix": ["138", "139", "150", "151", "180", "189"], # 中国手机号前缀
        "phone_length": 11,
        # -----------------------------------------------
        "default_first_name": "San",
        "default_last_name": "Zhang",
        "default_phone": "13800000000",
        "fra1": "FRA1CB",
    },
    "GB-London": {
        "nat_code": "gb",  # API 支持 GB，直接依赖 API 生成姓名
        "pool_name": "tls.gb.lon.fr.sentinel",
        "location": "London",
        "province_residence": "London",
        "nationality": "United Kingdom",
        "phone_country_code": "44",
        "default_first_name": "James",
        "default_last_name": "Smith",
        "default_phone": "7400000000",
        "fra1": "FRA1LO",
    },
        "IE-Dublin": {
        "nat_code": "ie",  # API 支持 GB，直接依赖 API 生成姓名
        "pool_name": "tls.ie.dub.fr.sentinel",
        "location": "Dublin",
        "province_residence": "Dublin",
        "nationality": "Ireland",
        "phone_country_code": "353",
        "default_first_name": "James",
        "default_last_name": "Smith",
        "default_phone": "0895224562",
        "fra1": "FRA1DB",
    }
}

# ==========================================
# 2. 辅助生成函数 (单一职责)
# ==========================================

def _fetch_random_user_data(nat_code: str = None) -> Dict[str, Any]:
    """
    请求 randomuser API。
    如果 nat_code 为空，则请求全局随机用户（仅用于借用其随机的出生日期和性别）。
    """
    url = f"https://randomuser.me/api/?nat={nat_code}" if nat_code else "https://randomuser.me/api/"
    try:
        resp = requests.get(url, timeout=10)
        resp.raise_for_status()
        raw = resp.json()
        results = raw.get("results")
        if results and isinstance(results, list):
            return results[0]
    except Exception:
        pass
    return {}

def _generate_localized_name(config: Dict[str, Any], api_user: Dict[str, Any]) -> Tuple[str, str]:
    """生成姓名：优先使用本地词库，否则使用 API 返回值"""
    if "local_last_names" in config and "local_first_names" in config:
        return random.choice(config["local_first_names"]), random.choice(config["local_last_names"])
    
    first = api_user.get("name", {}).get("first") or config["default_first_name"]
    last = api_user.get("name", {}).get("last") or config["default_last_name"]
    return first, last

def _generate_localized_phone(config: Dict[str, Any], api_user: Dict[str, Any]) -> str:
    """生成手机号：优先使用本地规则，否则清洗 API 返回值"""
    if "phone_prefix" in config:
        prefix = random.choice(config["phone_prefix"])
        suffix_len = config.get("phone_length", 11) - len(prefix)
        suffix = "".join(str(random.randint(0, 9)) for _ in range(suffix_len))
        return f"{prefix}{suffix}"
    
    phone_raw = api_user.get("cell") or api_user.get("phone") or ""
    phone = re.sub(r"\D", "", phone_raw)
    return phone or config["default_phone"]

def _generate_random_dates() -> Dict[str, str]:
    """生成合法的随机日期集合（出行、护照等）"""
    today = datetime.today()
    base_date = today + timedelta(days=random.randint(20, 90))
    
    # 护照日期（避免闰年 replace 报错，采用天数计算）
    start_date = today - timedelta(days=5 * 365)
    passport_issue = start_date + timedelta(days=random.randint(0, (today - start_date).days))
    passport_expiry = passport_issue + timedelta(days=10 * 365 + 2) - timedelta(days=1)
    
    return {
        "departure_origin_date": (base_date - timedelta(days=random.randint(0, 2))).strftime("%Y-%m-%d"),
        "arrival_schengen_area_date": base_date.strftime("%Y-%m-%d"),
        "departure_schengen_area_date": (base_date + timedelta(days=random.randint(2, 15))).strftime("%Y-%m-%d"),
        "passport_issue_date": passport_issue.strftime("%Y-%m-%d"),
        "passport_expiry_date": passport_expiry.strftime("%Y-%m-%d"),
    }

def _generate_email(first_name: str, last_name: str) -> str:
    """基于姓名生成随机邮箱"""
    email_prefix = re.sub(r"[^a-z0-9]", "", f"{first_name}{last_name}".lower())
    if not email_prefix:
        email_prefix = f"user{random.randint(100000, 999999)}"
    return f"{email_prefix}{random.randint(1000, 9999)}@text.skin"

# ==========================================
# 3. 主函数
# ==========================================

def generate_random_account_detail(country_code: str = "CN") -> Dict[str, Any]:
    """
    基于 randomuser 和指定国家配置生成随机账户信息。
    """
    config = COUNTRY_CONFIGS.get(country_code)
    if not config:
        raise ValueError(f"Unsupported country code: {country_code}")

    # 1. 抓取 API（即使不支持的国家，也可借用其随机返回的年龄/性别）
    api_user = _fetch_random_user_data(config.get("nat_code"))

    # 2. 解析基础数据（本地化拦截器）
    first_name, last_name = _generate_localized_name(config, api_user)
    phone_number = _generate_localized_phone(config, api_user)
    
    gender_raw = str(api_user.get("gender", "")).strip().lower()
    gender = "Male" if gender_raw == "male" else "Female"
    
    birthday_raw = api_user.get("dob", {}).get("date", "")
    birthday = birthday_raw[:10] if birthday_raw else "1990-01-01"
    
    # 3. 各种衍生计算
    email = _generate_email(first_name, last_name)
    dates = _generate_random_dates()
    
    app_form_suffix = "".join(str(random.randint(0, 9)) for _ in range(11))
    passport_no = "".join(random.choices("ABCDEFGHIJKLMNOPQRSTUVWXYZ", k=2)) + \
                  "".join(random.choices("0123456789", k=7))
    fra1_prefix = config.get('fra1')
    # LO 伦敦 DB 都柏林 PB 北京 SH 上海 HN 杭州 CB 广州
    # 4. 组装组装并返回
    return {
        "pool_name": config["pool_name"],
        "email": email,
        "pwd": DEFAULT_PASSWORD,
        "location": config["location"],
        "visa_type": VISA_TYPE,
        "travel_purpose": TRAVEL_PURPOSE,
        "application_form_id": f"{fra1_prefix}{app_form_suffix}",
        "last_name": last_name,
        "first_name": first_name,
        "gender": gender,
        "birthday": birthday,
        "nationality": config["nationality"],
        "province_residence": config["province_residence"],
        "passport_type": PASSPORT_TYPE,
        "passport_no": passport_no,
        "passport_issue_date": dates["passport_issue_date"],
        "passport_expiry_date": dates["passport_expiry_date"],
        "phone_country_code": config["phone_country_code"],
        "phone_number": phone_number,
        "departure_origin_date": dates["departure_origin_date"],
        "arrival_schengen_area_date": dates["arrival_schengen_area_date"],
        "departure_schengen_area_date": dates["departure_schengen_area_date"],
    }

# 测试代码
if __name__ == "__main__":
    print("--- 🇨🇳 中国数据 (借用API年龄性别 + 本地化姓名/手机) ---")
    print(generate_random_account_detail("CN"))

    print("\n--- 🇬🇧 英国数据 (完全依赖API生成) ---")
    print(generate_random_account_detail("GB"))