#!/usr/bin/env python3
"""
Pushover Notification Module
Sends professional push notifications when new media is downloaded
"""

import os
import requests
from datetime import datetime
from typing import Dict, Optional, Any
from pathlib import Path
from modules.universal_logger import get_logger

logger = get_logger('Notifier')


class PushoverNotifier:
    """Handles Pushover push notifications for media downloads"""

    # Pushover API endpoint
    API_URL = "https://api.pushover.net/1/messages.json"

    # Plural forms for proper grammar
    PLURALS = {
        'story': 'stories',
        'video': 'videos',
        'photo': 'photos',
        'image': 'images',
        'reel': 'reels',
        'post': 'posts',
        'thread': 'threads',
        'item': 'items',
        'media': 'media',  # Already plural (singular: medium)
        'tagged': 'tagged',  # "Tagged" doesn't change in plural (7 Tagged Photos)
        'audio': 'audio',  # Uncountable (3 Audio Downloaded)
    }

    # Priority levels
    PRIORITY_LOW = -2
    PRIORITY_NORMAL = -1
    PRIORITY_DEFAULT = 0
    PRIORITY_HIGH = 1
    PRIORITY_EMERGENCY = 2

    # Platform emoji/icons for better visual appeal
    PLATFORM_ICONS = {
        'instagram': '📸',
        'fastdl': '📸',
        'imginn': '📸',
        'toolzu': '📸',
        'tiktok': '🎵',
        'forums': '💬',
        'snapchat': '👻',
        'youtube': '▶️',
        'twitter': '🐦',
        'easynews': '📰',
    }

    # Platform name mapping (service name -> user-friendly platform name)
    PLATFORM_NAMES = {
        'fastdl': 'Instagram',
        'imginn': 'Instagram',
        'toolzu': 'Instagram',
        'instagram': 'Instagram',
        'tiktok': 'TikTok',
        'snapchat': 'Snapchat',
        'forums': 'Forum',
        'easynews': 'Easynews',
    }

    # Content type icons
    CONTENT_ICONS = {
        'post': '🖼️',
        'story': '⭐',
        'reel': '🎬',
        'video': '🎥',
        'image': '🖼️',
        'thread': '🧵',
        'photo': '📷',
        'audio': '🎵',
    }

    def __init__(self, user_key: str, api_token: str, enabled: bool = True,
                 default_priority: int = 0, device: str = None, include_image: bool = True,
                 unified_db=None, enable_review_queue_notifications: bool = True):
        """
        Initialize Pushover notifier

        Args:
            user_key: Your Pushover user key
            api_token: Your Pushover application API token
            enabled: Whether notifications are enabled
            default_priority: Default notification priority (-2 to 2)
            device: Specific device name to send to (optional)
            include_image: Whether to include image thumbnails in notifications (default: True)
            unified_db: UnifiedDatabase instance for recording notifications (optional)
            enable_review_queue_notifications: Whether to send push notifications for review queue items (default: True)
        """
        self.user_key = user_key
        self.api_token = api_token
        self.enabled = enabled
        self.default_priority = default_priority
        self.device = device
        self.include_image = include_image
        self.unified_db = unified_db
        self.enable_review_queue_notifications = enable_review_queue_notifications
        self.stats = {
            'sent': 0,
            'failed': 0,
            'skipped': 0
        }
        # Tracking for database recording
        self._current_notification_context = None

    def _record_notification(self, title: str, message: str, priority: int, status: str, response_data: dict, image_path: str = None):
        """Record notification to database

        Args:
            title: Notification title
            message: Notification message
            priority: Priority level
            status: Status ('sent' or 'failed')
            response_data: Response from Pushover API
            image_path: Optional path to thumbnail image
        """
        if not self.unified_db:
            logger.debug("[Pushover] No database connection available for recording notification")
            return

        if not self._current_notification_context:
            logger.debug("[Pushover] No notification context available for recording")
            return

        try:
            import json

            context = self._current_notification_context

            # Add image path to metadata if provided
            metadata = context.get('metadata', {}) or {}
            if image_path:
                metadata['image_path'] = str(image_path)

            with self.unified_db.get_connection() as conn:
                cursor = conn.cursor()

                cursor.execute("""
                    INSERT INTO notifications (
                        platform, source, content_type, message, title,
                        priority, download_count, sent_at, status, response_data, metadata
                    ) VALUES (?, ?, ?, ?, ?, ?, ?, datetime('now'), ?, ?, ?)
                """, (
                    context.get('platform'),
                    context.get('source'),
                    context.get('content_type'),
                    message,
                    title,
                    priority,
                    context.get('download_count', 1),
                    status,
                    json.dumps(response_data) if response_data else None,
                    json.dumps(metadata) if metadata else None
                ))

                conn.commit()
                logger.info(f"[Pushover] Recorded notification to database: {title} (status: {status})")

                # Broadcast to frontend for real-time toast notification
                try:
                    from web.backend.api import manager
                    if manager and manager.active_connections:
                        manager.broadcast_sync({
                            'type': 'notification_created',
                            'notification': {
                                'title': title,
                                'message': message,
                                'platform': context.get('platform'),
                                'source': context.get('source'),
                                'content_type': context.get('content_type'),
                                'download_count': context.get('download_count', 1),
                                'status': status,
                            }
                        })
                except Exception:
                    # Fail silently - API may not be running or manager not available
                    pass

                # Clear context after recording to prevent stale data on subsequent notifications
                self._current_notification_context = None
        except Exception as e:
            logger.warning(f"[Pushover] Failed to record notification to database: {e}")
            import traceback
            logger.warning(f"[Pushover] Traceback: {traceback.format_exc()}")

    def _get_platform_display_name(self, platform: str, source: str = None) -> str:
        """
        Convert service name to user-friendly platform name

        Args:
            platform: Service/platform name (fastdl, imginn, toolzu, etc.)
            source: Source/username (for forums, this is the forum name)

        Returns:
            User-friendly platform name (Instagram, TikTok, etc.)
        """
        platform_lower = platform.lower()

        # For forums, use the forum name (source) as the platform display name
        if platform_lower == 'forums' and source:
            return source.title()

        return self.PLATFORM_NAMES.get(platform_lower, platform.title())

    def _pluralize(self, word: str, count: int) -> str:
        """
        Get the correct plural form of a word

        Args:
            word: Singular word
            count: Count to determine if plural needed

        Returns:
            Singular or plural form
        """
        # Handle None or empty word
        if not word:
            return "items" if count != 1 else "item"

        if count == 1:
            return word

        # Check if we have a custom plural
        word_lower = word.lower()
        if word_lower in self.PLURALS:
            return self.PLURALS[word_lower].title() if word[0].isupper() else self.PLURALS[word_lower]

        # Check if word is already a plural form (value in PLURALS)
        if word_lower in self.PLURALS.values():
            return word  # Already plural, return as-is

        # Default: just add 's' (but not if already ends with 's')
        if word_lower.endswith('s'):
            return word
        return f"{word}s"

    def _extract_random_video_frame(self, video_path: str) -> str:
        """
        Extract a random frame from a video file

        Args:
            video_path: Path to the video file

        Returns:
            Path to extracted frame (temp file) or None if extraction failed
        """
        import subprocess
        import random
        import tempfile

        try:
            # Get video duration using ffprobe
            ffprobe_cmd = [
                'ffprobe',
                '-v', 'error',
                '-show_entries', 'format=duration',
                '-of', 'default=noprint_wrappers=1:nokey=1',
                video_path
            ]

            result = subprocess.run(
                ffprobe_cmd,
                capture_output=True,
                text=True,
                timeout=10
            )

            if result.returncode != 0:
                logger.warning(f"[Pushover] ffprobe failed to get video duration: {result.stderr[:200]}")
                return None

            duration = float(result.stdout.strip())

            # Skip first and last 10% to avoid black frames
            start_offset = duration * 0.1
            end_offset = duration * 0.9

            if end_offset <= start_offset:
                # Video too short, just use middle
                timestamp = duration / 2
            else:
                # Pick random timestamp in the middle 80%
                timestamp = random.uniform(start_offset, end_offset)

            logger.debug(f"[Pushover] Video duration: {duration:.2f}s, extracting frame at {timestamp:.2f}s")

            # Create temp file for the frame
            temp_fd, temp_path = tempfile.mkstemp(suffix='.jpg', prefix='pushover_frame_')
            os.close(temp_fd)  # Close the file descriptor, ffmpeg will write to it
            success = False

            try:
                # Extract frame using ffmpeg
                ffmpeg_cmd = [
                    'ffmpeg',
                    '-ss', str(timestamp),  # Seek to timestamp
                    '-i', video_path,       # Input file
                    '-vframes', '1',        # Extract 1 frame
                    '-q:v', '2',            # High quality
                    '-y',                   # Overwrite output
                    temp_path
                ]

                result = subprocess.run(
                    ffmpeg_cmd,
                    capture_output=True,
                    text=True,
                    timeout=30
                )

                if result.returncode != 0:
                    logger.debug(f"[Pushover] ffmpeg failed: {result.stderr}")
                    return None

                # Verify the frame was created
                if Path(temp_path).exists() and Path(temp_path).stat().st_size > 0:
                    success = True
                    return temp_path
                else:
                    logger.debug("[Pushover] Frame extraction produced empty file")
                    return None

            except subprocess.TimeoutExpired:
                logger.debug("[Pushover] Video frame extraction timed out")
                return None
            finally:
                # Clean up temp file if extraction failed
                if not success:
                    try:
                        Path(temp_path).unlink(missing_ok=True)
                    except OSError:
                        pass

        except Exception as e:
            logger.debug(f"[Pushover] Error extracting video frame: {e}")
            return None

    def send_notification(self,
                         title: str,
                         message: str,
                         priority: int = None,
                         url: str = None,
                         url_title: str = None,
                         sound: str = None,
                         device: str = None,
                         html: bool = False,
                         image_path: str = None,
                         max_retries: int = 3,
                         retry_delay: int = 5) -> bool:
        """
        Send a Pushover notification with automatic retry on transient failures

        Args:
            title: Notification title
            message: Notification message
            priority: Priority level (-2 to 2)
            url: Supplementary URL
            url_title: Title for the URL
            sound: Notification sound name
            device: Specific device to send to
            html: Enable HTML formatting
            image_path: Path to image file to attach as thumbnail
            max_retries: Maximum number of retry attempts (default 3)
            retry_delay: Initial retry delay in seconds, doubles each retry (default 5)

        Returns:
            True if notification sent successfully
        """
        if not self.enabled:
            logger.debug("[Pushover] Notifications disabled, skipping")
            self.stats['skipped'] += 1
            return False

        if not self.user_key or not self.api_token:
            logger.warning("[Pushover] Missing user_key or api_token")
            self.stats['failed'] += 1
            return False

        # Normalize priority
        actual_priority = priority if priority is not None else self.default_priority

        # Prepare payload
        payload = {
            'token': self.api_token,
            'user': self.user_key,
            'title': title,
            'message': message,
            'priority': actual_priority,
        }

        # Add optional parameters
        if url:
            payload['url'] = url
        if url_title:
            payload['url_title'] = url_title
        if sound:
            payload['sound'] = sound
        if device or self.device:
            payload['device'] = device or self.device
        if html:
            payload['html'] = 1

        # Retry loop with exponential backoff
        for attempt in range(max_retries):
            try:
                # Check if we have an image to attach
                files = None
                if image_path:
                    from pathlib import Path
                    img_path = Path(image_path)

                    # Only attach if file exists and is an image
                    if img_path.exists() and img_path.suffix.lower() in ['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.webp']:
                        try:
                            # Determine MIME type
                            mime_type = 'image/jpeg'
                            if img_path.suffix.lower() == '.png':
                                mime_type = 'image/png'
                            elif img_path.suffix.lower() == '.gif':
                                mime_type = 'image/gif'
                            elif img_path.suffix.lower() == '.bmp':
                                mime_type = 'image/bmp'
                            elif img_path.suffix.lower() == '.webp':
                                mime_type = 'image/webp'

                            # Open and attach the image
                            files = {'attachment': (img_path.name, open(img_path, 'rb'), mime_type)}
                            logger.debug(f"[Pushover] Attaching image: {img_path.name}")
                        except Exception as e:
                            logger.warning(f"[Pushover] Failed to attach image {image_path}: {e}")

                response = requests.post(self.API_URL, data=payload, files=files, timeout=30)

                # Close file if opened
                if files and 'attachment' in files:
                    files['attachment'][1].close()

                if response.status_code == 200:
                    result = response.json()
                    if result.get('status') == 1:
                        request_id = result.get('request', 'unknown')
                        if attempt > 0:
                            logger.info(f"[Pushover] Notification sent after {attempt + 1} attempt(s): {title} (request: {request_id})")
                        else:
                            logger.info(f"[Pushover] Notification sent: {title} (request: {request_id})")
                        self.stats['sent'] += 1

                        # Record to database if available and we have context
                        self._record_notification(title, message, actual_priority, 'sent', result, image_path)

                        return True
                    else:
                        # API returned error status - don't retry client errors
                        logger.error(f"[Pushover] API error: {result}")
                        self.stats['failed'] += 1

                        # Record failure to database
                        self._record_notification(title, message, actual_priority, 'failed', result, image_path)

                        return False

                # Handle HTTP errors with retry logic
                elif response.status_code >= 500:
                    # Server error (5xx) - retry with backoff
                    if attempt < max_retries - 1:
                        wait_time = retry_delay * (2 ** attempt)
                        logger.warning(f"[Pushover] HTTP {response.status_code}: {response.text[:100]}, retrying in {wait_time}s (attempt {attempt + 1}/{max_retries})")
                        import time
                        time.sleep(wait_time)
                        continue
                    else:
                        # Max retries exceeded
                        logger.error(f"[Pushover] HTTP {response.status_code} after {max_retries} attempts: {response.text}")
                        self.stats['failed'] += 1
                        self._record_notification(title, message, actual_priority, 'failed', {'error': f"HTTP {response.status_code} after {max_retries} retries"}, image_path)
                        return False
                else:
                    # Client error (4xx) - don't retry
                    logger.error(f"[Pushover] HTTP {response.status_code}: {response.text}")
                    self.stats['failed'] += 1
                    self._record_notification(title, message, actual_priority, 'failed', {'error': response.text}, image_path)
                    return False

            except (requests.ConnectionError, requests.Timeout) as e:
                # Network errors - retry with backoff
                if attempt < max_retries - 1:
                    wait_time = retry_delay * (2 ** attempt)
                    logger.warning(f"[Pushover] Network error: {e}, retrying in {wait_time}s (attempt {attempt + 1}/{max_retries})")
                    import time
                    time.sleep(wait_time)
                    continue
                else:
                    # Max retries exceeded
                    logger.error(f"[Pushover] Network error after {max_retries} attempts: {e}")
                    self.stats['failed'] += 1
                    self._record_notification(title, message, actual_priority, 'failed', {'error': f"Network error after {max_retries} retries: {str(e)}"}, image_path)
                    return False

            except Exception as e:
                # Other exceptions - don't retry
                logger.error(f"[Pushover] Failed to send notification: {e}")
                self.stats['failed'] += 1
                self._record_notification(title, message, actual_priority, 'failed', {'error': str(e)}, image_path)
                return False

        # Should never reach here, but just in case
        return False

    def notify_download(self,
                       platform: str,
                       source: str,
                       content_type: str,
                       filename: str = None,
                       search_term: str = None,
                       count: int = 1,
                       metadata: Dict[str, Any] = None,
                       priority: int = None) -> bool:
        """
        Send a professional notification for a new download

        Args:
            platform: Platform name (instagram, tiktok, forum, etc.)
            source: Username or source identifier
            content_type: Type of content (post, story, reel, thread, etc.)
            filename: Optional filename
            search_term: Optional search term (for forum searches)
            count: Number of items downloaded (default 1)
            metadata: Additional metadata dictionary
            priority: Notification priority

        Returns:
            True if notification sent successfully
        """
        metadata = metadata or {}

        # Handle None content_type
        content_type = content_type or 'item'

        # Get appropriate icons
        platform_icon = self.PLATFORM_ICONS.get(platform.lower(), '📥')
        content_icon = self.CONTENT_ICONS.get(content_type.lower(), '📄')

        # Build title with proper grammar
        if count > 1:
            plural_type = self._pluralize(content_type, count)
            title = f"{platform_icon} {count} {plural_type.title()} Downloaded"
        else:
            title = f"{platform_icon} New {content_type.title()} Downloaded"

        # Build message
        message_parts = []

        # Add platform (convert service name to user-friendly platform name)
        # For forums, use forum name; for Instagram services, use "Instagram"
        platform_display = self._get_platform_display_name(platform, source)
        message_parts.append(f"📱 <b>Platform:</b> {platform_display}")

        # Add source/username (skip for forums since source becomes the platform name)
        if source and platform.lower() != 'forums':
            message_parts.append(f"{content_icon} <b>Source:</b> {source}")

        # Add search term if available
        if search_term:
            message_parts.append(f"🔍 <b>Search:</b> {search_term}")

        # Add post date if available
        if metadata.get('post_date'):
            try:
                if isinstance(metadata['post_date'], str):
                    post_date = datetime.fromisoformat(metadata['post_date'])
                else:
                    post_date = metadata['post_date']
                date_str = post_date.strftime("%Y-%m-%d %H:%M")
                message_parts.append(f"📅 <b>Posted:</b> {date_str}")
            except Exception:
                pass

        # Add timestamp
        now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        message_parts.append(f"⏰ <b>Downloaded:</b> {now}")

        message = "\n".join(message_parts)

        # Set context for database recording
        self._current_notification_context = {
            'platform': platform,
            'source': source,
            'content_type': content_type,
            'download_count': count,
            'metadata': {'search_term': search_term} if search_term else metadata
        }

        # Determine sound based on platform or priority
        sound = None
        if priority and priority >= self.PRIORITY_HIGH:
            sound = "pushover"  # Default urgent sound

        return self.send_notification(
            title=title,
            message=message,
            priority=priority,
            sound=sound,
            html=True
        )

    def notify_batch_download(self,
                             platform: str,
                             downloads: list,
                             search_term: str = None,
                             is_review_queue: bool = False) -> bool:
        """
        Send notification for batch downloads

        Args:
            platform: Platform name
            downloads: List of download dicts with keys: source, content_type, filename, file_path
            search_term: Optional search term
            is_review_queue: True if these are review queue items (no face match)

        Returns:
            True if notification sent successfully
        """
        if not downloads:
            return False

        # Check if review queue notifications are disabled
        # Always check current database value for review queue notifications
        if is_review_queue:
            if self.unified_db:
                try:
                    from modules.settings_manager import SettingsManager
                    settings_manager = SettingsManager(str(self.unified_db.db_path))
                    pushover_settings = settings_manager.get('pushover', {})
                    enable_review_notifications = pushover_settings.get('enable_review_queue_notifications', True)
                    if not enable_review_notifications:
                        logger.debug("[Pushover] Skipping review queue notification (disabled in settings)")
                        return False
                except Exception as e:
                    logger.warning(f"[Pushover] Could not check review queue notification setting, using cached value: {e}")
                    # Fall back to cached value
                    if not self.enable_review_queue_notifications:
                        logger.debug("[Pushover] Skipping review queue notification (disabled in cached settings)")
                        return False
            else:
                # No database, use cached value
                if not self.enable_review_queue_notifications:
                    logger.debug("[Pushover] Skipping review queue notification (disabled in settings)")
                    return False

        # Extract source from first download
        source = None
        if downloads and downloads[0].get('source'):
            source = downloads[0]['source']

        # Extract content type (handle None explicitly)
        content_type = (downloads[0].get('content_type') or 'item') if downloads else 'item'

        # Collect all media file paths for the notification database record
        image_extensions = {'.jpg', '.jpeg', '.png', '.gif', '.bmp', '.webp', '.heic', '.heif', '.avif', '.tiff', '.tif'}
        video_extensions = {'.mp4', '.mov', '.avi', '.mkv', '.webm', '.m4v', '.flv'}
        audio_extensions = {'.mp3', '.wav', '.flac', '.aac', '.m4a', '.ogg', '.wma'}
        all_media_paths = []

        for dl in downloads:
            file_path = dl.get('file_path')
            if file_path and Path(file_path).exists():
                suffix = Path(file_path).suffix.lower()
                ct = dl.get('content_type', '').lower()
                if ct == 'audio' or suffix in audio_extensions:
                    media_type = 'audio'
                elif ct == 'image' or suffix in image_extensions:
                    media_type = 'image'
                elif ct == 'video' or suffix in video_extensions:
                    media_type = 'video'
                else:
                    continue
                all_media_paths.append({
                    'file_path': file_path,
                    'filename': dl.get('filename', Path(file_path).name),
                    'media_type': media_type
                })

        # Set context for database recording with all media files
        metadata = {}
        if search_term:
            metadata['search_term'] = search_term
        if all_media_paths:
            metadata['media_files'] = all_media_paths  # Store all media files for notifications page

        self._current_notification_context = {
            'platform': platform,
            'source': source,
            'content_type': content_type,
            'download_count': len(downloads),
            'metadata': metadata if metadata else None
        }

        # Use different icon for review queue
        if is_review_queue:
            platform_icon = "👁️"  # Eye icon for review
        else:
            platform_icon = self.PLATFORM_ICONS.get(platform.lower(), '📥')

        # Group by content type
        by_type = {}
        for dl in downloads:
            content_type = dl.get('content_type') or 'item'  # Handle None explicitly
            by_type.setdefault(content_type, []).append(dl)

        # Build title with proper grammar
        total = len(downloads)
        if is_review_queue:
            # Review queue notification
            if len(by_type) == 1:
                content_type = list(by_type.keys())[0]
                plural_type = self._pluralize(content_type, total)
                title = f"{platform_icon} {total} {plural_type.title()} - Review Queue"
            else:
                title = f"{platform_icon} {total} Items - Review Queue"
        else:
            # Regular download notification
            if len(by_type) == 1:
                # Single content type - use specific name
                content_type = list(by_type.keys())[0]
                plural_type = self._pluralize(content_type, total)
                title = f"{platform_icon} {total} {plural_type.title()} Downloaded"
            else:
                # Multiple content types - use "Items"
                title = f"{platform_icon} {total} Items Downloaded"

        # Build message
        message_parts = []

        # Extract source from first download since they're all from same source
        source = None
        if downloads and downloads[0].get('source'):
            source = downloads[0]['source']

        # Add platform (convert service name to user-friendly platform name)
        # For forums, use forum name; for Instagram services, use "Instagram"
        platform_display = self._get_platform_display_name(platform, source)
        message_parts.append(f"📱 <b>Platform:</b> {platform_display}")

        # Add source/username (skip for forums since source becomes the platform name)
        if source and platform.lower() != 'forums':
            # Get content icon for the primary content type
            primary_content_type = list(by_type.keys())[0] if by_type else 'item'
            content_icon = self.CONTENT_ICONS.get(primary_content_type.lower(), '📄')
            message_parts.append(f"{content_icon} <b>Source:</b> {source}")

        if search_term:
            message_parts.append(f"🔍 <b>Search:</b> {search_term}")

        # Add review queue notice if applicable
        if is_review_queue:
            message_parts.append(f"\n⚠️ <b>No face match detected</b> - Items moved to review queue for manual review")

        # Summary by type (only show if multiple types)
        if len(by_type) > 1:
            message_parts.append(f"\n<b>Breakdown:</b>")
            for content_type, items in by_type.items():
                content_icon = self.CONTENT_ICONS.get(content_type.lower(), '📄')
                count = len(items)
                plural_type = self._pluralize(content_type, count)
                message_parts.append(f"{content_icon} {count} {plural_type}")

        # Add timestamp
        now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        message_parts.append(f"\n⏰ <b>Downloaded:</b> {now}")

        message = "\n".join(message_parts)

        # Select a random file for thumbnail attachment (if enabled)
        # Can be an image or video (extract random frame from video)
        import random
        image_path = None
        temp_frame_path = None  # Track temporary frame extractions

        if self.include_image:
            image_extensions = {'.jpg', '.jpeg', '.png', '.gif', '.bmp', '.webp'}
            video_extensions = {'.mp4', '.mov', '.avi', '.mkv', '.webm', '.m4v'}

            # Collect all valid media file paths (images and videos)
            media_files = []
            for dl in downloads:
                file_path = dl.get('file_path')
                if file_path:
                    exists = Path(file_path).exists()
                    if exists:
                        suffix = Path(file_path).suffix.lower()
                        if suffix in image_extensions or suffix in video_extensions:
                            media_files.append(file_path)
                        else:
                            logger.debug(f"[Pushover] Skipping file (invalid extension): {Path(file_path).name} ({suffix})")
                    else:
                        logger.warning(f"[Pushover] Skipping file (doesn't exist): {file_path}")
                else:
                    logger.warning(f"[Pushover] Download entry has no file_path")

            logger.debug(f"[Pushover] Found {len(media_files)} valid media files out of {len(downloads)} downloads")

            # Randomly select one file if available
            if media_files:
                selected_file = random.choice(media_files)
                selected_suffix = Path(selected_file).suffix.lower()

                if selected_suffix in image_extensions:
                    # It's an image, use directly
                    image_path = selected_file
                    logger.debug(f"[Pushover] Selected image thumbnail: {Path(image_path).name}")

                elif selected_suffix in video_extensions:
                    # It's a video, extract a random frame
                    logger.info(f"[Pushover] Selected video for thumbnail, extracting random frame: {Path(selected_file).name}")
                    temp_frame_path = self._extract_random_video_frame(selected_file)
                    if temp_frame_path:
                        image_path = temp_frame_path
                        logger.info(f"[Pushover] Successfully extracted video frame for thumbnail: {Path(temp_frame_path).name}")
                    else:
                        logger.warning("[Pushover] Failed to extract frame from video - notification will be sent without thumbnail")
            else:
                logger.debug("[Pushover] No media files available for thumbnail attachment")
        else:
            logger.debug("[Pushover] Image thumbnails disabled in settings")

        # Send notification with lower priority for review queue
        priority = -1 if is_review_queue else None  # Low priority for review queue
        result = self.send_notification(
            title=title,
            message=message,
            html=True,
            image_path=image_path,
            priority=priority
        )

        # Clean up temporary frame file if we created one
        if temp_frame_path and Path(temp_frame_path).exists():
            try:
                Path(temp_frame_path).unlink()
                logger.debug(f"[Pushover] Cleaned up temp frame: {Path(temp_frame_path).name}")
            except Exception as e:
                logger.debug(f"[Pushover] Failed to cleanup temp frame: {e}")

        return result

    def notify_error(self, platform: str, error_message: str, source: str = None) -> bool:
        """
        Send error notification

        Args:
            platform: Platform name
            error_message: Error description
            source: Optional source/username

        Returns:
            True if notification sent successfully
        """
        # Convert service name to user-friendly platform name
        # For forums, use forum name; for Instagram services, use "Instagram"
        platform_display = self._get_platform_display_name(platform, source)
        title = f"⚠️ {platform_display} Download Error"

        message_parts = [
            f"<b>Platform:</b> {platform_display}",
        ]

        # Add source (skip for forums since source becomes the platform name)
        if source and platform.lower() != 'forums':
            message_parts.append(f"<b>Source:</b> {source}")

        message_parts.append(f"\n<b>Error:</b> {error_message}")

        message = "\n".join(message_parts)

        return self.send_notification(
            title=title,
            message=message,
            priority=self.PRIORITY_HIGH,
            sound="siren",
            html=True
        )

    def get_stats(self) -> Dict[str, int]:
        """Get notification statistics"""
        return self.stats.copy()

    def reset_stats(self):
        """Reset statistics"""
        self.stats = {
            'sent': 0,
            'failed': 0,
            'skipped': 0
        }


def create_notifier_from_config(config: Dict, unified_db=None) -> Optional[PushoverNotifier]:
    """
    Create a PushoverNotifier from configuration dictionary

    Args:
        config: Configuration dict with pushover settings
        unified_db: UnifiedDatabase instance for recording notifications (optional)

    Returns:
        PushoverNotifier instance or None if disabled/invalid
    """
    pushover_config = config.get('pushover', {})

    if not pushover_config.get('enabled', False):
        logger.info("[Pushover] Notifications disabled in config")
        return None

    user_key = pushover_config.get('user_key')
    api_token = pushover_config.get('api_token')

    if not user_key or not api_token:
        logger.warning("[Pushover] Missing user_key or api_token in config")
        return None

    return PushoverNotifier(
        user_key=user_key,
        api_token=api_token,
        enabled=True,
        default_priority=pushover_config.get('priority', 0),
        device=pushover_config.get('device'),
        include_image=pushover_config.get('include_image', True),
        unified_db=unified_db,
        enable_review_queue_notifications=pushover_config.get('enable_review_queue_notifications', True)
    )


if __name__ == "__main__":
    # Test the notifier
    print("Testing Pushover Notifier...")

    # This is a test - replace with your actual credentials
    notifier = PushoverNotifier(
        user_key="YOUR_USER_KEY",
        api_token="YOUR_API_TOKEN",
        enabled=False  # Set to True to test
    )

    # Test notification
    notifier.notify_download(
        platform="instagram",
        source="evalongoria",
        content_type="story",
        filename="evalongoria_story_20251018.mp4",
        metadata={'post_date': datetime.now()}
    )

    print(f"Stats: {notifier.get_stats()}")
