"""
Dashboard API Router

Provides endpoints for dashboard-specific data like recent items across different locations.
"""

from fastapi import APIRouter, Depends, Request
from typing import Dict, Any, Optional
from slowapi import Limiter
from slowapi.util import get_remote_address
from ..core.dependencies import get_current_user, get_app_state
from ..core.exceptions import handle_exceptions
from ..core.path_tokens import encode_path
from modules.universal_logger import get_logger

router = APIRouter(prefix="/api/dashboard", tags=["dashboard"])
logger = get_logger('API')
limiter = Limiter(key_func=get_remote_address)


@router.get("/recent-items")
@limiter.limit("60/minute")
@handle_exceptions
async def get_recent_items(
    request: Request,
    limit: int = 20,
    since_id: Optional[int] = None,
    current_user=Depends(get_current_user)
) -> Dict[str, Any]:
    """
    Get NEW items from Media, Review, and Internet Discovery for dashboard cards.

    Uses file_inventory.id for ordering since it monotonically increases with
    insertion order. download_date from the downloads table is included for
    display but not used for ordering (batch downloads can interleave timestamps).

    Args:
        limit: Max items per category
        since_id: Optional file_inventory ID - only return items with id > this value

    Returns up to `limit` items from each location, sorted by most recently added first.
    """
    app_state = get_app_state()
    with app_state.db.get_connection() as conn:
        cursor = conn.cursor()

        # Media items (location='final')
        # ORDER BY fi.id DESC — id is monotonically increasing and reflects insertion order.
        # download_date is included for display but NOT used for ordering.
        if since_id:
            cursor.execute("""
                SELECT fi.id, fi.file_path, fi.filename, fi.source, fi.platform, fi.content_type,
                       fi.file_size, COALESCE(d.download_date, fi.created_date) as added_at,
                       fi.width, fi.height
                FROM file_inventory fi
                LEFT JOIN downloads d ON d.filename = fi.filename
                WHERE fi.location = 'final'
                AND fi.id > ?
                AND (fi.moved_from_review IS NULL OR fi.moved_from_review = 0)
                AND (fi.from_discovery IS NULL OR fi.from_discovery = 0)
                ORDER BY fi.id DESC
                LIMIT ?
            """, (since_id, limit))
        else:
            cursor.execute("""
                SELECT fi.id, fi.file_path, fi.filename, fi.source, fi.platform, fi.content_type,
                       fi.file_size, COALESCE(d.download_date, fi.created_date) as added_at,
                       fi.width, fi.height
                FROM file_inventory fi
                LEFT JOIN downloads d ON d.filename = fi.filename
                WHERE fi.location = 'final'
                AND (fi.moved_from_review IS NULL OR fi.moved_from_review = 0)
                AND (fi.from_discovery IS NULL OR fi.from_discovery = 0)
                ORDER BY fi.id DESC
                LIMIT ?
            """, (limit,))

        media_items = []
        for row in cursor.fetchall():
            fp = row[1]
            media_items.append({
                'id': row[0],
                'file_path': fp,
                'file_token': encode_path(fp) if fp else None,
                'filename': row[2],
                'source': row[3],
                'platform': row[4],
                'media_type': row[5],
                'file_size': row[6],
                'added_at': row[7],
                'width': row[8],
                'height': row[9]
            })

        # Get total count for new media items
        if since_id:
            cursor.execute("""
                SELECT COUNT(*)
                FROM file_inventory
                WHERE location = 'final'
                AND id > ?
                AND (moved_from_review IS NULL OR moved_from_review = 0)
                AND (from_discovery IS NULL OR from_discovery = 0)
            """, (since_id,))
        else:
            cursor.execute("""
                SELECT COUNT(*) FROM file_inventory
                WHERE location = 'final'
                AND (moved_from_review IS NULL OR moved_from_review = 0)
                AND (from_discovery IS NULL OR from_discovery = 0)
            """)
        media_count = cursor.fetchone()[0]

        # Review items (location='review')
        if since_id:
            cursor.execute("""
                SELECT f.id, f.file_path, f.filename, f.source, f.platform, f.content_type,
                       f.file_size, COALESCE(d.download_date, f.created_date) as added_at,
                       f.width, f.height,
                       CASE WHEN fr.id IS NOT NULL THEN 1 ELSE 0 END as face_scanned,
                       fr.has_match as face_matched, fr.confidence as face_confidence, fr.matched_person
                FROM file_inventory f
                LEFT JOIN downloads d ON d.filename = f.filename
                LEFT JOIN face_recognition_scans fr ON f.file_path = fr.file_path
                WHERE f.location = 'review'
                AND f.id > ?
                AND (f.moved_from_media IS NULL OR f.moved_from_media = 0)
                ORDER BY f.id DESC
                LIMIT ?
            """, (since_id, limit))
        else:
            cursor.execute("""
                SELECT f.id, f.file_path, f.filename, f.source, f.platform, f.content_type,
                       f.file_size, COALESCE(d.download_date, f.created_date) as added_at,
                       f.width, f.height,
                       CASE WHEN fr.id IS NOT NULL THEN 1 ELSE 0 END as face_scanned,
                       fr.has_match as face_matched, fr.confidence as face_confidence, fr.matched_person
                FROM file_inventory f
                LEFT JOIN downloads d ON d.filename = f.filename
                LEFT JOIN face_recognition_scans fr ON f.file_path = fr.file_path
                WHERE f.location = 'review'
                AND (f.moved_from_media IS NULL OR f.moved_from_media = 0)
                ORDER BY f.id DESC
                LIMIT ?
            """, (limit,))

        review_items = []
        for row in cursor.fetchall():
            face_recognition = None
            if row[10]:  # face_scanned
                face_recognition = {
                    'scanned': True,
                    'matched': bool(row[11]) if row[11] is not None else False,
                    'confidence': row[12],
                    'matched_person': row[13]
                }

            fp = row[1]
            review_items.append({
                'id': row[0],
                'file_path': fp,
                'file_token': encode_path(fp) if fp else None,
                'filename': row[2],
                'source': row[3],
                'platform': row[4],
                'media_type': row[5],
                'file_size': row[6],
                'added_at': row[7],
                'width': row[8],
                'height': row[9],
                'face_recognition': face_recognition
            })

        # Get total count for new review items
        if since_id:
            cursor.execute("""
                SELECT COUNT(*)
                FROM file_inventory
                WHERE location = 'review'
                AND id > ?
                AND (moved_from_media IS NULL OR moved_from_media = 0)
            """, (since_id,))
        else:
            cursor.execute("""
                SELECT COUNT(*) FROM file_inventory
                WHERE location = 'review'
                AND (moved_from_media IS NULL OR moved_from_media = 0)
            """)
        review_count = cursor.fetchone()[0]

        # Internet Discovery items (celebrity_discovered_videos with status='new')
        internet_discovery_items = []
        internet_discovery_count = 0

        try:
            cursor.execute("""
                SELECT
                    v.id,
                    v.video_id,
                    v.title,
                    v.thumbnail,
                    v.channel_name,
                    v.platform,
                    v.duration,
                    v.max_resolution,
                    v.status,
                    v.discovered_at,
                    v.url,
                    v.view_count,
                    v.upload_date,
                    c.name as celebrity_name
                FROM celebrity_discovered_videos v
                LEFT JOIN celebrity_profiles c ON v.celebrity_id = c.id
                WHERE v.status = 'new'
                ORDER BY v.id DESC
                LIMIT ?
            """, (limit,))

            for row in cursor.fetchall():
                internet_discovery_items.append({
                    'id': row[0],
                    'video_id': row[1],
                    'title': row[2],
                    'thumbnail': row[3],
                    'channel_name': row[4],
                    'platform': row[5],
                    'duration': row[6],
                    'max_resolution': row[7],
                    'status': row[8],
                    'discovered_at': row[9],
                    'url': row[10],
                    'view_count': row[11],
                    'upload_date': row[12],
                    'celebrity_name': row[13]
                })

            # Get total count for internet discovery
            cursor.execute("SELECT COUNT(*) FROM celebrity_discovered_videos WHERE status = 'new'")
            internet_discovery_count = cursor.fetchone()[0]
        except Exception as e:
            # Table might not exist if celebrity feature not used
            logger.warning(f"Could not fetch internet discovery items: {e}", module="Dashboard")

        return {
            'media': {
                'count': media_count,
                'items': media_items
            },
            'review': {
                'count': review_count,
                'items': review_items
            },
            'internet_discovery': {
                'count': internet_discovery_count,
                'items': internet_discovery_items
            }
        }


@router.get("/dismissed-cards")
@limiter.limit("60/minute")
@handle_exceptions
async def get_dismissed_cards(
    request: Request,
    user=Depends(get_current_user)
) -> Dict[str, Any]:
    """Get the user's dismissed card IDs."""
    app_state = get_app_state()
    user_id = user.get('username', 'default')

    with app_state.db.get_connection() as conn:
        cursor = conn.cursor()
        cursor.execute("""
            SELECT preference_value FROM user_preferences
            WHERE user_id = ? AND preference_key = 'dashboard_dismissed_cards'
        """, (user_id,))
        row = cursor.fetchone()

        if row and row[0]:
            import json
            return json.loads(row[0])

    return {'media': None, 'review': None, 'internet_discovery': None}


@router.post("/dismissed-cards")
@limiter.limit("30/minute")
@handle_exceptions
async def set_dismissed_cards(
    request: Request,
    data: Dict[str, Any],
    user=Depends(get_current_user)
) -> Dict[str, str]:
    """Save the user's dismissed card IDs."""
    import json
    app_state = get_app_state()
    user_id = user.get('username', 'default')

    with app_state.db.get_connection(for_write=True) as conn:
        cursor = conn.cursor()
        cursor.execute("""
            INSERT INTO user_preferences (user_id, preference_key, preference_value, updated_at)
            VALUES (?, 'dashboard_dismissed_cards', ?, CURRENT_TIMESTAMP)
            ON CONFLICT(user_id, preference_key) DO UPDATE SET
                preference_value = excluded.preference_value,
                updated_at = CURRENT_TIMESTAMP
        """, (user_id, json.dumps(data)))
        conn.commit()

    return {'status': 'ok'}
