"""内容管理 CRUD API — /api/v1/contents/"""
import uuid
from typing import Optional

from fastapi import APIRouter, Depends, HTTPException, Query, status
from pydantic import BaseModel, Field
from sqlalchemy import select, func, update
from sqlalchemy.ext.asyncio import AsyncSession

from app.api.deps import get_current_user
from app.database import get_db
from app.models.content import Content, ContentVersion
from app.models.brand_knowledge import BrandKnowledge
from app.models.user import User

router = APIRouter()


# ---------------------------------------------------------------------------
# Pydantic Schemas
# ---------------------------------------------------------------------------

class ContentCreateRequest(BaseModel):
    title: str = Field(..., max_length=500)
    body: str
    content_type: str = Field(default="article", max_length=50)
    project_id: Optional[str] = None
    tags: Optional[list[str]] = None


class ContentUpdateRequest(BaseModel):
    title: Optional[str] = Field(None, max_length=500)
    body: Optional[str] = None
    content_type: Optional[str] = Field(None, max_length=50)
    status: Optional[str] = Field(None, max_length=20)
    tags: Optional[list[str]] = None


class ContentResponse(BaseModel):
    id: str
    title: str
    body: Optional[str]
    content_type: str
    status: str
    project_id: Optional[str]
    author_id: Optional[str]
    tags: Optional[list[str]]
    created_at: str
    updated_at: str
    published_at: Optional[str] = None

    model_config = {"from_attributes": True}


class BrandKnowledgeCreateRequest(BaseModel):
    category: str = Field(..., max_length=50)
    title: str = Field(..., max_length=200)
    body: str
    source: Optional[str] = None


class BrandKnowledgeUpdateRequest(BaseModel):
    category: Optional[str] = Field(None, max_length=50)
    title: Optional[str] = Field(None, max_length=200)
    body: Optional[str] = None
    source: Optional[str] = None


class BrandKnowledgeResponse(BaseModel):
    id: str
    brand_id: str
    category: str
    title: str
    body: str
    source: Optional[str]
    created_at: str
    updated_at: str

    model_config = {"from_attributes": True}


# ---------------------------------------------------------------------------
# Helpers
# ---------------------------------------------------------------------------

def _content_to_response(c: Content) -> ContentResponse:
    """Convert Content model to response schema."""
    tags = c.keywords if c.keywords else []
    published_at = None
    if c.status == "published" and c.updated_at:
        published_at = c.updated_at.isoformat()

    return ContentResponse(
        id=str(c.id),
        title=c.title,
        body=c.body,
        content_type=c.content_type,
        status=c.status,
        project_id=str(c.project_id) if c.project_id else None,
        author_id=str(c.created_by) if c.created_by else None,
        tags=tags,
        created_at=c.created_at.isoformat() if c.created_at else "",
        updated_at=c.updated_at.isoformat() if c.updated_at else "",
        published_at=published_at,
    )


def _brand_knowledge_to_response(bk: BrandKnowledge) -> BrandKnowledgeResponse:
    """Convert BrandKnowledge model to response schema."""
    source = None
    if bk.extra_metadata and isinstance(bk.extra_metadata, dict):
        source = bk.extra_metadata.get("source")

    return BrandKnowledgeResponse(
        id=str(bk.id),
        brand_id=str(bk.organization_id),
        category=bk.category,
        title=bk.title,
        body=bk.content,
        source=source,
        created_at=bk.created_at.isoformat() if bk.created_at else "",
        updated_at=bk.updated_at.isoformat() if bk.updated_at else "",
    )


# ---------------------------------------------------------------------------
# Content CRUD
# ---------------------------------------------------------------------------

@router.get("/", response_model=list[ContentResponse])
async def list_contents(
    status: Optional[str] = Query(None),
    content_type: Optional[str] = Query(None),
    skip: int = Query(0, ge=0),
    limit: int = Query(20, ge=1, le=100),
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(get_current_user),
):
    """列出当前组织的内容列表"""
    org_id = current_user.organization_id
    if not org_id:
        return []

    stmt = select(Content).where(Content.organization_id == org_id)
    if status:
        stmt = stmt.where(Content.status == status)
    if content_type:
        stmt = stmt.where(Content.content_type == content_type)
    stmt = stmt.order_by(Content.created_at.desc()).offset(skip).limit(limit)

    result = await db.execute(stmt)
    contents = result.scalars().all()
    return [_content_to_response(c) for c in contents]


@router.post("/", response_model=ContentResponse, status_code=status.HTTP_201_CREATED)
async def create_content(
    body: ContentCreateRequest,
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(get_current_user),
):
    """手动创建内容"""
    org_id = current_user.organization_id
    if not org_id:
        raise HTTPException(status_code=403, detail="用户未关联组织")

    project_uuid = None
    if body.project_id:
        try:
            project_uuid = uuid.UUID(body.project_id)
        except ValueError:
            raise HTTPException(status_code=400, detail="无效的 project_id")

    content = Content(
        organization_id=org_id,
        title=body.title,
        content_type=body.content_type,
        body=body.body,
        status="draft",
        project_id=project_uuid,
        keywords=body.tags or [],
        created_by=current_user.id,
        current_version=1,
    )
    db.add(content)
    await db.flush()

    # Create initial version
    version = ContentVersion(
        content_id=content.id,
        version_number=1,
        title=body.title,
        body=body.body,
        change_summary="初始创建",
        created_by=current_user.id,
    )
    db.add(version)
    await db.commit()
    await db.refresh(content)

    return _content_to_response(content)


@router.get("/{content_id}", response_model=ContentResponse)
async def get_content(
    content_id: uuid.UUID,
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(get_current_user),
):
    """获取单条内容详情"""
    org_id = current_user.organization_id
    if not org_id:
        raise HTTPException(status_code=404, detail="内容不存在")

    stmt = select(Content).where(
        Content.id == content_id,
        Content.organization_id == org_id,
    )
    result = await db.execute(stmt)
    content = result.scalar_one_or_none()
    if not content:
        raise HTTPException(status_code=404, detail="内容不存在")

    return _content_to_response(content)


@router.put("/{content_id}", response_model=ContentResponse)
async def update_content(
    content_id: uuid.UUID,
    body: ContentUpdateRequest,
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(get_current_user),
):
    """更新内容"""
    org_id = current_user.organization_id
    if not org_id:
        raise HTTPException(status_code=404, detail="内容不存在")

    stmt = select(Content).where(
        Content.id == content_id,
        Content.organization_id == org_id,
    )
    result = await db.execute(stmt)
    content = result.scalar_one_or_none()
    if not content:
        raise HTTPException(status_code=404, detail="内容不存在")

    update_dict = body.model_dump(exclude_unset=True)

    # Map tags -> keywords
    if "tags" in update_dict:
        content.keywords = update_dict.pop("tags")

    needs_version = False
    if "body" in update_dict and update_dict["body"] != content.body:
        needs_version = True
    if "title" in update_dict and update_dict["title"] != content.title:
        needs_version = True

    for field, value in update_dict.items():
        setattr(content, field, value)

    if needs_version:
        content.current_version += 1
        version = ContentVersion(
            content_id=content.id,
            version_number=content.current_version,
            title=content.title,
            body=content.body,
            change_summary=f"版本 {content.current_version}",
            created_by=current_user.id,
        )
        db.add(version)

    await db.commit()
    await db.refresh(content)
    return _content_to_response(content)


@router.delete("/{content_id}", status_code=status.HTTP_204_NO_CONTENT)
async def delete_content(
    content_id: uuid.UUID,
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(get_current_user),
):
    """删除内容"""
    org_id = current_user.organization_id
    if not org_id:
        raise HTTPException(status_code=404, detail="内容不存在")

    stmt = select(Content).where(
        Content.id == content_id,
        Content.organization_id == org_id,
    )
    result = await db.execute(stmt)
    content = result.scalar_one_or_none()
    if not content:
        raise HTTPException(status_code=404, detail="内容不存在")

    await db.delete(content)
    await db.commit()


@router.post("/{content_id}/publish", response_model=ContentResponse)
async def publish_content(
    content_id: uuid.UUID,
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(get_current_user),
):
    """发布内容（将状态改为 published）"""
    org_id = current_user.organization_id
    if not org_id:
        raise HTTPException(status_code=404, detail="内容不存在")

    stmt = select(Content).where(
        Content.id == content_id,
        Content.organization_id == org_id,
    )
    result = await db.execute(stmt)
    content = result.scalar_one_or_none()
    if not content:
        raise HTTPException(status_code=404, detail="内容不存在")

    content.status = "published"
    await db.commit()
    await db.refresh(content)
    return _content_to_response(content)


# ---------------------------------------------------------------------------
# Brand Knowledge CRUD  (under /api/v1/contents/knowledge/)
# ---------------------------------------------------------------------------

@router.get("/knowledge/", response_model=list[BrandKnowledgeResponse])
async def list_brand_knowledge(
    brand_id: Optional[str] = Query(None),
    category: Optional[str] = Query(None),
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(get_current_user),
):
    """列出品牌知识库条目"""
    org_id = current_user.organization_id
    if not org_id:
        return []

    stmt = select(BrandKnowledge).where(
        BrandKnowledge.organization_id == org_id,
        BrandKnowledge.is_active.is_(True),
    )
    # brand_id maps to organization_id; filter only if different org requested
    if brand_id:
        try:
            brand_uuid = uuid.UUID(brand_id)
            stmt = stmt.where(BrandKnowledge.organization_id == brand_uuid)
        except ValueError:
            pass
    if category:
        stmt = stmt.where(BrandKnowledge.category == category)
    stmt = stmt.order_by(BrandKnowledge.created_at.desc())

    result = await db.execute(stmt)
    items = result.scalars().all()
    return [_brand_knowledge_to_response(bk) for bk in items]


@router.post("/knowledge/", response_model=BrandKnowledgeResponse, status_code=status.HTTP_201_CREATED)
async def create_brand_knowledge(
    body: BrandKnowledgeCreateRequest,
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(get_current_user),
):
    """创建品牌知识库条目"""
    org_id = current_user.organization_id
    if not org_id:
        raise HTTPException(status_code=403, detail="用户未关联组织")

    bk = BrandKnowledge(
        organization_id=org_id,
        category=body.category,
        title=body.title,
        content=body.body,
        extra_metadata={"source": body.source} if body.source else None,
        created_by=current_user.id,
    )
    db.add(bk)
    await db.commit()
    await db.refresh(bk)
    return _brand_knowledge_to_response(bk)


@router.put("/knowledge/{knowledge_id}", response_model=BrandKnowledgeResponse)
async def update_brand_knowledge(
    knowledge_id: uuid.UUID,
    body: BrandKnowledgeUpdateRequest,
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(get_current_user),
):
    """更新品牌知识库条目"""
    org_id = current_user.organization_id
    if not org_id:
        raise HTTPException(status_code=404, detail="知识条目不存在")

    stmt = select(BrandKnowledge).where(
        BrandKnowledge.id == knowledge_id,
        BrandKnowledge.organization_id == org_id,
    )
    result = await db.execute(stmt)
    bk = result.scalar_one_or_none()
    if not bk:
        raise HTTPException(status_code=404, detail="知识条目不存在")

    update_dict = body.model_dump(exclude_unset=True)
    if "body" in update_dict:
        bk.content = update_dict.pop("body")
    if "source" in update_dict:
        source = update_dict.pop("source")
        if bk.extra_metadata is None:
            bk.extra_metadata = {}
        bk.extra_metadata["source"] = source

    for field, value in update_dict.items():
        setattr(bk, field, value)

    await db.commit()
    await db.refresh(bk)
    return _brand_knowledge_to_response(bk)


@router.delete("/knowledge/{knowledge_id}", status_code=status.HTTP_204_NO_CONTENT)
async def delete_brand_knowledge(
    knowledge_id: uuid.UUID,
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(get_current_user),
):
    """删除品牌知识库条目"""
    org_id = current_user.organization_id
    if not org_id:
        raise HTTPException(status_code=404, detail="知识条目不存在")

    stmt = select(BrandKnowledge).where(
        BrandKnowledge.id == knowledge_id,
        BrandKnowledge.organization_id == org_id,
    )
    result = await db.execute(stmt)
    bk = result.scalar_one_or_none()
    if not bk:
        raise HTTPException(status_code=404, detail="知识条目不存在")

    await db.delete(bk)
    await db.commit()
