from __future__ import annotations

from datetime import datetime
from typing import Any

from pydantic import BaseModel, Field, field_validator, model_validator

from flow_xhs.platform.search_filters import normalize_filter_value


class CommonInput(BaseModel):
    trace_id: str | None = None
    account_uid: str | None = None


class NoteSearchInput(CommonInput):
    keyword: str = Field(min_length=1)
    size: int = Field(default=20, ge=1, le=100)
    sort_by: str | None = None
    note_type: str | None = None
    publish_time: str | None = None
    search_scope: str | None = None
    location: str | None = None

    @field_validator("sort_by", mode="before")
    @classmethod
    def _normalize_sort_by(cls, value: str | None) -> str | None:
        return normalize_filter_value("sort_by", value)

    @field_validator("note_type", mode="before")
    @classmethod
    def _normalize_note_type(cls, value: str | None) -> str | None:
        return normalize_filter_value("note_type", value)

    @field_validator("publish_time", mode="before")
    @classmethod
    def _normalize_publish_time(cls, value: str | None) -> str | None:
        return normalize_filter_value("publish_time", value)

    @field_validator("search_scope", mode="before")
    @classmethod
    def _normalize_search_scope(cls, value: str | None) -> str | None:
        return normalize_filter_value("search_scope", value)

    @field_validator("location", mode="before")
    @classmethod
    def _normalize_location(cls, value: str | None) -> str | None:
        return normalize_filter_value("location", value)


class UserSearchInput(CommonInput):
    keyword: str = Field(min_length=1)
    size: int = Field(default=20, ge=1, le=100)


class UserGetInput(CommonInput):
    user_id: str = Field(min_length=1)
    xsec_token: str | None = None
    xsec_source: str | None = "pc_feed"


class NoteGetInput(CommonInput):
    note_id: str = Field(min_length=1)
    xsec_token: str | None = None
    xsec_source: str | None = "pc_feed"
    comment_size: int = Field(default=10, ge=1, le=100)
    sub_comment_size: int = Field(default=5, ge=1, le=50)


class PublishNoteInput(CommonInput):
    target: str = Field(min_length=1)
    image_list: list[str] = Field(default_factory=list)
    video: str | None = None
    title: str = ""
    content: str = ""
    tags: list[str] = Field(default_factory=list)
    schedule_at: str | None = None

    @field_validator("image_list")
    @classmethod
    def _validate_images(cls, value: list[str]) -> list[str]:
        cleaned = [v.strip() for v in value if isinstance(v, str) and v.strip()]
        return cleaned

    @field_validator("video", mode="before")
    @classmethod
    def _validate_video(cls, value: str | None) -> str | None:
        if value is None:
            return None
        if not isinstance(value, str):
            raise ValueError("video 必须是字符串")
        text = value.strip()
        return text or None

    @model_validator(mode="after")
    def _validate_publish_target_media(self) -> "PublishNoteInput":
        target_text = self.target.strip().lower()
        if target_text == "image" and not self.image_list:
            raise ValueError("image_list 至少包含一个有效项")
        if target_text == "video" and not self.video:
            raise ValueError("video 不能为空")
        return self


class AccountListInput(CommonInput):
    only_active: bool = True


class AuthLoginInput(CommonInput):
    pass


class GenericInputEnvelope(BaseModel):
    command: str
    params: dict[str, Any]
    trace_id: str | None = None
    account_uid: str | None = None


class PublishScheduleModel(BaseModel):
    schedule_at: datetime
