from __future__ import annotations

from datetime import datetime
from typing import Any, Dict, List, Optional

from pydantic import BaseModel, Field


class CodeKnowledgeBaseCreate(BaseModel):
    name: str = Field(..., min_length=1)
    project_path: Optional[str] = None
    vector_path: str = Field(..., min_length=1)
    metadata_path: str = Field(..., min_length=1)
    graph_path: str = Field(..., min_length=1)


class CodeKnowledgeBaseUploadResponse(BaseModel):
    id: int
    status: str


class CodeKnowledgeBaseResponse(BaseModel):
    id: int
    name: str
    project_path: Optional[str] = None
    vector_path: str
    metadata_path: str
    graph_path: str
    status: str
    metadata_summary: Optional[Dict[str, Any]] = None
    created_at: datetime
    updated_at: datetime

    class Config:
        from_attributes = True


class CodeQuestionRequest(BaseModel):
    question: str = Field(..., min_length=1)
    top_k: int = Field(default=6, ge=1, le=20)
    min_similarity: float = Field(default=0.0, ge=0.0, le=1.0)
    use_llm: bool = True


class CodeQuestionResponse(BaseModel):
    answer: str
    evidence: List[Dict[str, Any]]
    raw_response: Optional[str] = None


class ConsistencyJobCreate(BaseModel):
    srs_extraction_id: int
    code_kb_id: int
    requirement_uids: Optional[List[str]] = None
    top_k: int = Field(default=8, ge=1, le=30)
    max_call_hops: int = Field(default=2, ge=0, le=4)
    min_similarity: float = Field(default=0.55, ge=0.0, le=1.0)
    use_llm: bool = True


class ConsistencyJobCreateResponse(BaseModel):
    job_id: int
    status: str


class AutoConsistencyJobCreateResponse(BaseModel):
    job_id: int
    status: str


class AutoConsistencyJobStatusResponse(BaseModel):
    job_id: int
    status: str
    error_message: Optional[str] = None
    current_step: Optional[str] = None
    srs_extraction_id: Optional[int] = None
    code_kb_id: Optional[int] = None
    consistency_job_id: Optional[int] = None
    created_at: datetime
    updated_at: datetime


class ConsistencyJobResponse(BaseModel):
    id: int
    srs_extraction_id: int
    code_kb_id: int
    status: str
    total_requirements: int
    completed_requirements: int
    output_summary: Optional[Dict[str, Any]] = None
    error_message: Optional[str] = None
    started_at: Optional[datetime] = None
    completed_at: Optional[datetime] = None
    created_at: datetime
    updated_at: datetime

    class Config:
        from_attributes = True


class ConsistencyResultResponse(BaseModel):
    id: int
    job_id: int
    requirement_uid: str
    verdict: str
    coverage_score: float
    confidence: float
    matched_functions: List[Dict[str, Any]]
    covered_points: List[str]
    missing_points: List[str]
    conflict_points: List[str]
    call_chain_evidence: List[str]
    suggestion: Optional[str] = None
    raw_judgment: Optional[Dict[str, Any]] = None
    created_at: datetime
    updated_at: datetime

    class Config:
        from_attributes = True
