"""Search API 数据模型"""

from typing import Optional, List, Dict, Any
from pydantic import Field, field_validator
from .base import OctenBaseModel
from ..utils.constants import (
    SEARCH_TYPES,
    TIME_BASIS_OPTIONS,
    FORMAT_OPTIONS,
    SAFESEARCH_OPTIONS,
)


class HighlightOptions(OctenBaseModel):
    """高亮选项配置

    Attributes:
        enable: 是否返回高亮内容
        max_tokens: 高亮内容的最大 token 数
    """

    enable: bool = Field(True, description="是否返回高亮")
    max_tokens: int = Field(
        300,
        ge=100,
        le=2048,
        description="高亮最大 tokens",
    )


class FullContentOptions(OctenBaseModel):
    """完整内容选项配置

    Attributes:
        enable: 是否返回完整内容
        max_tokens: 完整内容的最大 token 数
    """

    enable: bool = Field(False, description="是否返回完整内容")
    max_tokens: int = Field(
        1000,
        ge=1,
        le=100000,
        description="内容最大 tokens",
    )


class SearchRequest(OctenBaseModel):
    """Search API 请求模型

    Attributes:
        query: 搜索查询字符串
        search_type: 搜索类型（auto/keyword/semantic）
        count: 返回结果数量
        include_domains: 包含的域名列表
        exclude_domains: 排除的域名列表
        include_text: 必须包含的文本列表
        exclude_text: 必须排除的文本列表
        time_basis: 时间基准（auto/published/crawled）
        start_time: 开始时间（ISO 8601 格式）
        end_time: 结束时间（ISO 8601 格式）
        highlight: 高亮选项
        format: 内容格式（text/markdown）
        safesearch: 安全搜索级别（off/strict）
        full_content: 完整内容选项
    """

    query: str = Field(
        ...,
        max_length=500,
        description="搜索查询",
    )
    search_type: Optional[str] = Field(
        "auto",
        description="搜索类型: auto/keyword/semantic",
    )
    count: Optional[int] = Field(
        5,
        ge=1,
        le=100,
        description="结果数量",
    )
    include_domains: Optional[List[str]] = Field(
        None,
        description="包含域名",
    )
    exclude_domains: Optional[List[str]] = Field(
        None,
        description="排除域名",
    )
    include_text: Optional[List[str]] = Field(
        None,
        description="必须包含的文本",
    )
    exclude_text: Optional[List[str]] = Field(
        None,
        description="必须排除的文本",
    )
    time_basis: Optional[str] = Field(
        "auto",
        description="时间基准: auto/published/crawled",
    )
    start_time: Optional[str] = Field(
        None,
        description="开始时间 ISO 8601",
    )
    end_time: Optional[str] = Field(
        None,
        description="结束时间 ISO 8601",
    )
    highlight: Optional[HighlightOptions] = Field(
        None,
        description="高亮选项",
    )
    format: Optional[str] = Field(
        "text",
        description="格式: text/markdown",
    )
    safesearch: Optional[str] = Field(
        "strict",
        description="安全搜索: off/strict",
    )
    full_content: Optional[FullContentOptions] = Field(
        None,
        description="完整内容选项",
    )

    @field_validator("search_type")
    @classmethod
    def validate_search_type(cls, v: Optional[str]) -> Optional[str]:
        """验证搜索类型"""
        if v is not None and v not in SEARCH_TYPES:
            raise ValueError(f"search_type 必须是 {SEARCH_TYPES} 之一")
        return v

    @field_validator("time_basis")
    @classmethod
    def validate_time_basis(cls, v: Optional[str]) -> Optional[str]:
        """验证时间基准"""
        if v is not None and v not in TIME_BASIS_OPTIONS:
            raise ValueError(f"time_basis 必须是 {TIME_BASIS_OPTIONS} 之一")
        return v

    @field_validator("format")
    @classmethod
    def validate_format(cls, v: Optional[str]) -> Optional[str]:
        """验证格式"""
        if v is not None and v not in FORMAT_OPTIONS:
            raise ValueError(f"format 必须是 {FORMAT_OPTIONS} 之一")
        return v

    @field_validator("safesearch")
    @classmethod
    def validate_safesearch(cls, v: Optional[str]) -> Optional[str]:
        """验证安全搜索"""
        if v is not None and v not in SAFESEARCH_OPTIONS:
            raise ValueError(f"safesearch 必须是 {SAFESEARCH_OPTIONS} 之一")
        return v


class SearchResult(OctenBaseModel):
    """搜索结果项

    Attributes:
        title: 页面标题
        url: 页面 URL
        highlight: 高亮摘要
        full_content: 完整内容
        authors: 作者信息
        time_published: 发布时间
        time_last_crawled: 最后爬取时间
    """

    title: str = Field(..., description="标题")
    url: str = Field(..., description="URL")
    highlight: Optional[str] = Field(None, description="高亮摘要")
    full_content: Optional[str] = Field(None, description="完整内容")
    authors: Optional[str] = Field(None, description="作者")
    time_published: Optional[str] = Field(None, description="发布时间")
    time_last_crawled: Optional[str] = Field(None, description="最后爬取时间")


class SearchResponse(OctenBaseModel):
    """Search API 响应模型

    Attributes:
        code: 响应码（0 表示成功）
        msg: 响应消息
        data: 响应数据
        meta: 元数据（包含 usage、latency 等）
    """

    code: int = Field(..., description="响应码")
    msg: str = Field(..., description="响应消息")
    data: Dict[str, Any] = Field(..., description="响应数据")
    meta: Dict[str, Any] = Field(..., description="元数据")

    @property
    def results(self) -> List[Dict[str, Any]]:
        """获取搜索结果列表"""
        return self.data.get("results", [])

    @property
    def query(self) -> Optional[str]:
        """获取查询字符串"""
        return self.data.get("query")

    @property
    def search_type(self) -> Optional[str]:
        """获取实际使用的搜索类型"""
        return self.data.get("search_type")

    @property
    def usage(self) -> Optional[Dict[str, Any]]:
        """获取使用量信息"""
        return self.meta.get("usage")

    @property
    def latency(self) -> Optional[Dict[str, Any]]:
        """获取延迟信息"""
        return self.meta.get("latency")

    @property
    def warning(self) -> Optional[str]:
        """获取警告信息"""
        return self.meta.get("warning")
