from typing import Optional

from fastapi import APIRouter, Depends, UploadFile, File, Form, status, Query, HTTPException
from sqlmodel import Session

from app.core.logging import setup_logger
from app.core.config import get_settings
from app.api.deps import require_roles
from app.db.session import get_session
from app.models.user import User, Role
from app.schemas.project import ProjectRead, ProjectDetailRead, ProjectUpdateResponse, ProductTemplateInfo
from app.schemas.common import PaginatedResponse
from app.services.project_service import ProjectService

logger = setup_logger(__name__)
settings = get_settings()

router = APIRouter(prefix="/api/projects", tags=["Projects"])

@router.post("/create", status_code=status.HTTP_201_CREATED, response_model=ProjectRead)
async def create_project_endpoint(
    project_name: str = Form(...),
    client_name: str = Form(...),
    overlay_image: UploadFile = File(...),
    logo_image: Optional[UploadFile] = File(None),
    db: Session = Depends(get_session),
    current_user: User = Depends(require_roles(Role.SUPERADMIN, Role.ADMIN)),
):
    """
    Create project and process overlay against all active product templates.
    """
    project = await ProjectService.create_project(
        project_name=project_name,
        client_name=client_name,
        overlay_file=overlay_image,
        logo_file=logo_image,
        current_user=current_user,
        session=db,
    )
    return project

@router.get(
    "/list",
    response_model=PaginatedResponse[ProjectRead],
    status_code=status.HTTP_200_OK,
)
def list_projects_endpoint(
    page: int = Query(1, ge=1),
    limit: int = Query(10, ge=1, le=200),
    search: Optional[str] = None,
    sort_by: Optional[str] = "created_at",
    order: Optional[str] = "desc",
    db: Session = Depends(get_session),
    current_user: User = Depends(require_roles(Role.SUPERADMIN, Role.ADMIN)),
):
    if sort_by not in ["id", "project_name", "client_name", "created_at", "updated_at"]:
        raise HTTPException(400, "Invalid sort_by field")
    if order not in ["asc", "desc"]:
        raise HTTPException(400, "Invalid order")
    rows, total = ProjectService.list_projects(
        db,
        page=page,
        limit=limit,
        search=search,
        sort_by=sort_by,
        order=order,
    )

    return PaginatedResponse[ProjectRead](
        total=total,
        page=page,
        limit=limit,
        items=[ProjectRead.from_orm(r) for r in rows],
    )

@router.get(
    "/detail/{project_id}",
    status_code=status.HTTP_200_OK,
    response_model=ProjectDetailRead
)
def project_detail_endpoint(
    project_id: int,
    db: Session = Depends(get_session),
    current_user: User = Depends(require_roles(Role.SUPERADMIN, Role.ADMIN)),
):
    project, images = ProjectService.get_project_detail(db, project_id)

    response = {
        **ProjectRead.from_orm(project).dict(),
        "images": [
            {
                "id": img["id"],
                "final_image_path": img["final_image_path"],
                "product_template": ProductTemplateInfo.from_orm(img["product_template"]).dict()
            }
            for img in images
        ]
    }

    return ProjectDetailRead.model_validate(response)

@router.patch(
    "/update/{project_id}",
    response_model=ProjectUpdateResponse,
    status_code=status.HTTP_200_OK
)
async def update_project(
    project_id: int,
    project_name: Optional[str] = Form(None),
    client_name: Optional[str] = Form(None),
    overlay_image: Optional[UploadFile] = File(None),
    logo_image: Optional[UploadFile] = File(None),

    db: Session = Depends(get_session),
    current_user: User = Depends(require_roles(Role.ADMIN, Role.SUPERADMIN))
):
    return await ProjectService.update_project(
        db=db,
        current_user=current_user,
        project_id=project_id,
        project_name=project_name,
        client_name=client_name,
        overlay_file=overlay_image,
        logo_file=logo_image,
    )

@router.patch(
    "/regenerate-image/{product_image_id}",
    status_code=status.HTTP_200_OK
)
async def regenerate_single_image_endpoint(
    product_image_id: int,
    new_overlay_image: UploadFile = File(...),
    db: Session = Depends(get_session),
    current_user: User = Depends(require_roles(Role.ADMIN, Role.SUPERADMIN)),
):
    return await ProjectService.regenerate_single_image(
        db=db,
        product_image_id=product_image_id,
        new_overlay_file=new_overlay_image,
        current_user=current_user
    )

# @router.delete("/delete/{project_id}", status_code=status.HTTP_200_OK)
# def delete_project_endpoint(
#     project_id: int,
#     db: Session = Depends(get_session),
#     current_user: User = Depends(require_roles(Role.SUPERADMIN, Role.ADMIN)),
# ):
#     ProjectService.delete_project(db, project_id)
#     return {"success": True}
