"""Pydantic request/response models for criteria API."""

from __future__ import annotations
from typing import Any, Optional
from pydantic import BaseModel


class CriteriaGenerateRequest(BaseModel):
    project_description: str
    research_questions: list[str] = []
    additional_notes: str = ""
    existing_criteria: list[dict[str, Any]] = []
    criterion_type: str = "exclude"  # "include" or "exclude"
    model: str = "gpt-4.1"
    mock: bool = False


class PICOExtractRequest(BaseModel):
    project_description: str
    research_questions: list[str] = []
    model: str = "gpt-4.1"
    mock: bool = False


class CriteriaRefineRequest(BaseModel):
    current_criteria: list[dict[str, Any]]
    conflicts: list[dict[str, Any]] = []
    project_description: str = ""
    model: str = "gpt-4.1"
    mock: bool = False


class CriterionResponse(BaseModel):
    category: str
    text: str
    description: str = ""
    criterion_type: str = "exclude"
    confidence: Optional[float] = None
    rationale: Optional[str] = None
    title_abstract_assessable: bool = True


class CriteriaGenerateResponse(BaseModel):
    criteria: list[CriterionResponse]


class PICOExtractResponse(BaseModel):
    elements: dict[str, Any]
    gap_flags: list[str] = []
    contraindications: list[dict[str, Any]] = []


class ContextRefineRequest(BaseModel):
    description: str
    research_questions: list[str] = []
    model: str = "gpt-4.1"
    mock: bool = False


class ContextRefineResponse(BaseModel):
    refined_description: str
    refined_research_questions: list[str]
    explanation: str


class ConsolidateRequest(BaseModel):
    criteria: list[dict[str, Any]]
    project_description: str = ""
    research_questions: list[str] = []
    model: str = "gpt-4.1"
    mock: bool = False


class DuplicateGroupResponse(BaseModel):
    group_type: str
    category: str
    criterion_ids: list[int]
    recommended_primary_id: int
    merge_rationale: str
    ai_confidence: float


class ConsolidationProposalResponse(BaseModel):
    category: str
    criterion_ids: list[int]
    proposed_merged_criterion: str
    proposed_description: str
    proposed_type: str
    merge_rationale: str
    ai_confidence: float


class ConsolidateResponse(BaseModel):
    duplicate_groups: list[DuplicateGroupResponse] = []
    consolidation_proposals: list[ConsolidationProposalResponse] = []
    warnings: list[str] = []


class QuestionAnalysisRequest(BaseModel):
    """Request to analyse a single research question for search-readiness."""

    research_question: str
    model: str = "gpt-5-mini"
    mock: bool = False


class QuestionAnalysisResponse(BaseModel):
    """PICOS analysis result for a single research question.

    `status` is one of "ready" or "could_improve" — kept as `str` (not Literal) to
    stay consistent with the rest of this schema file, which uses
    `from __future__ import annotations` and would need `model_rebuild()` for Literal.
    """

    status: str
    missing_elements: list[str] = []
    suggestion: str
