"""
Daily reminder scanner for subscription expiry and invoice overdue.
Runs at 09:00 Pacific/Auckland daily via APScheduler.
"""

from datetime import date, timedelta
from app.core.database import get_db
from app.core.models import (
    Subscription, SubscriptionStatus, Invoice, InvoiceStatus,
    Reminder, ReminderType, Customer, EmailLog, EmailLogStatus, TelegramLog, TelegramLogStatus
)
from app.services.email_service import send_email
from app.services.telegram_service import send_telegram_message, format_reminder_message
from app.core.config import get_telegram_config
import logging

logger = logging.getLogger(__name__)


async def check_and_send_reminders():
    """Main daily reminder check."""
    db = next(get_db())
    today = date.today()
    config = get_telegram_config()
    chat_id = config["chat_id"]
    
    results = {"subscription_expiry": {"checked": 0, "sent": 0}, "invoice_overdue": {"checked": 0, "sent": 0}}
    
    active_reminders = db.query(Reminder).filter(Reminder.status == "active").all()
    for reminder in active_reminders:
        if reminder.reminder_type == ReminderType.subscription_expiry:
            await _check_subscription_expiry(db, reminder, today, chat_id, results)
        elif reminder.reminder_type == ReminderType.invoice_overdue:
            await _check_invoice_overdue(db, reminder, today, chat_id, results)
    
    return results


async def _check_subscription_expiry(db, reminder, today, chat_id, results):
    future_date = today + timedelta(days=reminder.trigger_days)
    
    subs = db.query(Subscription).filter(
        Subscription.status == SubscriptionStatus.active,
        Subscription.end_date != None,
        Subscription.end_date <= future_date,
        Subscription.end_date >= today,
    ).all()
    
    results["subscription_expiry"]["checked"] = len(subs)
    
    for sub in subs:
        customer = db.query(Customer).get(sub.customer_id)
        days_left = (sub.end_date - today).days
        product_name = sub.product.name if sub.product else "Unknown"
        entity_name = f"{customer.name if customer else 'Unknown'} - {product_name}"
        details = f"Auto-renew: {'Yes' if sub.auto_renew else 'No'}"
        tg_msg = format_reminder_message("subscription_expiry", entity_name, days_left, details)
        
        if reminder.send_telegram:
            result = await send_telegram_message(chat_id, tg_msg)
            log = TelegramLog(
                chat_id=chat_id, message=tg_msg,
                status=TelegramLogStatus.sent if result["success"] else TelegramLogStatus.failed,
                error_message=result.get("error"))
            db.add(log)
            if result["success"]:
                results["subscription_expiry"]["sent"] += 1
        
        if reminder.send_email and customer and customer.email:
            body = f"Subscription {product_name} expires in {days_left} days.\nAuto-renew: {'Yes' if sub.auto_renew else 'No'}"
            email_result = await send_email(customer.email, "Subscription Expiry Reminder", body)
            db.add(EmailLog(
                recipient=customer.email, subject="Subscription Expiry Reminder", body=body,
                status=EmailLogStatus.sent if email_result["success"] else EmailLogStatus.failed,
                error_message=email_result.get("error")))
        
        db.commit()


async def _check_invoice_overdue(db, reminder, today, chat_id, results):
    overdue_invoices = db.query(Invoice).filter(
        Invoice.status.in_([InvoiceStatus.issued, InvoiceStatus.sent]),
        Invoice.due_date != None,
        Invoice.due_date < today,
    ).all()
    
    results["invoice_overdue"]["checked"] = len(overdue_invoices)
    
    for invoice in overdue_invoices:
        if invoice.status not in [InvoiceStatus.overdue, InvoiceStatus.paid, InvoiceStatus.void]:
            invoice.status = InvoiceStatus.overdue
            db.commit()
        
        customer = db.query(Customer).get(invoice.customer_id)
        days_overdue = (today - invoice.due_date).days
        details = f"Amount: {invoice.currency} {float(invoice.total_amount):,.2f}"
        tg_msg = format_reminder_message("invoice_overdue", invoice.invoice_number, days_overdue, details)
        
        if reminder.send_telegram:
            result = await send_telegram_message(chat_id, tg_msg)
            log = TelegramLog(
                chat_id=chat_id, message=tg_msg,
                status=TelegramLogStatus.sent if result["success"] else TelegramLogStatus.failed,
                error_message=result.get("error"))
            db.add(log)
            if result["success"]:
                results["invoice_overdue"]["sent"] += 1
        
        if reminder.send_email and customer and customer.email:
            body = f"Invoice {invoice.invoice_number} is {days_overdue} days overdue. Amount: {invoice.currency} {float(invoice.total_amount):,.2f}"
            email_result = await send_email(customer.email, "Invoice Overdue Reminder", body)
            db.add(EmailLog(
                recipient=customer.email, subject="Invoice Overdue Reminder", body=body,
                status=EmailLogStatus.sent if email_result["success"] else EmailLogStatus.failed,
                error_message=email_result.get("error")))
        
        db.commit()


def setup_reminder_scheduler():
    """Set up APScheduler for daily reminders at 09:00 Pacific/Auckland."""
    from apscheduler.schedulers.asyncio import AsyncIOScheduler
    from apscheduler.triggers.cron import CronTrigger
    
    scheduler = AsyncIOScheduler()
    scheduler.add_job(
        check_and_send_reminders,
        CronTrigger(hour=9, minute=0, timezone="Pacific/Auckland"),
        id="daily_reminder_check",
        name="Daily Reminder Check",
        replace_existing=True,
    )
    scheduler.start()
    return scheduler