# -*- coding: utf-8 -*-
"""
日志和历史记录API
"""

from typing import List, Optional
from datetime import datetime, timedelta
from urllib.parse import urlparse
from fastapi import APIRouter, Depends, HTTPException, Query
from pydantic import BaseModel
from sqlalchemy.orm import Session, joinedload
from sqlalchemy import desc

from app.db import get_db
from app.core.config import settings
from app.core.security import get_current_user
from app.models.logs import PltProcessRecord, UserActionLog, PltPiece
from app.models.user import User

router = APIRouter()

CURRENT_QINIU_DOMAIN = settings.QINIU_DOMAIN.rstrip("/")
CURRENT_QINIU_HOST = urlparse(CURRENT_QINIU_DOMAIN).netloc.lower() if CURRENT_QINIU_DOMAIN else ""
KNOWN_QINIU_HOST_MARKERS = ("qiniuio.com", "clouddn.com", "qnssl.com")
LEGACY_QINIU_HOSTS = {
    "iovip-z2.qiniuio.com",
    "t9zfnhhrn.hn-bkt.clouddn.com",
}


def normalize_qiniu_url(url: Optional[str]) -> Optional[str]:
    """将历史记录中的旧七牛域名切换到当前绑定域名。"""
    if not url or not CURRENT_QINIU_DOMAIN:
        return url

    parsed = urlparse(url)
    host = parsed.netloc.lower()

    if not parsed.scheme or not host or not parsed.path:
        return url

    if host == CURRENT_QINIU_HOST:
        return url

    is_qiniu_host = host in LEGACY_QINIU_HOSTS or any(
        host.endswith(marker) for marker in KNOWN_QINIU_HOST_MARKERS
    )
    if not is_qiniu_host:
        return url

    suffix = parsed.path
    if parsed.query:
        suffix = f"{suffix}?{parsed.query}"
    return f"{CURRENT_QINIU_DOMAIN}{suffix}"


def normalize_record_piece_urls(record: Optional[PltProcessRecord]) -> Optional[PltProcessRecord]:
    """在返回详情前修正裁片图片地址，兼容旧域名历史记录。"""
    if not record or not record.pieces:
        return record

    for piece in record.pieces:
        piece.image_url = normalize_qiniu_url(piece.image_url)

    return record


# ==================== 数据模型 ====================

class ActionLogCreate(BaseModel):
    """创建操作日志"""
    session_id: Optional[str] = None
    action_type: str
    action_params: Optional[dict] = None
    page: Optional[str] = None
    result: str = "success"
    error_message: Optional[str] = None
    duration_ms: Optional[int] = None


class ActionLogResponse(BaseModel):
    """操作日志响应"""
    id: int
    action_type: str
    action_params: Optional[dict]
    page: Optional[str]
    result: str
    error_message: Optional[str]
    duration_ms: Optional[int]
    created_at: datetime
    
    class Config:
        from_attributes = True


class PltPieceCreate(BaseModel):
    """裁片信息"""
    group_id: int
    size: str
    image_url: Optional[str] = None
    width_px: int = 0
    height_px: int = 0
    width_cm: float = 0
    height_cm: float = 0
    left_cm: float = 0
    top_cm: float = 0
    center_x_cm: float = 0
    center_y_cm: float = 0


class PltPieceResponse(BaseModel):
    """裁片响应"""
    id: int
    group_id: int
    size: str
    image_url: Optional[str]
    width_px: int
    height_px: int
    width_cm: float
    height_cm: float
    left_cm: float
    top_cm: float
    center_x_cm: float
    center_y_cm: float
    
    class Config:
        from_attributes = True


class PltRecordCreate(BaseModel):
    """创建PLT处理记录"""
    filename: Optional[str] = None
    file_size: Optional[int] = None
    rotated_filename: Optional[str] = None
    size_labels: Optional[List[str]] = None
    dpi: int = 150
    rotation: int = 0
    total_groups: int = 0
    total_pieces: int = 0
    process_time_ms: Optional[int] = None
    status: str = "success"
    error_message: Optional[str] = None
    pieces: Optional[List[PltPieceCreate]] = None  # 裁片详情


class PltRecordResponse(BaseModel):
    """PLT处理记录响应"""
    id: int
    filename: Optional[str]
    file_size: Optional[int]
    rotated_filename: Optional[str]
    size_labels: Optional[List[str]]
    dpi: int
    rotation: int
    total_groups: int
    total_pieces: int
    process_time_ms: Optional[int]
    status: str
    created_at: datetime
    
    class Config:
        from_attributes = True


class PltRecordDetailResponse(PltRecordResponse):
    """PLT处理记录详情响应（包含裁片）"""
    pieces: List[PltPieceResponse] = []


class SessionLogsResponse(BaseModel):
    """会话日志响应（给AI用）"""
    user_id: int
    username: str
    current_page: Optional[str]
    recent_actions: List[ActionLogResponse]
    recent_plt_records: List[PltRecordResponse]
    error_count: int


# ==================== API端点 ====================

@router.post("/logs/action", response_model=ActionLogResponse)
async def create_action_log(
    log_data: ActionLogCreate,
    current_username: str = Depends(get_current_user),
    db: Session = Depends(get_db)
):
    """记录用户操作日志"""
    # 获取用户ID
    user = db.query(User).filter(User.username == current_username).first()
    if not user:
        raise HTTPException(status_code=404, detail="用户不存在")
    
    # 创建日志
    log = UserActionLog(
        user_id=user.id,
        session_id=log_data.session_id,
        action_type=log_data.action_type,
        action_params=log_data.action_params,
        page=log_data.page,
        result=log_data.result,
        error_message=log_data.error_message,
        duration_ms=log_data.duration_ms
    )
    db.add(log)
    db.commit()
    db.refresh(log)
    
    return log


@router.post("/plt/record", response_model=PltRecordResponse)
async def create_plt_record(
    record_data: PltRecordCreate,
    current_username: str = Depends(get_current_user),
    db: Session = Depends(get_db)
):
    """记录PLT处理记录（包含裁片详情）"""
    user = db.query(User).filter(User.username == current_username).first()
    if not user:
        raise HTTPException(status_code=404, detail="用户不存在")
    
    record = PltProcessRecord(
        user_id=user.id,
        filename=record_data.filename,
        file_size=record_data.file_size,
        rotated_filename=record_data.rotated_filename,
        size_labels=record_data.size_labels,
        dpi=record_data.dpi,
        rotation=record_data.rotation,
        total_groups=record_data.total_groups,
        total_pieces=record_data.total_pieces,
        process_time_ms=record_data.process_time_ms,
        status=record_data.status,
        error_message=record_data.error_message
    )
    db.add(record)
    db.flush()  # 获取 record.id
    
    # 保存裁片详情
    if record_data.pieces:
        for piece_data in record_data.pieces:
            piece = PltPiece(
                record_id=record.id,
                group_id=piece_data.group_id,
                size=piece_data.size,
                image_url=normalize_qiniu_url(piece_data.image_url),
                width_px=piece_data.width_px,
                height_px=piece_data.height_px,
                width_cm=piece_data.width_cm,
                height_cm=piece_data.height_cm,
                left_cm=piece_data.left_cm,
                top_cm=piece_data.top_cm,
                center_x_cm=piece_data.center_x_cm,
                center_y_cm=piece_data.center_y_cm
            )
            db.add(piece)
    
    db.commit()
    db.refresh(record)
    
    return record


@router.get("/plt/history/{record_id}", response_model=PltRecordDetailResponse)
async def get_plt_record_detail(
    record_id: int,
    current_username: str = Depends(get_current_user),
    db: Session = Depends(get_db)
):
    """获取PLT处理记录详情（包含裁片）"""
    user = db.query(User).filter(User.username == current_username).first()
    if not user:
        raise HTTPException(status_code=404, detail="用户不存在")
    
    record = db.query(PltProcessRecord)\
        .options(joinedload(PltProcessRecord.pieces))\
        .filter(PltProcessRecord.id == record_id)\
        .filter(PltProcessRecord.user_id == user.id)\
        .first()
    
    if not record:
        raise HTTPException(status_code=404, detail="记录不存在")
    
    return normalize_record_piece_urls(record)


@router.get("/plt/history", response_model=List[PltRecordResponse])
async def get_plt_history(
    limit: int = Query(20, ge=1, le=100),
    days: int = Query(0, ge=0, le=3650),  # 0 表示不限制时间
    current_username: str = Depends(get_current_user),
    db: Session = Depends(get_db)
):
    """获取用户的 PLT 处理历史，days=0 表示全部记录"""
    user = db.query(User).filter(User.username == current_username).first()
    if not user:
        raise HTTPException(status_code=404, detail="用户不存在")

    query = db.query(PltProcessRecord)\
        .filter(PltProcessRecord.user_id == user.id)

    if days > 0:
        since = datetime.now() - timedelta(days=days)
        query = query.filter(PltProcessRecord.created_at >= since)

    records = query.order_by(desc(PltProcessRecord.created_at))\
        .limit(limit)\
        .all()
    
    return records


@router.get("/logs/recent", response_model=List[ActionLogResponse])
async def get_recent_logs(
    limit: int = Query(50, ge=1, le=200),
    action_type: Optional[str] = None,
    current_username: str = Depends(get_current_user),
    db: Session = Depends(get_db)
):
    """获取用户最近的操作日志"""
    user = db.query(User).filter(User.username == current_username).first()
    if not user:
        raise HTTPException(status_code=404, detail="用户不存在")
    
    query = db.query(UserActionLog).filter(UserActionLog.user_id == user.id)
    
    if action_type:
        query = query.filter(UserActionLog.action_type.like(f"{action_type}%"))
    
    logs = query.order_by(desc(UserActionLog.created_at)).limit(limit).all()
    
    return logs


@router.get("/logs/session", response_model=SessionLogsResponse)
async def get_session_context(
    hours: int = Query(24, ge=1, le=168),
    current_username: str = Depends(get_current_user),
    db: Session = Depends(get_db)
):
    """获取会话上下文（给AI助手用）"""
    user = db.query(User).filter(User.username == current_username).first()
    if not user:
        raise HTTPException(status_code=404, detail="用户不存在")
    
    since = datetime.now() - timedelta(hours=hours)
    
    # 最近的操作日志
    recent_actions = db.query(UserActionLog)\
        .filter(UserActionLog.user_id == user.id)\
        .filter(UserActionLog.created_at >= since)\
        .order_by(desc(UserActionLog.created_at))\
        .limit(50)\
        .all()
    
    # 最近的PLT处理记录
    recent_plt = db.query(PltProcessRecord)\
        .filter(PltProcessRecord.user_id == user.id)\
        .filter(PltProcessRecord.created_at >= since)\
        .order_by(desc(PltProcessRecord.created_at))\
        .limit(10)\
        .all()
    
    # 错误数量
    error_count = db.query(UserActionLog)\
        .filter(UserActionLog.user_id == user.id)\
        .filter(UserActionLog.created_at >= since)\
        .filter(UserActionLog.result == "error")\
        .count()
    
    # 当前页面（最近一次进入页面的记录）
    last_page_action = db.query(UserActionLog)\
        .filter(UserActionLog.user_id == user.id)\
        .filter(UserActionLog.action_type == "page.enter")\
        .order_by(desc(UserActionLog.created_at))\
        .first()
    
    current_page = last_page_action.action_params.get("page") if last_page_action and last_page_action.action_params else None
    
    return SessionLogsResponse(
        user_id=user.id,
        username=current_username,
        current_page=current_page,
        recent_actions=recent_actions,
        recent_plt_records=recent_plt,
        error_count=error_count
    )
