"""Reported photos endpoints - admin only."""

from __future__ import annotations

from datetime import datetime
from typing import Annotated, Optional

from fastapi import APIRouter, Depends, HTTPException, Query, status
from pydantic import BaseModel, ConfigDict
from sqlalchemy import text
from sqlalchemy.orm import Session

from backend.db.session import get_auth_db, get_db
from backend.db.models import Photo, PhotoTagLinkage
from backend.api.users import get_current_admin_user, require_feature_permission

router = APIRouter(prefix="/reported-photos", tags=["reported-photos"])


class ReportedPhotoResponse(BaseModel):
    """Reported photo DTO returned from API."""

    model_config = ConfigDict(from_attributes=True, protected_namespaces=())

    id: int
    photo_id: int
    user_id: int
    user_name: Optional[str] = None
    user_email: Optional[str] = None
    status: str
    reported_at: str
    reviewed_at: Optional[str] = None
    reviewed_by: Optional[int] = None
    review_notes: Optional[str] = None
    report_comment: Optional[str] = None
    # Photo details from main database
    photo_path: Optional[str] = None
    photo_filename: Optional[str] = None
    photo_media_type: Optional[str] = None


class ReportedPhotosListResponse(BaseModel):
    """List of reported photos."""

    model_config = ConfigDict(protected_namespaces=())

    items: list[ReportedPhotoResponse]
    total: int


class ReviewDecision(BaseModel):
    """Decision for a single reported photo."""

    model_config = ConfigDict(protected_namespaces=())

    id: int
    decision: str  # 'keep' or 'remove'
    review_notes: Optional[str] = None


class ReviewRequest(BaseModel):
    """Request to review multiple reported photos."""

    model_config = ConfigDict(protected_namespaces=())

    decisions: list[ReviewDecision]


class ReviewResponse(BaseModel):
    """Response from review operation."""

    model_config = ConfigDict(protected_namespaces=())

    kept: int
    removed: int
    errors: list[str]


class CleanupResponse(BaseModel):
    """Response payload for cleanup operations."""

    model_config = ConfigDict(protected_namespaces=())

    deleted_records: int
    errors: list[str]
    warnings: list[str] = []


@router.get("", response_model=ReportedPhotosListResponse)
def list_reported_photos(
    current_user: Annotated[
        dict, Depends(require_feature_permission("user_reported"))
    ],
    status_filter: Optional[str] = None,
    auth_db: Session = Depends(get_auth_db),
    main_db: Session = Depends(get_db),
) -> ReportedPhotosListResponse:
    """List all reported photos from the auth database.
    
    This endpoint reads from the separate auth database (DATABASE_URL_AUTH)
    and returns all reported photos from the inappropriate_photo_reports table.
    Optionally filter by status: 'pending', 'reviewed', or 'dismissed'.
    """
    try:
        # Query inappropriate_photo_reports from auth database using raw SQL
        # Join with users table to get user name/email
        if status_filter:
            result = auth_db.execute(text("""
                SELECT 
                    ipr.id,
                    ipr.photo_id,
                    ipr.user_id,
                    u.name as user_name,
                    u.email as user_email,
                    ipr.status,
                    ipr.reported_at,
                    ipr.reviewed_at,
                    ipr.reviewed_by,
                    ipr.review_notes,
                    ipr.report_comment
                FROM inappropriate_photo_reports ipr
                LEFT JOIN users u ON ipr.user_id = u.id
                WHERE ipr.status = :status_filter
                ORDER BY ipr.reported_at DESC
            """), {"status_filter": status_filter})
        else:
            result = auth_db.execute(text("""
                SELECT 
                    ipr.id,
                    ipr.photo_id,
                    ipr.user_id,
                    u.name as user_name,
                    u.email as user_email,
                    ipr.status,
                    ipr.reported_at,
                    ipr.reviewed_at,
                    ipr.reviewed_by,
                    ipr.review_notes,
                    ipr.report_comment
                FROM inappropriate_photo_reports ipr
                LEFT JOIN users u ON ipr.user_id = u.id
                ORDER BY ipr.reported_at DESC
            """))
        
        rows = result.fetchall()
        items = []
        for row in rows:
            # Get photo details from main database
            photo_path = None
            photo_filename = None
            photo_media_type = None
            photo = main_db.query(Photo).filter(Photo.id == row.photo_id).first()
            if photo:
                photo_path = photo.path
                photo_filename = photo.filename
                photo_media_type = photo.media_type
            
            items.append(ReportedPhotoResponse(
                id=row.id,
                photo_id=row.photo_id,
                user_id=row.user_id,
                user_name=row.user_name,
                user_email=row.user_email,
                status=row.status,
                reported_at=str(row.reported_at) if row.reported_at else '',
                reviewed_at=str(row.reviewed_at) if row.reviewed_at else None,
                reviewed_by=row.reviewed_by,
                review_notes=row.review_notes,
                report_comment=row.report_comment,
                photo_path=photo_path,
                photo_filename=photo_filename,
                photo_media_type=photo_media_type,
            ))
        
        return ReportedPhotosListResponse(items=items, total=len(items))
    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Error reading from auth database: {str(e)}"
        )


@router.post("/review", response_model=ReviewResponse)
def review_reported_photos(
    current_user: Annotated[
        dict, Depends(require_feature_permission("user_reported"))
    ],
    request: ReviewRequest,
    auth_db: Session = Depends(get_auth_db),
    main_db: Session = Depends(get_db),
) -> ReviewResponse:
    """Review reported photos - keep or remove them.
    
    For 'keep' decision:
    - Updates status in auth database to 'reviewed'
    - Photo remains in main database
    
    For 'remove' decision:
    - Updates status in auth database to 'reviewed'
    - Deletes photo from main database (cascade deletes faces, tags, etc.)
    """
    kept_count = 0
    removed_count = 0
    errors = []
    admin_user_id = current_user.get("user_id")
    now = datetime.utcnow()
    
    for decision in request.decisions:
        try:
            # Get reported photo from auth database
            # Allow processing 'pending' and 'reviewed' status reports (to allow changing decisions)
            result = auth_db.execute(text("""
                SELECT 
                    ipr.id,
                    ipr.photo_id,
                    ipr.status
                FROM inappropriate_photo_reports ipr
                WHERE ipr.id = :id AND ipr.status IN ('pending', 'reviewed')
            """), {"id": decision.id})
            
            row = result.fetchone()
            if not row:
                errors.append(f"Reported photo {decision.id} not found or cannot be reviewed (status: dismissed)")
                continue
            
            if decision.decision == 'remove':
                # Delete photo from main database (cascade will handle related records)
                photo = main_db.query(Photo).filter(Photo.id == row.photo_id).first()
                if not photo:
                    auth_db.execute(text("""
                        UPDATE inappropriate_photo_reports
                        SET status = 'dismissed',
                            reviewed_at = :reviewed_at,
                            reviewed_by = :reviewed_by,
                            review_notes = :review_notes
                        WHERE id = :id
                    """), {
                        "id": decision.id,
                        "reviewed_at": now,
                        "reviewed_by": admin_user_id,
                        "review_notes": decision.review_notes or "Photo not found in database; auto-dismissed"
                    })
                    auth_db.commit()
                    removed_count += 1
                    continue
                
                # Delete tag linkages for this photo
                main_db.query(PhotoTagLinkage).filter(
                    PhotoTagLinkage.photo_id == photo.id
                ).delete(synchronize_session=False)
                
                # Delete the photo (cascade will delete faces, etc.)
                main_db.delete(photo)
                main_db.commit()
                
                # Update status in auth database to dismissed
                auth_db.execute(text("""
                    UPDATE inappropriate_photo_reports
                    SET status = 'dismissed',
                        reviewed_at = :reviewed_at,
                        reviewed_by = :reviewed_by,
                        review_notes = :review_notes
                    WHERE id = :id
                """), {
                    "id": decision.id,
                    "reviewed_at": now,
                    "reviewed_by": admin_user_id,
                    "review_notes": decision.review_notes or "Photo removed"
                })
                auth_db.commit()
                
                removed_count += 1
                
            elif decision.decision == 'keep':
                # Update status to reviewed (photo stays in database)
                auth_db.execute(text("""
                    UPDATE inappropriate_photo_reports
                    SET status = 'reviewed',
                        reviewed_at = :reviewed_at,
                        reviewed_by = :reviewed_by,
                        review_notes = :review_notes
                    WHERE id = :id
                """), {
                    "id": decision.id,
                    "reviewed_at": now,
                    "reviewed_by": admin_user_id,
                    "review_notes": decision.review_notes or "Photo kept"
                })
                auth_db.commit()
                
                kept_count += 1
            else:
                errors.append(f"Invalid decision '{decision.decision}' for reported photo {decision.id}")
                
        except Exception as e:
            errors.append(f"Error processing reported photo {decision.id}: {str(e)}")
            # Rollback any partial changes
            main_db.rollback()
            auth_db.rollback()
    
    return ReviewResponse(
        kept=kept_count,
        removed=removed_count,
        errors=errors
    )


@router.post("/cleanup", response_model=CleanupResponse)
def cleanup_reported_photos(
    current_admin: dict = Depends(get_current_admin_user),
    status_filter: Annotated[
        Optional[str],
        Query(description="Use 'keep' to clear reviewed or 'remove' to clear dismissed records.")
    ] = None,
    auth_db: Session = Depends(get_auth_db),
) -> CleanupResponse:
    """Delete rows from inappropriate_photo_reports based on review status."""
    status_mapping = {
        "keep": "reviewed",
        "remove": "dismissed",
    }

    if status_filter and status_filter not in status_mapping:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="Invalid status_filter. Use 'keep', 'remove', or omit the parameter.",
        )

    db_status_filter = status_mapping.get(status_filter)
    warnings: list[str] = []

    try:
        if db_status_filter:
            result = auth_db.execute(
                text(
                    """
                    DELETE FROM inappropriate_photo_reports
                    WHERE status = :status_filter
                """
                ),
                {"status_filter": db_status_filter},
            )
        else:
            result = auth_db.execute(
                text(
                    """
                    DELETE FROM inappropriate_photo_reports
                    WHERE status IN ('reviewed', 'dismissed')
                """
                )
            )

        deleted_records = result.rowcount if hasattr(result, "rowcount") else 0
        auth_db.commit()

        if deleted_records == 0:
            if db_status_filter:
                warnings.append(
                    f"No reported photos matched the '{status_filter}' decision filter."
                )
            else:
                warnings.append("No reviewed or dismissed reported photos to delete.")

        return CleanupResponse(
            deleted_records=deleted_records,
            errors=[],
            warnings=warnings,
        )
    except Exception as exc:
        auth_db.rollback()
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Failed to cleanup reported photos: {exc}",
        )

