"""
数据模型 — 邮箱/收件人/变量/内容/服务器/DNS账号等
"""
from dataclasses import dataclass, field
from typing import List, Optional
import threading
import time


@dataclass
class MailBox:
    id: int = 0
    enable: bool = True
    sender_name: str = ""
    user: str = ""
    email: str = ""
    pwd: str = ""
    smtp: str = ""
    port: int = 25
    ssl_tls: str = "none"
    day_max_count: int = 0
    day_sent: int = 0
    day_first_time: str = ""
    sent: int = 0
    sent_succ: int = 0
    sent_after_disable: int = 0
    fail_after_disable: int = 5
    succ_after_disable: int = 0
    series_fail: int = 0
    pause_second: int = 0
    pause_first_time: str = ""
    pause_second_limit: bool = False
    random_user: bool = False
    info: str = ""
    box_type: int = 1
    locker: threading.Lock = field(default_factory=threading.Lock)
    oauth_client_id: str = ""
    oauth_client_secret: str = ""
    oauth_access_token: str = ""
    oauth_refresh_token: str = ""
    oauth_token_expires: float = 0.0

    def can_send(self) -> bool:
        if not self.enable:
            return False
        if self.day_max_count > 0 and self.day_sent >= self.day_max_count:
            return False
        if self.fail_after_disable > 0 and self.series_fail >= self.fail_after_disable:
            return False
        if self.sent_after_disable > 0 and self.sent >= self.sent_after_disable:
            return False
        if self.succ_after_disable > 0 and self.sent_succ >= self.succ_after_disable:
            return False
        return True

    def reset_daily(self):
        today = time.strftime('%Y-%m-%d')
        if self.day_first_time != today:
            self.day_sent = 0
            self.day_first_time = today


@dataclass
class Email:
    email_address: str = ""
    name: str = ""
    info: str = ""
    var_text: str = ""
    image_index: int = 0
    is_highlight: bool = False
    subject: str = ""
    content: str = ""
    tid: str = ""
    source: str = "manual"


@dataclass
class Variable:
    var_name: str = ""
    note: str = ""
    describe: str = ""
    var_content: List[str] = field(default_factory=list)
    is_multi_not_same: bool = False
    is_custom_type: bool = False
    is_seq: bool = False
    change_times: int = 1
    use_times: int = 0
    id: int = 0
    locker: threading.Lock = field(default_factory=threading.Lock)


@dataclass
class Content:
    enable: bool = True
    content_text: str = ""
    note: str = ""
    mail_type: int = 1
    is_highlight: bool = False


@dataclass
class SubjectEx:
    enable: bool = True
    subject: str = ""
    is_highlight: bool = False


@dataclass
class Attachment:
    filename: str = ""
    file_path: str = ""
    content_id: str = ""
    is_inline: bool = False


@dataclass
class ProxyIP:
    id: int = 0
    ip: str = ""
    port: int = 0
    proxy_type: str = "socks5"
    username: str = ""
    pwd: str = ""
    enable: bool = True
    use_count: int = 0
    fail_count: int = 0


@dataclass
class ServerConfig:
    hostname: str = ""
    username: str = "root"
    password: str = ""
    port: int = 22
    domain: str = ""
    email_user: str = ""
    email_pass: str = ""
    subdomain: str = ""
    status: str = ""
    info: str = ""
    mta_type: str = ""
    ssh_key_path: str = ""
    token: str = ""
    dns_provider: str = "cloudflare"
    server_type: str = ""
    admin_pass: str = ""

    def parse_from_line(self, line: str, separator: str = '----'):
        parts = [p.strip() for p in line.split(separator)]
        if len(parts) >= 1:
            self.hostname = parts[0]
        if len(parts) >= 2:
            self.username = parts[1]
        if len(parts) >= 3:
            self.password = parts[2]
        if len(parts) >= 4:
            try:
                self.port = int(parts[3])
            except ValueError:
                self.port = 22
        if len(parts) >= 5:
            self.domain = parts[4]
        if len(parts) >= 6:
            self.email_user = parts[5]
        if len(parts) >= 7:
            self.email_pass = parts[6]
        if len(parts) >= 8:
            self.subdomain = parts[7]


@dataclass
class DNSAccount:
    id: int = 0
    provider: str = "cloudflare"
    label: str = ""
    api_email: str = ""
    api_key: str = ""
    access_key_id: str = ""
    access_key_secret: str = ""
    api_token: str = ""
    zone_count: int = 0
    enable: bool = True


@dataclass
class DomainInfo:
    domain: str = ""
    account_id: int = 0
    provider: str = ""
    zone_id: str = ""
    record_count: int = 0
    has_mx: bool = False
    has_spf: bool = False
    has_dkim: bool = False
    has_dmarc: bool = False
    status: str = ""


@dataclass
class SendStats:
    total: int = 0
    success: int = 0
    fail: int = 0
    start_time: float = 0.0
    inbox_count: int = 0
    adjust_count: int = 0
    bounce_count: int = 0
    open_count: int = 0

    @property
    def elapsed(self) -> float:
        if self.start_time:
            return time.time() - self.start_time
        return 0

    @property
    def speed(self) -> float:
        if self.elapsed > 0:
            return (self.success + self.fail) / self.elapsed
        return 0

    @property
    def inbox_rate(self) -> float:
        if self.success > 0:
            return self.inbox_count / self.success
        return 0

    @property
    def open_rate(self) -> float:
        if self.success > 0:
            return self.open_count / self.success
        return 0


@dataclass
class SmartRule:
    enabled: bool = True
    trigger: str = ""
    action: str = ""
    last_triggered: float = 0
    trigger_count: int = 0


@dataclass
class BounceRecord:
    email: str = ""
    reason: str = ""
    smtp_code: str = ""
    category: str = ""
    timestamp: float = 0
