"""
数据生成器
生成测试数据和Mock数据
"""
import random
import string
from typing import Optional, List, Dict, Any
from datetime import datetime, timedelta
from faker import Faker as _Faker
from loguru import logger


class DataGenerator:
    """
    数据生成器
    生成各种类型的测试数据
    """
    
    def __init__(self, locale: str = "zh_CN"):
        self._faker = _Faker(locale)
    
    # ==================== 个人信息 ====================
    
    def name(self) -> str:
        """生成姓名"""
        return self._faker.name()
    
    def first_name(self) -> str:
        """生成名"""
        return self._faker.first_name()
    
    def last_name(self) -> str:
        """生成姓"""
        return self._faker.last_name()
    
    def email(self, domain: str = None) -> str:
        """生成邮箱"""
        if domain:
            username = self._faker.user_name()
            return f"{username}@{domain}"
        return self._faker.email()
    
    def phone(self) -> str:
        """生成手机号"""
        return self._faker.phone_number()
    
    def address(self) -> str:
        """生成地址"""
        return self._faker.address()
    
    def city(self) -> str:
        """生成城市"""
        return self._faker.city()
    
    def company(self) -> str:
        """生成公司名"""
        return self._faker.company()
    
    def job_title(self) -> str:
        """生成职位"""
        return self._faker.job()
    
    # ==================== 网络相关 ====================
    
    def url(self) -> str:
        """生成URL"""
        return self._faker.url()
    
    def domain(self) -> str:
        """生成域名"""
        return self._faker.domain_name()
    
    def ip_address(self, version: int = 4) -> str:
        """生成IP地址"""
        if version == 6:
            return self._faker.ipv6()
        return self._faker.ipv4()
    
    def mac_address(self) -> str:
        """生成MAC地址"""
        return self._faker.mac_address()
    
    def user_agent(self) -> str:
        """生成User-Agent"""
        return self._faker.user_agent()
    
    # ==================== 金融相关 ====================
    
    def credit_card_number(self) -> str:
        """生成信用卡号"""
        return self._faker.credit_card_number()
    
    def credit_card_expiry(self) -> str:
        """生成信用卡过期日期"""
        return self._faker.credit_card_expire()
    
    def bank_account(self) -> str:
        """生成银行账号"""
        return self._faker.bban()
    
    def price(self, min_value: float = 1.0, max_value: float = 1000.0) -> float:
        """生成价格"""
        return round(random.uniform(min_value, max_value), 2)
    
    def currency_code(self) -> str:
        """生成货币代码"""
        return random.choice(["CNY", "USD", "EUR", "GBP", "JPY"])
    
    # ==================== 时间日期 ====================
    
    def date(self, start: str = "-30y", end: str = "today") -> str:
        """生成日期"""
        return self._faker.date_between(start_date=start, end_date=end).isoformat()
    
    def datetime(self, start: str = "-30y", end: str = "now") -> datetime:
        """生成日期时间"""
        return self._faker.date_time_between(start_date=start, end_date=end)
    
    def future_date(self, days: int = 30) -> str:
        """生成未来日期"""
        return self._faker.future_date(end_date=f"+{days}d").isoformat()
    
    def past_date(self, days: int = 365) -> str:
        """生成过去日期"""
        return self._faker.past_date(start_date=f"-{days}d").isoformat()
    
    def timestamp(self) -> int:
        """生成时间戳"""
        return int(self._faker.unix_time())
    
    # ==================== 文本内容 ====================
    
    def text(self, max_nb_chars: int = 200) -> str:
        """生成文本"""
        return self._faker.text(max_nb_chars=max_nb_chars)
    
    def sentence(self, nb_words: int = 6) -> str:
        """生成句子"""
        return self._faker.sentence(nb_words=nb_words)
    
    def paragraph(self, nb_sentences: int = 3) -> str:
        """生成段落"""
        return self._faker.paragraph(nb_sentences=nb_sentences)
    
    def word(self) -> str:
        """生成单词"""
        return self._faker.word()
    
    def words(self, nb: int = 3) -> List[str]:
        """生成多个单词"""
        return self._faker.words(nb=nb)
    
    # ==================== 数字和编码 ====================
    
    def int(self, min_value: int = 0, max_value: int = 9999) -> int:
        """生成整数"""
        return random.randint(min_value, max_value)
    
    def float(self, min_value: float = 0, max_value: float = 100, decimals: int = 2) -> float:
        """生成浮点数"""
        return round(random.uniform(min_value, max_value), decimals)
    
    def uuid(self) -> str:
        """生成UUID"""
        return self._faker.uuid4()
    
    def barcode(self, type: str = "ean13") -> str:
        """生成条形码"""
        if type == "ean13":
            return self._faker.ean13()
        elif type == "ean8":
            return self._faker.ean8()
        return self._faker.ean13()
    
    # ==================== 中文特有 ====================
    
    def chinese_name(self) -> str:
        """生成中文姓名"""
        return self._faker.name()
    
    def chinese_id_card(self) -> str:
        """生成身份证号"""
        return self._faker.ssn()
    
    def chinese_phone(self) -> str:
        """生成中国手机号"""
        prefixes = ["130", "131", "132", "133", "135", "136", "137", "138", "139",
                   "150", "151", "152", "153", "155", "156", "157", "158", "159",
                   "180", "181", "182", "183", "184", "185", "186", "187", "188", "189"]
        prefix = random.choice(prefixes)
        suffix = ''.join(random.choices(string.digits, k=8))
        return prefix + suffix
    
    def chinese_address(self) -> str:
        """生成中文地址"""
        return self._faker.address()
    
    # ==================== 批量生成 ====================
    
    def generate_user(self) -> Dict[str, Any]:
        """生成用户数据"""
        return {
            "name": self.name(),
            "email": self.email(),
            "phone": self.phone(),
            "address": self.address(),
            "city": self.city(),
            "company": self.company(),
            "job": self.job_title(),
        }
    
    def generate_users(self, count: int = 10) -> List[Dict[str, Any]]:
        """批量生成用户数据"""
        return [self.generate_user() for _ in range(count)]
    
    def generate_product(self) -> Dict[str, Any]:
        """生成产品数据"""
        return {
            "name": self._faker.product_name() if hasattr(self._faker, 'product_name') else f"产品{self._faker.word()}",
            "price": self.price(),
            "description": self.sentence(),
            "sku": self._faker.bothify(text='SKU-####'),
            "barcode": self.barcode(),
            "stock": self.int(0, 1000),
        }
    
    def generate_products(self, count: int = 10) -> List[Dict[str, Any]]:
        """批量生成产品数据"""
        return [self.generate_product() for _ in range(count)]
    
    def generate_order(self) -> Dict[str, Any]:
        """生成订单数据"""
        products = self.generate_products(random.randint(1, 5))
        total = sum(p["price"] * random.randint(1, 3) for p in products)
        
        return {
            "order_id": self._faker.bothify(text='ORD-######'),
            "user": self.generate_user(),
            "products": products,
            "total": round(total, 2),
            "status": random.choice(["pending", "paid", "shipped", "delivered"]),
            "created_at": self.datetime().isoformat(),
        }
    
    def generate_orders(self, count: int = 10) -> List[Dict[str, Any]]:
        """批量生成订单数据"""
        return [self.generate_order() for _ in range(count)]
    
    # ==================== 自定义生成 ====================
    
    def from_pattern(self, pattern: str) -> str:
        """
        根据模式生成数据
        
        Args:
            pattern: 模式字符串
                # = 数字
                ? = 字母
                * = 数字或字母
                
        Example:
            from_pattern("###-???") -> "123-ABC"
        """
        result = []
        for char in pattern:
            if char == "#":
                result.append(str(random.randint(0, 9)))
            elif char == "?":
                result.append(random.choice(string.ascii_letters))
            elif char == "*":
                result.append(random.choice(string.ascii_letters + string.digits))
            else:
                result.append(char)
        return "".join(result)
    
    def from_template(self, template: Dict[str, Any]) -> Dict[str, Any]:
        """
        根据模板生成数据
        
        Args:
            template: 数据模板
                
        Example:
            template = {
                "name": "{name}",
                "email": "{email}",
                "age": "{int:18,65}",
                "price": "{float:10,100,2}",
            }
        """
        result = {}
        
        for key, value in template.items():
            if isinstance(value, str) and value.startswith("{") and value.endswith("}"):
                # 解析占位符
                placeholder = value[1:-1]
                result[key] = self._parse_placeholder(placeholder)
            else:
                result[key] = value
        
        return result
    
    def _parse_placeholder(self, placeholder: str) -> Any:
        """解析占位符"""
        if ":" in placeholder:
            type_name, params = placeholder.split(":", 1)
            
            if type_name == "int":
                min_v, max_v = map(int, params.split(","))
                return self.int(min_v, max_v)
            elif type_name == "float":
                parts = params.split(",")
                min_v, max_v = float(parts[0]), float(parts[1])
                decimals = int(parts[2]) if len(parts) > 2 else 2
                return self.float(min_v, max_v, decimals)
            elif type_name == "pattern":
                return self.from_pattern(params)
        
        # 直接调用方法
        if hasattr(self, placeholder):
            return getattr(self, placeholder)()
        
        return placeholder


# 全局实例
_generator: Optional[DataGenerator] = None


def get_generator(locale: str = "zh_CN") -> DataGenerator:
    """获取数据生成器实例"""
    global _generator
    if _generator is None:
        _generator = DataGenerator(locale)
    return _generator


# 快捷函数
def fake_name() -> str:
    """生成姓名"""
    return get_generator().name()


def fake_email() -> str:
    """生成邮箱"""
    return get_generator().email()


def fake_phone() -> str:
    """生成手机号"""
    return get_generator().phone()


def fake_address() -> str:
    """生成地址"""
    return get_generator().address()


def fake_user() -> Dict[str, Any]:
    """生成用户数据"""
    return get_generator().generate_user()


def fake_users(count: int = 10) -> List[Dict[str, Any]]:
    """批量生成用户"""
    return get_generator().generate_users(count)


def fake_product() -> Dict[str, Any]:
    """生成产品数据"""
    return get_generator().generate_product()


def fake_order() -> Dict[str, Any]:
    """生成订单数据"""
    return get_generator().generate_order()
