import uuid

from fastapi import APIRouter, Depends, HTTPException, Query, status
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession

from app.api.deps import get_current_user
from app.database import get_db
from app.models.user import User
from app.models.brand import Brand
from app.models.monitoring import MonitoringRecord
from app.schemas.monitoring import (
    MonitoringRecordCreate,
    MonitoringRecordResponse,
    MonitoringRecordList,
    MonitoringChangeReport,
    MonitoringStatusUpdate,
)
from app.services.monitoring.monitor_service import MonitorService

router = APIRouter()


async def _get_brand_with_access(
    brand_id: uuid.UUID,
    db: AsyncSession,
    current_user: User,
) -> Brand:
    stmt = select(Brand).where(
        Brand.id == brand_id,
        Brand.user_id == current_user.id,
    )
    result = await db.execute(stmt)
    brand = result.scalar_one_or_none()

    if not brand:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="品牌不存在",
        )
    return brand


def _record_to_response(record: MonitoringRecord) -> MonitoringRecordResponse:
    return MonitoringRecordResponse(
        id=record.id,
        brand_id=record.brand_id,
        content_id=record.content_id,
        query_keywords=record.query_keywords,
        platform=record.platform,
        baseline_citation_count=record.baseline_citation_count,
        baseline_sentiment=record.baseline_sentiment,
        baseline_rank=record.baseline_rank,
        current_citation_count=record.current_citation_count,
        current_sentiment=record.current_sentiment,
        current_rank=record.current_rank,
        change_type=record.change_type,
        change_details=record.change_details,
        check_interval_hours=record.check_interval_hours,
        last_checked_at=record.last_checked_at,
        next_check_at=record.next_check_at,
        status=record.status,
        created_at=record.created_at,
        updated_at=record.updated_at,
    )


@router.post("/tasks", response_model=MonitoringRecordResponse)
async def create_monitoring_task(
    request: MonitoringRecordCreate,
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    await _get_brand_with_access(request.brand_id, db, current_user)

    service = MonitorService()
    record = await service.create_monitoring_record(
        db=db,
        brand_id=request.brand_id,
        content_id=request.content_id,
        query_keywords=request.query_keywords,
        platform=request.platform,
        check_interval_hours=request.check_interval_hours,
    )
    return _record_to_response(record)


@router.get("/brand/{brand_id}", response_model=MonitoringRecordList)
async def get_brand_monitoring(
    brand_id: uuid.UUID,
    skip: int = Query(0, ge=0),
    limit: int = Query(20, ge=1, le=100),
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    await _get_brand_with_access(brand_id, db, current_user)

    service = MonitorService()
    records, total = await service.get_brand_monitoring(
        db=db,
        brand_id=brand_id,
        skip=skip,
        limit=limit,
    )
    return MonitoringRecordList(
        records=[_record_to_response(r) for r in records],
        total=total,
    )


@router.get("/{record_id}/report", response_model=MonitoringChangeReport)
async def get_change_report(
    record_id: uuid.UUID,
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    stmt = select(MonitoringRecord).where(MonitoringRecord.id == record_id)
    result = await db.execute(stmt)
    record = result.scalar_one_or_none()

    if not record:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="监测记录不存在",
        )

    await _get_brand_with_access(record.brand_id, db, current_user)

    service = MonitorService()
    report = await service.generate_change_report(db, record_id)
    if not report:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="变化报告不存在",
        )

    return MonitoringChangeReport(
        monitoring_record_id=uuid.UUID(report["monitoring_record_id"]),
        brand_id=uuid.UUID(report["brand_id"]),
        change_type=report["change_type"],
        change_details=report["change_details"],
        baseline=report["baseline"],
        current=report["current"],
        recommendations=report["recommendations"],
    )


@router.put("/{record_id}/status", response_model=MonitoringRecordResponse)
async def update_monitoring_status(
    record_id: uuid.UUID,
    status_update: MonitoringStatusUpdate,
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    valid_statuses = {"active", "paused", "completed"}
    if status_update.status not in valid_statuses:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail=f"无效的状态值，支持: {', '.join(valid_statuses)}",
        )

    stmt = select(MonitoringRecord).where(MonitoringRecord.id == record_id)
    result = await db.execute(stmt)
    record = result.scalar_one_or_none()

    if not record:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="监测记录不存在",
        )

    await _get_brand_with_access(record.brand_id, db, current_user)

    record.status = status_update.status
    await db.commit()
    await db.refresh(record)

    return _record_to_response(record)


@router.post("/{record_id}/check", response_model=MonitoringRecordResponse)
async def trigger_manual_check(
    record_id: uuid.UUID,
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    stmt = select(MonitoringRecord).where(MonitoringRecord.id == record_id)
    result = await db.execute(stmt)
    record = result.scalar_one_or_none()

    if not record:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="监测记录不存在",
        )

    await _get_brand_with_access(record.brand_id, db, current_user)

    service = MonitorService()
    updated_record = await service.check_and_compare(db, record_id)
    if not updated_record:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="检测执行失败",
        )

    return _record_to_response(updated_record)
