# app/schemas.py
from pydantic import BaseModel
from typing import List, Optional, Dict, Any
from datetime import datetime


# ---------- Project ----------
class ProjectBase(BaseModel):
    name: Optional[str] = None

class ProjectCreate(ProjectBase):
    pdf_filename: str

class ProjectResponse(ProjectBase):
    id: int
    pdf_filename: str
    status: str
    created_at: datetime
    completed_at: Optional[datetime] = None
    error_message: Optional[str] = None
    
    class Config:
        from_attributes = True

class ProjectDetail(ProjectResponse):
    pages: List["PageResponse"] = []
    issues: List["IssueResponse"] = []
    
    class Config:
        from_attributes = True


# ---------- Page ----------
class PageBase(BaseModel):
    page_number: int
    width: Optional[int] = None
    height: Optional[int] = None

class PageResponse(PageBase):
    id: int
    png_path: Optional[str] = None
    vlm_description: Optional[str] = None
    ocr_data: Optional[Dict[str, Any]] = None
    issue_count: int = 0
    
    class Config:
        from_attributes = True


# ---------- Issue ----------
class IssueBase(BaseModel):
    issue_type: str
    severity: str
    message: str
    page_number: Optional[int] = None
    
class IssueCreate(IssueBase):
    bbox_x1: Optional[float] = None
    bbox_y1: Optional[float] = None
    bbox_x2: Optional[float] = None
    bbox_y2: Optional[float] = None
    dimension_text: Optional[str] = None
    confidence: Optional[float] = None
    extra_data: Optional[Dict[str, Any]] = None

class IssueResponse(IssueBase):
    id: int
    project_id: int
    bbox_x1: Optional[float] = None
    bbox_y1: Optional[float] = None
    bbox_x2: Optional[float] = None
    bbox_y2: Optional[float] = None
    dimension_text: Optional[str] = None
    confidence: Optional[float] = None
    source: Optional[str] = None
    created_at: datetime
    feedback: Optional["FeedbackResponse"] = None
    page_id: Optional[int] = None
    
    class Config:
        from_attributes = True


# ---------- Feedback ----------
class FeedbackCreate(BaseModel):
    issue_id: int
    is_true_positive: Optional[bool] = None
    comment: Optional[str] = None
    action_taken: Optional[str] = None  # fixed / ignored / not_sure

class FeedbackResponse(BaseModel):
    id: int
    issue_id: int
    is_true_positive: Optional[bool] = None
    comment: Optional[str] = None
    action_taken: Optional[str] = None
    created_at: datetime
    
    class Config:
        from_attributes = True


# ---------- Stats ----------
class StatsResponse(BaseModel):
    total_projects: int
    total_issues: int
    issues_by_type: Dict[str, int]
    feedback_stats: Dict[str, int]  # true_positive, false_positive, unreviewed
    accuracy_estimate: Optional[float] = None  # Доля правильных срабатываний


# ---------- Training Data ----------
class TrainingSample(BaseModel):
    """Один пример для обучения ML-модели."""
    issue_id: int
    issue_type: str
    severity: str
    message: str
    bbox: Dict[str, float]  # x1, y1, x2, y2
    dimension_text: Optional[str] = None
    confidence: Optional[float] = None
    page_number: int
    is_true_positive: Optional[bool] = None
    
    # Для обучения детектора (YOLO)
    image_path: Optional[str] = None  # Путь к PNG страницы
    crop_path: Optional[str] = None  # Вырезанный фрагмент bbox
    label: Optional[str] = None  # "good_dimension" / "bad_placement" / etc.

class TrainingDataExport(BaseModel):
    total_samples: int
    labeled_samples: int  # Есть is_true_positive
    samples: List[TrainingSample]
    export_format: str  # json / yolo / csv
    
    class Config:
        from_attributes = True
