"""Scheduled background tasks for the application"""

import logging
from datetime import datetime, timedelta
from flask import current_app
from app import db
from app.models import Invoice, User, TimeEntry
from app.utils.email import send_overdue_invoice_notification, send_weekly_summary


logger = logging.getLogger(__name__)


def check_overdue_invoices():
    """Check for overdue invoices and send notifications
    
    This task should be run daily to check for invoices that are past their due date
    and send notifications to users who have overdue invoice notifications enabled.
    """
    try:
        logger.info("Checking for overdue invoices...")
        
        # Get all invoices that are overdue and not paid/cancelled
        today = datetime.utcnow().date()
        overdue_invoices = Invoice.query.filter(
            Invoice.due_date < today,
            Invoice.status.in_(['draft', 'sent'])
        ).all()
        
        logger.info(f"Found {len(overdue_invoices)} overdue invoices")
        
        notifications_sent = 0
        for invoice in overdue_invoices:
            # Update invoice status to overdue if it's not already
            if invoice.status != 'overdue':
                invoice.status = 'overdue'
                db.session.commit()
            
            # Get users to notify (creator and admins)
            users_to_notify = set()
            
            # Add the invoice creator
            if invoice.creator:
                users_to_notify.add(invoice.creator)
            
            # Add all admins
            admins = User.query.filter_by(role='admin', is_active=True).all()
            users_to_notify.update(admins)
            
            # Send notifications
            for user in users_to_notify:
                if user.email and user.email_notifications and user.notification_overdue_invoices:
                    try:
                        send_overdue_invoice_notification(invoice, user)
                        notifications_sent += 1
                        logger.info(f"Sent overdue notification for invoice {invoice.invoice_number} to {user.username}")
                    except Exception as e:
                        logger.error(f"Failed to send notification to {user.username}: {e}")
        
        logger.info(f"Sent {notifications_sent} overdue invoice notifications")
        return notifications_sent
    
    except Exception as e:
        logger.error(f"Error checking overdue invoices: {e}")
        return 0


def send_weekly_summaries():
    """Send weekly time tracking summaries to users
    
    This task should be run weekly (e.g., Sunday evening or Monday morning)
    to send time tracking summaries to users who have opted in.
    """
    try:
        logger.info("Sending weekly summaries...")
        
        # Get users who want weekly summaries
        users = User.query.filter_by(
            is_active=True,
            email_notifications=True,
            notification_weekly_summary=True
        ).all()
        
        logger.info(f"Found {len(users)} users with weekly summaries enabled")
        
        # Calculate date range (last 7 days)
        end_date = datetime.utcnow().date()
        start_date = end_date - timedelta(days=7)
        
        summaries_sent = 0
        for user in users:
            if not user.email:
                continue
            
            try:
                # Get time entries for this user in the past week
                entries = TimeEntry.query.filter(
                    TimeEntry.user_id == user.id,
                    TimeEntry.start_time >= datetime.combine(start_date, datetime.min.time()),
                    TimeEntry.start_time < datetime.combine(end_date + timedelta(days=1), datetime.min.time()),
                    TimeEntry.end_time.isnot(None)
                ).all()
                
                if not entries:
                    logger.info(f"No entries for {user.username}, skipping")
                    continue
                
                # Calculate hours worked
                hours_worked = sum(e.duration_hours for e in entries)
                
                # Group by project
                projects_map = {}
                for entry in entries:
                    if entry.project:
                        project_name = entry.project.name
                        if project_name not in projects_map:
                            projects_map[project_name] = {'name': project_name, 'hours': 0}
                        projects_map[project_name]['hours'] += entry.duration_hours
                
                projects_data = sorted(projects_map.values(), key=lambda x: x['hours'], reverse=True)
                
                # Send email
                send_weekly_summary(
                    user=user,
                    start_date=start_date.strftime('%Y-%m-%d'),
                    end_date=end_date.strftime('%Y-%m-%d'),
                    hours_worked=hours_worked,
                    projects_data=projects_data
                )
                
                summaries_sent += 1
                logger.info(f"Sent weekly summary to {user.username}")
            
            except Exception as e:
                logger.error(f"Failed to send weekly summary to {user.username}: {e}")
        
        logger.info(f"Sent {summaries_sent} weekly summaries")
        return summaries_sent
    
    except Exception as e:
        logger.error(f"Error sending weekly summaries: {e}")
        return 0


def register_scheduled_tasks(scheduler):
    """Register all scheduled tasks with APScheduler
    
    Args:
        scheduler: APScheduler instance
    """
    try:
        # Check overdue invoices daily at 9 AM
        scheduler.add_job(
            func=check_overdue_invoices,
            trigger='cron',
            hour=9,
            minute=0,
            id='check_overdue_invoices',
            name='Check for overdue invoices',
            replace_existing=True
        )
        logger.info("Registered overdue invoices check task")
        
        # Send weekly summaries every Monday at 8 AM
        scheduler.add_job(
            func=send_weekly_summaries,
            trigger='cron',
            day_of_week='mon',
            hour=8,
            minute=0,
            id='send_weekly_summaries',
            name='Send weekly time summaries',
            replace_existing=True
        )
        logger.info("Registered weekly summaries task")
        
    except Exception as e:
        logger.error(f"Error registering scheduled tasks: {e}")

