"""Data models for Kawaa API responses."""

from dataclasses import dataclass, field
from enum import Enum
from typing import Any, Dict, List, Optional


class VerificationStatus(str, Enum):
    """Email verification status."""

    VALID = "valid"
    INVALID = "invalid"
    RISKY = "risky"
    UNKNOWN = "unknown"


class JobStatus(str, Enum):
    """Batch job status."""

    PENDING = "pending"
    PROCESSING = "processing"
    COMPLETED = "completed"
    FAILED = "failed"


@dataclass
class VerificationFlags:
    """Flags indicating email characteristics."""

    disposable: bool = False
    role: bool = False
    free_provider: bool = False
    catch_all: bool = False

    @classmethod
    def from_dict(cls, data: Dict[str, Any]) -> "VerificationFlags":
        """Create from API response dict."""
        return cls(
            disposable=data.get("disposable", False),
            role=data.get("role", False),
            free_provider=data.get("free_provider", False),
            catch_all=data.get("catch_all", False),
        )


@dataclass
class VerificationDetails:
    """Technical verification details."""

    mx_records: List[str] = field(default_factory=list)
    smtp_response: Optional[str] = None

    @classmethod
    def from_dict(cls, data: Dict[str, Any]) -> "VerificationDetails":
        """Create from API response dict."""
        return cls(
            mx_records=data.get("mx_records", []),
            smtp_response=data.get("smtp_response"),
        )


@dataclass
class VerificationResult:
    """Result of a single email verification."""

    email: str
    status: VerificationStatus
    score: int
    flags: VerificationFlags
    suggestion: Optional[str] = None
    verification: Optional[VerificationDetails] = None
    reason: Optional[str] = None

    @classmethod
    def from_dict(cls, data: Dict[str, Any]) -> "VerificationResult":
        """Create from API response dict."""
        flags_data = data.get("flags", {})
        # Handle flat structure or nested flags
        if not flags_data and any(k in data for k in ["disposable", "role", "free_provider"]):
            flags_data = {
                "disposable": data.get("disposable", False),
                "role": data.get("role", False),
                "free_provider": data.get("free_provider", False),
                "catch_all": data.get("catch_all", False),
            }

        verification_data = data.get("verification", {})

        return cls(
            email=data.get("email", ""),
            status=VerificationStatus(data.get("status", "unknown")),
            score=data.get("quality_score", data.get("score", 0)),
            flags=VerificationFlags.from_dict(flags_data),
            suggestion=data.get("suggestion"),
            verification=VerificationDetails.from_dict(verification_data) if verification_data else None,
            reason=data.get("reason"),
        )

    @property
    def is_valid(self) -> bool:
        """Check if email is valid."""
        return self.status == VerificationStatus.VALID

    @property
    def is_deliverable(self) -> bool:
        """Check if email is likely deliverable (valid or risky with high score)."""
        return self.status == VerificationStatus.VALID or (
            self.status == VerificationStatus.RISKY and self.score >= 70
        )


@dataclass
class BatchJobResult:
    """Result of creating a batch verification job."""

    job_id: str
    status: JobStatus
    total_submitted: int
    duplicates_removed: int
    unique_emails: int
    credits_used: int
    credits_remaining: int
    message: Optional[str] = None

    @classmethod
    def from_dict(cls, data: Dict[str, Any]) -> "BatchJobResult":
        """Create from API response dict."""
        return cls(
            job_id=data.get("job_id", ""),
            status=JobStatus(data.get("status", "pending")),
            total_submitted=data.get("total_submitted", 0),
            duplicates_removed=data.get("duplicates_removed", 0),
            unique_emails=data.get("unique_emails", 0),
            credits_used=data.get("credits_used", 0),
            credits_remaining=data.get("credits_remaining", 0),
            message=data.get("message"),
        )


@dataclass
class JobStatusResult:
    """Status of a batch verification job."""

    job_id: str
    status: JobStatus
    total_emails: int
    processed_emails: int
    valid_count: int
    invalid_count: int
    risky_count: int
    unknown_count: int
    progress_percent: float
    created_at: Optional[str] = None
    completed_at: Optional[str] = None
    results: List[VerificationResult] = field(default_factory=list)

    @classmethod
    def from_dict(cls, data: Dict[str, Any]) -> "JobStatusResult":
        """Create from API response dict."""
        results = []
        if "results" in data:
            results = [VerificationResult.from_dict(r) for r in data["results"]]

        return cls(
            job_id=data.get("job_id", ""),
            status=JobStatus(data.get("status", "pending")),
            total_emails=data.get("total_emails", 0),
            processed_emails=data.get("processed_emails", 0),
            valid_count=data.get("valid_count", 0),
            invalid_count=data.get("invalid_count", 0),
            risky_count=data.get("risky_count", 0),
            unknown_count=data.get("unknown_count", 0),
            progress_percent=data.get("progress_percent", 0.0),
            created_at=data.get("created_at"),
            completed_at=data.get("completed_at"),
            results=results,
        )

    @property
    def is_completed(self) -> bool:
        """Check if job is completed."""
        return self.status == JobStatus.COMPLETED

    @property
    def is_failed(self) -> bool:
        """Check if job failed."""
        return self.status == JobStatus.FAILED


@dataclass
class DownloadResult:
    """Result of downloading job results."""

    job_id: str
    result_count: int
    results: List[VerificationResult] = field(default_factory=list)
    download_url: Optional[str] = None
    expires_in_seconds: Optional[int] = None

    @classmethod
    def from_dict(cls, data: Dict[str, Any]) -> "DownloadResult":
        """Create from API response dict."""
        results = []
        if "results" in data:
            results = [VerificationResult.from_dict(r) for r in data["results"]]

        return cls(
            job_id=data.get("job_id", ""),
            result_count=data.get("result_count", 0),
            results=results,
            download_url=data.get("download_url"),
            expires_in_seconds=data.get("expires_in_seconds"),
        )


@dataclass
class AccountInfo:
    """User account information."""

    user_id: str
    email: str
    plan: str
    credits_remaining: int
    credits_used: int
    created_at: str

    @classmethod
    def from_dict(cls, data: Dict[str, Any]) -> "AccountInfo":
        """Create from API response dict."""
        return cls(
            user_id=data.get("user_id", ""),
            email=data.get("email", ""),
            plan=data.get("plan", "free"),
            credits_remaining=data.get("credits_remaining", 0),
            credits_used=data.get("credits_used", 0),
            created_at=data.get("created_at", ""),
        )


@dataclass
class FindResult:
    """Email finder result."""

    email: Optional[str]
    confidence: int
    pattern: Optional[str]
    verified: bool
    status: str
    quality_score: int
    flags: VerificationFlags
    candidates_checked: int
    credits_used: int
    credits_remaining: int
    message: Optional[str] = None

    @property
    def found(self) -> bool:
        """Whether an email was found."""
        return self.email is not None and self.confidence > 0

    @classmethod
    def from_dict(cls, data: Dict[str, Any]) -> "FindResult":
        """Create from API response dict."""
        flags_data = data.get("flags", {})
        flags = VerificationFlags.from_dict(flags_data) if flags_data else VerificationFlags()

        return cls(
            email=data.get("email"),
            confidence=data.get("confidence", 0),
            pattern=data.get("pattern"),
            verified=data.get("verified", False),
            status=data.get("status", "not_found"),
            quality_score=data.get("quality_score", 0),
            flags=flags,
            candidates_checked=data.get("candidates_checked", 0),
            credits_used=data.get("credits_used", 0),
            credits_remaining=data.get("credits_remaining", 0),
            message=data.get("message"),
        )
