from fastapi import APIRouter, Depends, HTTPException, Request
from pydantic import BaseModel, Field

from model.blog_model import BlogModel, BlogPayload
from utils.auth_helper import requires_permission, assert_actor_match
from utils.turnstile_helper import verify_turnstile


router = APIRouter()


class BlogAdminPayload(BaseModel):
    title: str = Field(..., min_length=1)
    description: str = Field(..., min_length=1)
    thumbnail: str = Field(..., min_length=1)
    actorId: str


@router.get("/blogs")
async def get_public_blogs():
    try:
        blogs = BlogModel.get_public_blogs()
        return {
            "success": True,
            "data": blogs,
        }
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))


@router.get("/blogs/{blog_id}")
async def get_public_blog_detail(blog_id: str):
    try:
        blog = BlogModel.get_blog_by_id(blog_id)
        if not blog:
            raise HTTPException(status_code=404, detail="Blog not found")

        return {
            "success": True,
            "data": blog,
        }
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))


@router.post("/admin/blogs", dependencies=[Depends(verify_turnstile)])
async def create_blog(
    payload: BlogAdminPayload,
    current_user=Depends(requires_permission("blog_management")),
):
    try:
        actor_id = current_user["id"]
        actor_name = current_user.get("name", "")

        assert_actor_match(current_user, payload.actorId)

        blog = BlogModel.create_blog(
            BlogPayload(
                title=payload.title,
                description=payload.description,
                thumbnail=payload.thumbnail,
            )
        )

        return {
            "success": True,
            "message": "Đã thêm blog thành công!",
            "data": blog,
            "actedBy": {
                "id": actor_id,
                "name": actor_name,
            },
        }

    except ValueError as e:
        raise HTTPException(status_code=400, detail=str(e))
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))


@router.put("/admin/blogs/{blog_id}", dependencies=[Depends(verify_turnstile)])
async def update_blog(
    blog_id: str,
    payload: BlogAdminPayload,
    current_user=Depends(requires_permission("blog_management")),
):
    try:
        actor_id = current_user["id"]
        actor_name = current_user.get("name", "")

        assert_actor_match(current_user, payload.actorId)

        blog = BlogModel.update_blog(
            blog_id,
            BlogPayload(
                title=payload.title,
                description=payload.description,
                thumbnail=payload.thumbnail,
            ),
        )

        if not blog:
            raise HTTPException(status_code=404, detail="Blog not found")

        return {
            "success": True,
            "message": "Cập nhật blog thành công!",
            "data": blog,
            "actedBy": {
                "id": actor_id,
                "name": actor_name,
            },
        }

    except ValueError as e:
        raise HTTPException(status_code=400, detail=str(e))
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))


@router.delete("/admin/blogs/{blog_id}", dependencies=[Depends(verify_turnstile)])
async def delete_blog(
    blog_id: str,
    request: Request,
    current_user=Depends(requires_permission("blog_management")),
):
    try:
        actor_id = current_user["id"]
        actor_name = current_user.get("name", "")

        assert_actor_match(current_user, request.headers.get("x-actor-id"))

        deleted_count = BlogModel.delete_blog(blog_id)

        if deleted_count == 0:
            raise HTTPException(status_code=404, detail="Blog not found")

        return {
            "success": True,
            "message": "Xóa blog thành công!",
            "actedBy": {
                "id": actor_id,
                "name": actor_name,
            },
        }

    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))
