"""
证书管理 API 端点

提供证书相关的 RESTful API：
- 获取证书列表
- 获取证书详情
- 下载证书
- 验证证书
"""

from typing import Optional, List
from fastapi import APIRouter, Depends, HTTPException, status, Response, Query
from fastapi.responses import StreamingResponse
from sqlalchemy.ext.asyncio import AsyncSession
import io

from app.core.deps import get_db, get_current_user
from app.models.user import User
from app.services.certificate_service import CertificateService

router = APIRouter()


@router.get("/templates")
async def get_certificate_templates(
    cert_type: Optional[str] = Query(None, description="证书类型: course/exam/achievement"),
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    """获取证书模板列表"""
    service = CertificateService(db)
    templates = await service.get_templates(cert_type)
    return {
        "code": 200,
        "message": "success",
        "data": templates
    }


@router.get("/me")
async def get_my_certificates(
    cert_type: Optional[str] = Query(None, description="证书类型过滤"),
    offset: 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)
):
    """获取当前用户的证书列表"""
    service = CertificateService(db)
    result = await service.get_user_certificates(
        user_id=current_user.id,
        cert_type=cert_type,
        offset=offset,
        limit=limit
    )
    return {
        "code": 200,
        "message": "success",
        "data": result
    }


@router.get("/user/{user_id}")
async def get_user_certificates(
    user_id: int,
    cert_type: Optional[str] = Query(None),
    offset: 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)
):
    """获取指定用户的证书列表（需要管理员权限）"""
    # 只允许查看自己的证书或管理员查看
    if current_user.id != user_id and current_user.role not in ["admin", "enterprise_admin"]:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="无权查看其他用户的证书"
        )
    
    service = CertificateService(db)
    result = await service.get_user_certificates(
        user_id=user_id,
        cert_type=cert_type,
        offset=offset,
        limit=limit
    )
    return {
        "code": 200,
        "message": "success",
        "data": result
    }


@router.get("/{cert_id}")
async def get_certificate_detail(
    cert_id: int,
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    """获取证书详情"""
    service = CertificateService(db)
    cert = await service.get_certificate_by_id(cert_id)
    
    if not cert:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="证书不存在"
        )
    
    return {
        "code": 200,
        "message": "success",
        "data": cert
    }


@router.get("/{cert_id}/image")
async def get_certificate_image(
    cert_id: int,
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    """获取证书分享图片"""
    service = CertificateService(db)
    
    try:
        # 获取基础URL
        base_url = "https://kpl.example.com/certificates"  # 可从配置读取
        
        image_bytes = await service.generate_certificate_image(cert_id, base_url)
        
        return StreamingResponse(
            io.BytesIO(image_bytes),
            media_type="image/png",
            headers={
                "Content-Disposition": f"inline; filename=certificate_{cert_id}.png"
            }
        )
    except ValueError as e:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=str(e)
        )
    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"生成证书图片失败: {str(e)}"
        )


@router.get("/{cert_id}/download")
async def download_certificate(
    cert_id: int,
    format: str = Query("pdf", description="下载格式: pdf 或 png"),
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    """
    下载证书
    
    支持 PDF 和 PNG 两种格式
    - PDF: 高质量打印版本（需要安装 weasyprint）
    - PNG: 图片版本
    """
    service = CertificateService(db)
    cert = await service.get_certificate_by_id(cert_id)
    
    if not cert:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="证书不存在"
        )
    
    # 如果已有缓存的 PDF/图片 URL 则返回
    if format.lower() == "pdf" and cert.get("pdf_url"):
        return {
            "code": 200,
            "message": "success",
            "data": {
                "download_url": cert["pdf_url"]
            }
        }
    
    if format.lower() == "png" and cert.get("image_url"):
        return {
            "code": 200,
            "message": "success",
            "data": {
                "download_url": cert["image_url"]
            }
        }
    
    # 动态生成证书文件
    try:
        from app.core.config import settings
        base_url = settings.PUBLIC_DOMAIN + "/certificates"
        
        content, filename, mime_type = await service.download_certificate(
            cert_id, format, base_url
        )
        
        return StreamingResponse(
            io.BytesIO(content),
            media_type=mime_type,
            headers={
                "Content-Disposition": f"attachment; filename={filename}"
            }
        )
    except ValueError as e:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail=str(e)
        )
    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"下载失败: {str(e)}"
        )


@router.get("/verify/{cert_no}")
async def verify_certificate(
    cert_no: str,
    db: AsyncSession = Depends(get_db)
):
    """
    验证证书真伪
    
    此接口无需登录，可用于公开验证证书
    """
    service = CertificateService(db)
    cert = await service.get_certificate_by_no(cert_no)
    
    if not cert:
        return {
            "code": 404,
            "message": "证书不存在或编号错误",
            "data": {
                "valid": False,
                "certificate_no": cert_no
            }
        }
    
    return {
        "code": 200,
        "message": "证书验证通过",
        "data": {
            "valid": True,
            "certificate_no": cert_no,
            "title": cert.get("title"),
            "type_name": cert.get("type_name"),
            "issued_at": cert.get("issued_at"),
            "user": cert.get("user", {}),
        }
    }


@router.post("/issue/course")
async def issue_course_certificate(
    course_id: int,
    course_name: str,
    completion_rate: float = 100.0,
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    """
    颁发课程结业证书
    
    通常由系统在用户完成课程时自动调用
    """
    service = CertificateService(db)
    
    try:
        cert = await service.issue_course_certificate(
            user_id=current_user.id,
            course_id=course_id,
            course_name=course_name,
            completion_rate=completion_rate,
            user_name=current_user.full_name or current_user.username
        )
        await db.commit()
        
        return {
            "code": 200,
            "message": "证书颁发成功",
            "data": cert
        }
    except ValueError as e:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail=str(e)
        )


@router.post("/issue/exam")
async def issue_exam_certificate(
    exam_id: int,
    exam_name: str,
    score: float,
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    """
    颁发考试合格证书
    
    通常由系统在用户考试通过时自动调用
    """
    service = CertificateService(db)
    
    try:
        cert = await service.issue_exam_certificate(
            user_id=current_user.id,
            exam_id=exam_id,
            exam_name=exam_name,
            score=score,
            user_name=current_user.full_name or current_user.username
        )
        await db.commit()
        
        return {
            "code": 200,
            "message": "证书颁发成功",
            "data": cert
        }
    except ValueError as e:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail=str(e)
        )
