from pydantic import BaseModel, ConfigDict, Field
from datetime import datetime, date
from typing import Optional, List, Dict, Any


class TopicFieldBase(BaseModel):
    name: str
    icon: Optional[str] = None
    color: Optional[str] = None
    description: Optional[str] = None
    parent_id: Optional[int] = None
    sort_order: int = 0
    is_active: bool = True


class TopicFieldResponse(TopicFieldBase):
    id: int
    created_at: Optional[datetime] = None
    updated_at: Optional[datetime] = None

    model_config = ConfigDict(from_attributes=True)


class TopicConfigFieldBase(BaseModel):
    name: str
    key: str
    field_type: str = "number"
    weight: float = 1.0
    options: List[Any] = []
    min_value: Optional[float] = None
    max_value: Optional[float] = None
    is_required: bool = False
    sort_order: int = 0


class TopicConfigFieldResponse(TopicConfigFieldBase):
    id: int
    field_id: int
    created_at: Optional[datetime] = None

    model_config = ConfigDict(from_attributes=True)


class TopicStatusConfigBase(BaseModel):
    status: str
    label: str
    color: Optional[str] = None
    icon: Optional[str] = None
    sort_order: int = 0
    is_default: bool = False


class TopicStatusConfigResponse(TopicStatusConfigBase):
    id: int
    created_at: Optional[datetime] = None

    model_config = ConfigDict(from_attributes=True)


class TopicBase(BaseModel):
    id: str
    field_id: Optional[int] = None
    field_name: Optional[str] = None
    title: str
    format: Optional[str] = None
    core_concept: Optional[str] = None
    audience_pain: Optional[str] = None
    unique_angle: Optional[str] = None
    priority: Optional[str] = None
    priority_score: int = 0
    total_score: Optional[float] = None
    status: str = "pending"
    tags: List[str] = []
    custom_data: Dict[str, Any] = {}
    scoring_data: Dict[str, Any] = {}
    lock_by: Optional[str] = None
    lock_at: Optional[datetime] = None


class TopicCreate(BaseModel):
    id: Optional[str] = None
    field_id: Optional[int] = None
    title: str
    format: Optional[str] = None
    core_concept: Optional[str] = None
    audience_pain: Optional[str] = None
    unique_angle: Optional[str] = None
    priority: Optional[str] = None
    tags: List[str] = []
    custom_data: Dict[str, Any] = {}
    scoring_data: Dict[str, Any] = {}


class TopicUpdate(BaseModel):
    field_id: Optional[int] = None
    title: Optional[str] = None
    format: Optional[str] = None
    core_concept: Optional[str] = None
    audience_pain: Optional[str] = None
    unique_angle: Optional[str] = None
    priority: Optional[str] = None
    status: Optional[str] = None
    tags: Optional[List[str]] = None
    custom_data: Optional[Dict[str, Any]] = None
    scoring_data: Optional[Dict[str, Any]] = None
    priority_score: Optional[int] = None
    total_score: Optional[float] = None


class TopicResponse(TopicBase):
    created_at: Optional[datetime] = None
    updated_at: Optional[datetime] = None
    generated_at: Optional[datetime] = None
    ready_at: Optional[date] = None
    published_at: Optional[date] = None
    compliance_score: Optional[int] = None
    platform_urls: Dict[str, str] = {}
    cases: List[Any] = []

    model_config = ConfigDict(from_attributes=True)


class TopicScoreRequest(BaseModel):
    scoring_data: Dict[str, Any]


class ArticleBase(BaseModel):
    id: str
    topic_id: str
    platform: str
    file_path: str
    status: str = "draft"
    compliance_score: Optional[int] = None
    word_count: Optional[int] = None
    outline: Optional[str] = None
    created_at: Optional[datetime] = None

    model_config = ConfigDict(from_attributes=True)


class ArticleResponse(ArticleBase):
    html_content: Optional[str] = None

    model_config = ConfigDict(from_attributes=True)


class ContentCalendarBase(BaseModel):
    topic_id: Optional[str] = None
    field_id: Optional[int] = None
    title: str
    planned_date: date
    platform: Optional[str] = None
    status: str = "planned"
    reminder_time: Optional[datetime] = None
    notes: Optional[str] = None


class ContentCalendarCreate(ContentCalendarBase):
    created_by: Optional[str] = None


class ContentCalendarUpdate(BaseModel):
    topic_id: Optional[str] = None
    title: Optional[str] = None
    planned_date: Optional[date] = None
    published_date: Optional[date] = None
    platform: Optional[str] = None
    status: Optional[str] = None
    reminder_time: Optional[datetime] = None
    notes: Optional[str] = None


class ContentCalendarResponse(ContentCalendarBase):
    id: int
    published_date: Optional[date] = None
    created_by: Optional[str] = None
    created_at: Optional[datetime] = None
    updated_at: Optional[datetime] = None

    model_config = ConfigDict(from_attributes=True)


class ContentMetricsBase(BaseModel):
    topic_id: str
    platform: str
    publish_url: Optional[str] = None
    views: int = 0
    likes: int = 0
    favorites: int = 0
    comments: int = 0
    shares: int = 0


class ContentMetricsCreate(ContentMetricsBase):
    data_snapshot: Optional[Dict[str, Any]] = None


class ContentMetricsUpdate(BaseModel):
    publish_url: Optional[str] = None
    views: Optional[int] = None
    likes: Optional[int] = None
    favorites: Optional[int] = None
    comments: Optional[int] = None
    shares: Optional[int] = None
    data_snapshot: Optional[Dict[str, Any]] = None


class ContentMetricsResponse(ContentMetricsBase):
    id: int
    engagement_rate: float = 0
    last_fetched: Optional[datetime] = None
    created_at: Optional[datetime] = None
    updated_at: Optional[datetime] = None

    model_config = ConfigDict(from_attributes=True)


class MediaAssetBase(BaseModel):
    filename: str
    file_path: str
    file_url: Optional[str] = None
    file_type: str
    mime_type: Optional[str] = None
    size: Optional[int] = None
    width: Optional[int] = None
    height: Optional[int] = None
    thumbnail_path: Optional[str] = None
    alt_text: Optional[str] = None
    tags: List[str] = []
    topic_ids: List[str] = []


class MediaAssetCreate(MediaAssetBase):
    uploaded_by: Optional[str] = None


class MediaAssetUpdate(BaseModel):
    alt_text: Optional[str] = None
    tags: Optional[List[str]] = None
    topic_ids: Optional[List[str]] = None


class MediaAssetResponse(MediaAssetBase):
    id: int
    usage_count: int = 0
    uploaded_by: Optional[str] = None
    created_at: Optional[datetime] = None
    updated_at: Optional[datetime] = None

    model_config = ConfigDict(from_attributes=True)


class PlatformConfigBase(BaseModel):
    platform: str
    name: str
    icon: Optional[str] = None
    api_endpoint: Optional[str] = None
    auth_config: Dict[str, Any] = {}
    format_template: Dict[str, Any] = {}
    compliance_rules: Dict[str, Any] = {}
    default_format: Optional[str] = None
    is_active: bool = True


class PlatformConfigCreate(PlatformConfigBase):
    pass


class PlatformConfigUpdate(BaseModel):
    name: Optional[str] = None
    icon: Optional[str] = None
    api_endpoint: Optional[str] = None
    auth_config: Optional[Dict[str, Any]] = None
    format_template: Optional[Dict[str, Any]] = None
    compliance_rules: Optional[Dict[str, Any]] = None
    default_format: Optional[str] = None
    is_active: Optional[bool] = None


class PlatformConfigResponse(PlatformConfigBase):
    id: int
    created_at: Optional[datetime] = None
    updated_at: Optional[datetime] = None

    model_config = ConfigDict(from_attributes=True)


class ContentTaskBase(BaseModel):
    topic_id: Optional[str] = None
    stage: str
    status: str = "pending"
    progress: int = 0
    message: Optional[str] = None


class ContentTaskCreate(BaseModel):
    topic_id: Optional[str] = None
    stage: str
    created_by: Optional[str] = None


class ContentTaskResponse(ContentTaskBase):
    id: int
    task_id: str
    result_data: Dict[str, Any] = {}
    error_msg: Optional[str] = None
    started_at: Optional[datetime] = None
    finished_at: Optional[datetime] = None
    duration: Optional[int] = None
    created_by: Optional[str] = None
    created_at: Optional[datetime] = None

    model_config = ConfigDict(from_attributes=True)


class MetricsDashboard(BaseModel):
    total_topics: int
    topics_by_status: Dict[str, int]
    total_published: int
    total_views: int
    total_likes: int
    avg_engagement_rate: float
    top_topics: List[Dict[str, Any]]
    recent_metrics: List[ContentMetricsResponse]


class CalendarMonthResponse(BaseModel):
    year: int
    month: int
    entries: List[ContentCalendarResponse]
    stats: Dict[str, int]


class AuditLogBase(BaseModel):
    user_id: Optional[int] = None
    username: str
    action: str
    resource_type: Optional[str] = None
    resource_id: Optional[str] = None
    details: Optional[Dict[str, Any]] = None
    ip_address: Optional[str] = None
    user_agent: Optional[str] = None
    created_at: Optional[datetime] = None

    model_config = ConfigDict(from_attributes=True)


class AuditLogResponse(AuditLogBase):
    id: int


class UserBase(BaseModel):
    username: str
    role: str = "user"


class UserCreate(UserBase):
    password: str


class UserUpdate(BaseModel):
    username: Optional[str] = None
    password: Optional[str] = None
    role: Optional[str] = None


class UserResponse(UserBase):
    id: int
    created_at: Optional[datetime] = None

    model_config = ConfigDict(from_attributes=True)


class LoginRequest(BaseModel):
    username: str
    password: str


class TokenResponse(BaseModel):
    token: str
    role: str
    user: UserResponse


class PublishRequest(BaseModel):
    topic_id: str
    platform_urls: Dict[str, str]


class PublishActionRequest(BaseModel):
    action: str
    platform: Optional[str] = None
    status: str
    operator: Optional[str] = None
    description: Optional[str] = None
    suggestion: Optional[str] = None
    url: Optional[str] = None
    error_msg: Optional[str] = None


class PublishRecordResponse(BaseModel):
    id: int
    topic_id: str
    platform: str
    action: str
    status: str
    operator: Optional[str] = None
    description: Optional[str] = None
    suggestion: Optional[str] = None
    url: Optional[str] = None
    error_msg: Optional[str] = None
    created_at: datetime

    model_config = ConfigDict(from_attributes=True)


class CaseBase(BaseModel):
    title: str
    field: str
    summary: str
    key_metrics: Optional[str] = None
    date: Optional[str] = None
    source: str
    source_url: Optional[str] = None
    credibility_rating: Optional[str] = None
    china_applicability: Optional[str] = None


class CaseResponse(CaseBase):
    id: int
    created_at: Optional[datetime] = None
    updated_at: Optional[datetime] = None

    model_config = ConfigDict(from_attributes=True)


class TaskLogBase(BaseModel):
    task_name: str
    topic_id: Optional[str] = None
    status: str
    message: Optional[str] = None
    started_at: Optional[datetime] = None
    finished_at: Optional[datetime] = None
    duration: Optional[int] = None


class TaskLogResponse(TaskLogBase):
    id: int

    model_config = ConfigDict(from_attributes=True)


class LLMConfigBase(BaseModel):
    name: str
    system_prompt: Optional[str] = None
    user_prompt_template: str
    temperature: float = 0.7
    max_tokens: int = 2000
    model: Optional[str] = None
    is_active: bool = True


class LLMConfigResponse(LLMConfigBase):
    id: int
    created_at: Optional[datetime] = None
    updated_at: Optional[datetime] = None

    model_config = ConfigDict(from_attributes=True)


class SystemConfigBase(BaseModel):
    key: str
    value: Optional[str] = None
    description: Optional[str] = None


class SystemConfigResponse(SystemConfigBase):
    value: Optional[Any] = None
    updated_at: Optional[datetime] = None

    model_config = ConfigDict(from_attributes=True)


class SystemStatus(BaseModel):
    total_topics: int
    topics_by_status: Dict[str, int]
    ready_topics: List[TopicResponse]
    today_articles: int
    compliance_rate: float
    last_optimization: Optional[datetime] = None
    execution_time: Optional[float] = None


class OptimizationRequest(BaseModel):
    topic_ids: Optional[List[str]] = None


class BatchPublishRequest(BaseModel):
    date: str