from __future__ import annotations

from dataclasses import dataclass, field
from typing import Any, Optional


@dataclass
class StructureJobSubmission:
    success: bool
    message: str
    job_id: Optional[str] = None

    @classmethod
    def from_dict(cls, data: dict) -> StructureJobSubmission:
        return cls(
            success=data.get("success", False),
            message=data.get("message", ""),
            job_id=data.get("job_id"),
        )


@dataclass
class StructureJob:
    job_id: str
    job_name: str
    status: str
    total_files: int = 0
    completed: int = 0
    failed: int = 0
    pending: int = 0
    created_at: Optional[str] = None
    completed_at: Optional[str] = None

    @classmethod
    def from_dict(cls, data: dict) -> StructureJob:
        return cls(
            job_id=data.get("job_id", ""),
            job_name=data.get("job_name", ""),
            status=data.get("status", ""),
            total_files=data.get("total_files", 0),
            completed=data.get("completed", 0),
            failed=data.get("failed", 0),
            pending=data.get("pending", 0),
            created_at=data.get("created_at"),
            completed_at=data.get("completed_at"),
        )


@dataclass
class StructureFileStatus:
    file_name: str
    status: str
    model: str = ""
    id: Optional[int] = None
    mean_plddt: Optional[float] = None
    clash_score: Optional[float] = None
    affinity_score: Optional[float] = None
    alias: Optional[str] = None
    created_at: Optional[str] = None
    updated_at: Optional[str] = None

    @classmethod
    def from_dict(cls, data: dict) -> StructureFileStatus:
        return cls(
            file_name=data.get("file_name", ""),
            status=data.get("status", ""),
            model=data.get("model", ""),
            id=data.get("id"),
            mean_plddt=data.get("mean_plddt"),
            clash_score=data.get("clash_score"),
            affinity_score=data.get("affinity_score"),
            alias=data.get("alias"),
            created_at=data.get("created_at"),
            updated_at=data.get("updated_at"),
        )


@dataclass
class StructureJobStatus:
    success: bool
    job_id: Optional[str] = None
    job_name: Optional[str] = None
    job_status: Optional[str] = None
    total_files: int = 0
    completed: int = 0
    failed: int = 0
    pending: int = 0
    files: list[StructureFileStatus] = field(default_factory=list)

    @classmethod
    def from_dict(cls, data: dict) -> StructureJobStatus:
        return cls(
            success=data.get("success", False),
            job_id=data.get("job_id"),
            job_name=data.get("job_name"),
            job_status=data.get("job_status"),
            total_files=data.get("total_files", 0),
            completed=data.get("completed", 0),
            failed=data.get("failed", 0),
            pending=data.get("pending", 0),
            files=[StructureFileStatus.from_dict(f) for f in data.get("files", [])],
        )


@dataclass
class StructureMetrics:
    mean_plddt: Optional[float] = None
    clash_score: Optional[float] = None
    affinity_score: Optional[float] = None

    @classmethod
    def from_dict(cls, data: dict) -> StructureMetrics:
        return cls(
            mean_plddt=data.get("mean_plddt"),
            clash_score=data.get("clash_score"),
            affinity_score=data.get("affinity_score"),
        )


@dataclass
class StructurePredictionResult:
    success: bool
    message: Optional[str] = None
    id: Optional[int] = None
    job_name: Optional[str] = None
    file_name: Optional[str] = None
    status: Optional[str] = None
    model: Optional[str] = None
    structure_content: Optional[str] = None
    confidence_json: Optional[dict[str, Any]] = None
    metrics: Optional[StructureMetrics] = None
    alias: Optional[str] = None
    created_at: Optional[str] = None
    updated_at: Optional[str] = None

    @classmethod
    def from_dict(cls, data: dict) -> StructurePredictionResult:
        metrics_raw = data.get("metrics")
        return cls(
            success=data.get("success", False),
            message=data.get("message"),
            id=data.get("id"),
            job_name=data.get("job_name"),
            file_name=data.get("file_name"),
            status=data.get("status"),
            model=data.get("model"),
            structure_content=data.get("structure_content"),
            confidence_json=data.get("confidence_json"),
            metrics=StructureMetrics.from_dict(metrics_raw) if metrics_raw else None,
            alias=data.get("alias"),
            created_at=data.get("created_at"),
            updated_at=data.get("updated_at"),
        )
