"""
Email Sending Worker Tasks
Handles all email operations asynchronously
"""
import logging
from typing import Optional, Dict, Any, List

from celery import shared_task
from sqlalchemy import select

from app.workers.celery_app import celery
from app.database import get_sync_session
from app.config import settings

logger = logging.getLogger(__name__)


# Email templates
EMAIL_TEMPLATES = {
    "welcome": {
        "subject": "Welcome to AI360 Solutions!",
        "body": """
Hello {client_name},

Welcome to AI360 Solutions! We're excited to have you on board.

Your account has been created successfully. You can now access your dashboard at:
{dashboard_url}

Here's what you can do next:
1. Set up your first chatbot
2. Customize your branding settings
3. Integrate with your website or WhatsApp

If you have any questions, our support team is here to help.

Best regards,
The AI360 Team
        """
    },
    "invoice": {
        "subject": "Invoice {invoice_number} - AI360 Solutions",
        "body": """
Hello {client_name},

Please find attached your invoice for the billing period: {billing_period}

Invoice Details:
- Invoice Number: {invoice_number}
- Amount Due: {currency} {amount}
- Due Date: {due_date}

You can view and pay your invoice online at:
{payment_url}

Thank you for your business!

Best regards,
The AI360 Team
        """
    },
    "invoice_reminder": {
        "subject": "Payment Reminder - Invoice {invoice_number}",
        "body": """
Hello {client_name},

This is a friendly reminder that your invoice {invoice_number} is due in {days_until_due} days.

Invoice Details:
- Amount Due: {currency} {amount}
- Due Date: {due_date}

Please make the payment at your earliest convenience:
{payment_url}

If you've already made the payment, please disregard this email.

Best regards,
The AI360 Team
        """
    },
    "invoice_overdue": {
        "subject": "OVERDUE: Invoice {invoice_number} - Immediate Action Required",
        "body": """
Hello {client_name},

Your invoice {invoice_number} is now {days_overdue} days overdue.

Invoice Details:
- Amount Due: {currency} {amount}
- Original Due Date: {due_date}

Please make the payment immediately to avoid service interruption:
{payment_url}

If you're experiencing difficulties, please contact our support team.

Best regards,
The AI360 Team
        """
    },
    "payment_success": {
        "subject": "Payment Received - Thank You!",
        "body": """
Hello {client_name},

We've received your payment for invoice {invoice_number}.

Payment Details:
- Amount: {currency} {amount}
- Transaction ID: {transaction_id}
- Date: {payment_date}

Thank you for your prompt payment!

Best regards,
The AI360 Team
        """
    },
    "usage_warning": {
        "subject": "Usage Alert: {percentage} of {resource_type} limit reached",
        "body": """
Hello {client_name},

This is to notify you that you've used {percentage} of your monthly {resource_type} limit.

Current Usage: {current_usage} / {limit}

To avoid service interruption, consider upgrading your plan:
{upgrade_url}

Best regards,
The AI360 Team
        """
    },
    "limit_exceeded": {
        "subject": "ALERT: Monthly {resource_type} limit exceeded",
        "body": """
Hello {client_name},

You have exceeded your monthly {resource_type} limit.

Current Usage: {current_usage} / {limit}

Your service may be affected. Please upgrade your plan immediately:
{upgrade_url}

Best regards,
The AI360 Team
        """
    },
    "daily_usage_report": {
        "subject": "Daily Usage Report - {date}",
        "body": """
Hello {client_name},

Here's your daily usage summary for {date}:

- Total Messages: {total_messages}
- Total Conversations: {total_conversations}
- Total Tokens: {total_tokens}
- Estimated Cost: {total_cost}

View detailed analytics in your dashboard:
https://portal.ai360.com/analytics

Best regards,
The AI360 Team
        """
    },
    "team_invitation": {
        "subject": "You've been invited to join {company_name} on AI360",
        "body": """
Hello,

{inviter_name} has invited you to join {company_name} on AI360 Solutions.

You've been assigned the role: {role}

Click the link below to accept the invitation:
{invitation_url}

This invitation expires on {expires_at}.

Best regards,
The AI360 Team
        """
    },
    "password_reset": {
        "subject": "Reset Your Password - AI360 Solutions",
        "body": """
Hello {name},

We received a request to reset your password for your AI360 account.

Click the link below to reset your password:
{reset_url}

This link expires in {expires_in} hours.

If you didn't request this, please ignore this email.

Best regards,
The AI360 Team
        """
    },
    "email_verification": {
        "subject": "Verify Your Email - AI360 Solutions",
        "body": """
Hello {name},

Please verify your email address by clicking the link below:
{verification_url}

This link expires in {expires_in} hours.

Best regards,
The AI360 Team
        """
    },
    "subscription_activated": {
        "subject": "Subscription Activated - {plan_name}",
        "body": """
Hello {client_name},

Your subscription to {plan_name} has been activated successfully!

Plan Details:
- Plan: {plan_name}
- Billing Cycle: {billing_cycle}
- Next Billing Date: {next_billing_date}

You now have access to all features included in your plan.

Best regards,
The AI360 Team
        """
    },
    "subscription_cancelled": {
        "subject": "Subscription Cancelled - AI360 Solutions",
        "body": """
Hello {client_name},

Your subscription has been cancelled as requested.

Your access will continue until: {access_end_date}

We're sorry to see you go! If you change your mind, you can reactivate your subscription anytime.

Best regards,
The AI360 Team
        """
    },
    "payment_retry_reminder": {
        "subject": "Action Required: Payment Retry for Invoice {invoice_number}",
        "body": """
Hello {client_name},

We were unable to process the payment for your invoice {invoice_number}.

Invoice Details:
- Amount Due: {currency} {amount}
- Attempt: {attempt_number} of 4

Please update your payment method or make a manual payment:
{payment_url}

To avoid service interruption, please complete this payment as soon as possible.

Best regards,
The AI360 Team
        """
    },
    "refund_processed": {
        "subject": "Refund Processed - AI360 Solutions",
        "body": """
Hello {client_name},

We have processed a refund for your invoice {invoice_number}.

Refund Details:
- Refund Amount: {currency} {refund_amount}
- Original Amount: {currency} {original_amount}
- Refund Date: {refund_date}

The refund should appear in your account within 5-7 business days.

If you have any questions, please contact our support team.

Best regards,
The AI360 Team
        """
    },
    "subscription_suspended": {
        "subject": "IMPORTANT: Your Subscription Has Been Suspended",
        "body": """
Hello {client_name},

Your AI360 subscription has been temporarily suspended.

Reason: {reason}

To reactivate your subscription and restore access to all features, please update your payment method:
{reactivation_url}

If you believe this is an error, please contact our support team immediately.

Best regards,
The AI360 Team
        """
    },
    "subscription_reactivated": {
        "subject": "Your Subscription Has Been Reactivated!",
        "body": """
Hello {client_name},

Great news! Your AI360 subscription has been successfully reactivated.

You now have full access to all your features and services.

Access your dashboard:
{dashboard_url}

Thank you for continuing with AI360 Solutions!

Best regards,
The AI360 Team
        """
    },
    "plan_change_confirmation": {
        "subject": "Plan Change Confirmed - AI360 Solutions",
        "body": """
Hello {client_name},

Your plan has been successfully changed!

Plan Change Details:
- Previous Plan: {old_plan_name}
- New Plan: {new_plan_name}
- Effective Date: {effective_date}
- Proration Credit: {currency} {credit_amount}
- Proration Charge: {currency} {charge_amount}
- Net Amount: {currency} {net_amount}

Your new plan features are now active.

Best regards,
The AI360 Team
        """
    },
    "payment_failed_final": {
        "subject": "URGENT: Final Payment Attempt Failed - Action Required",
        "body": """
Hello {client_name},

Unfortunately, all payment attempts for invoice {invoice_number} have failed.

Amount Due: {currency} {amount}

Your subscription has been suspended to prevent further service usage.

To restore your services, please:
1. Update your payment method
2. Clear the outstanding balance

Reactivate now: {reactivation_url}

If you need assistance, please contact our billing team.

Best regards,
The AI360 Team
        """
    },
}


@celery.task(
    bind=True,
    name="app.workers.tasks.email_tasks.send_email",
    max_retries=3,
    default_retry_delay=60,
    queue="emails"
)
def send_email(
    self,
    recipient_email: str,
    subject: str,
    body: str,
    recipient_name: Optional[str] = None,
    html_body: Optional[str] = None,
    attachments: Optional[List[Dict[str, Any]]] = None,
    reply_to: Optional[str] = None,
    cc: Optional[List[str]] = None,
    bcc: Optional[List[str]] = None,
    track_opens: bool = True,
    track_clicks: bool = True
) -> Dict[str, Any]:
    """
    Send a single email

    Args:
        recipient_email: Recipient email address
        subject: Email subject
        body: Plain text body
        recipient_name: Recipient name
        html_body: HTML body (optional)
        attachments: List of attachments
        reply_to: Reply-to address
        cc: CC addresses
        bcc: BCC addresses
        track_opens: Track email opens
        track_clicks: Track link clicks
    """
    try:
        logger.info(f"Sending email to {recipient_email}: {subject}")

        # Import email service
        from app.services.email_service import EmailService

        email_service = EmailService()

        result = email_service.send_email(
            to_email=recipient_email,
            to_name=recipient_name,
            subject=subject,
            text_content=body,
            html_content=html_body,
            attachments=attachments,
            reply_to=reply_to,
            cc=cc,
            bcc=bcc,
            track_opens=track_opens,
            track_clicks=track_clicks
        )

        if result.success:
            logger.info(f"Email sent successfully to {recipient_email}, message_id: {result.message_id}")
            return {
                "success": True,
                "message_id": result.message_id,
                "provider": result.provider
            }
        else:
            logger.error(f"Failed to send email to {recipient_email}: {result.error}")
            raise Exception(result.error)

    except Exception as e:
        logger.error(f"Error sending email to {recipient_email}: {str(e)}")
        self.retry(exc=e)


@celery.task(
    bind=True,
    name="app.workers.tasks.email_tasks.send_templated_email",
    max_retries=3,
    default_retry_delay=60,
    queue="emails"
)
def send_templated_email(
    self,
    template_name: str,
    recipient_email: str,
    recipient_name: Optional[str] = None,
    context: Optional[Dict[str, Any]] = None,
    attachments: Optional[List[Dict[str, Any]]] = None,
    custom_subject: Optional[str] = None
) -> Dict[str, Any]:
    """
    Send a templated email

    Args:
        template_name: Name of the email template
        recipient_email: Recipient email address
        recipient_name: Recipient name
        context: Template context variables
        attachments: List of attachments
        custom_subject: Override template subject
    """
    try:
        logger.info(f"Sending templated email '{template_name}' to {recipient_email}")

        if template_name not in EMAIL_TEMPLATES:
            raise ValueError(f"Unknown email template: {template_name}")

        template = EMAIL_TEMPLATES[template_name]
        context = context or {}

        # Format subject and body
        subject = custom_subject or template["subject"].format(**context)
        body = template["body"].format(**context)

        # Send email
        result = send_email.apply(
            args=[recipient_email, subject, body],
            kwargs={
                "recipient_name": recipient_name,
                "attachments": attachments
            }
        )

        return result.get()

    except KeyError as e:
        logger.error(f"Missing context variable for template '{template_name}': {e}")
        raise
    except Exception as e:
        logger.error(f"Error sending templated email: {str(e)}")
        self.retry(exc=e)


@celery.task(
    bind=True,
    name="app.workers.tasks.email_tasks.send_bulk_emails",
    max_retries=2,
    queue="emails"
)
def send_bulk_emails(
    self,
    recipients: List[Dict[str, str]],
    subject: str,
    body: str,
    html_body: Optional[str] = None,
    batch_size: int = 100,
    delay_between_batches: int = 1
) -> Dict[str, Any]:
    """
    Send bulk emails to multiple recipients

    Args:
        recipients: List of {"email": "", "name": ""} dicts
        subject: Email subject
        body: Plain text body
        html_body: HTML body (optional)
        batch_size: Number of emails per batch
        delay_between_batches: Seconds between batches
    """
    try:
        logger.info(f"Sending bulk emails to {len(recipients)} recipients")

        results = {
            "total": len(recipients),
            "sent": 0,
            "failed": 0,
            "errors": []
        }

        # Process in batches
        for i in range(0, len(recipients), batch_size):
            batch = recipients[i:i + batch_size]

            for recipient in batch:
                try:
                    send_email.delay(
                        recipient_email=recipient["email"],
                        subject=subject,
                        body=body,
                        recipient_name=recipient.get("name"),
                        html_body=html_body
                    )
                    results["sent"] += 1
                except Exception as e:
                    results["failed"] += 1
                    results["errors"].append({
                        "email": recipient["email"],
                        "error": str(e)
                    })

            # Delay between batches to avoid rate limits
            if i + batch_size < len(recipients):
                import time
                time.sleep(delay_between_batches)

        logger.info(f"Bulk email complete: {results}")
        return results

    except Exception as e:
        logger.error(f"Error sending bulk emails: {str(e)}")
        self.retry(exc=e)


@celery.task(
    bind=True,
    name="app.workers.tasks.email_tasks.send_bulk_templated_emails",
    max_retries=2,
    queue="emails"
)
def send_bulk_templated_emails(
    self,
    template_name: str,
    recipients: List[Dict[str, Any]],
    batch_size: int = 100
) -> Dict[str, Any]:
    """
    Send bulk templated emails with personalized context

    Args:
        template_name: Name of the email template
        recipients: List of {"email": "", "name": "", "context": {}} dicts
        batch_size: Number of emails per batch
    """
    try:
        logger.info(f"Sending bulk templated emails '{template_name}' to {len(recipients)} recipients")

        results = {
            "total": len(recipients),
            "queued": 0,
            "failed": 0,
            "errors": []
        }

        for recipient in recipients:
            try:
                send_templated_email.delay(
                    template_name=template_name,
                    recipient_email=recipient["email"],
                    recipient_name=recipient.get("name"),
                    context=recipient.get("context", {})
                )
                results["queued"] += 1
            except Exception as e:
                results["failed"] += 1
                results["errors"].append({
                    "email": recipient["email"],
                    "error": str(e)
                })

        logger.info(f"Bulk templated email queued: {results}")
        return results

    except Exception as e:
        logger.error(f"Error queuing bulk templated emails: {str(e)}")
        self.retry(exc=e)


@celery.task(
    name="app.workers.tasks.email_tasks.send_welcome_email",
    queue="emails"
)
def send_welcome_email(
    client_id: int,
    user_email: str,
    user_name: str
) -> Dict[str, Any]:
    """
    Send welcome email to new client

    Args:
        client_id: Client ID
        user_email: User email
        user_name: User name
    """
    return send_templated_email.apply(
        args=["welcome", user_email],
        kwargs={
            "recipient_name": user_name,
            "context": {
                "client_name": user_name,
                "dashboard_url": f"https://portal.ai360.com/dashboard"
            }
        }
    ).get()


@celery.task(
    name="app.workers.tasks.email_tasks.send_team_invitation_email",
    queue="emails"
)
def send_team_invitation_email(
    invitation_id: int
) -> Dict[str, Any]:
    """
    Send team invitation email

    Args:
        invitation_id: Team invitation ID
    """
    try:
        from app.models.client_settings import TeamInvitation
        from app.models.user import User
        from app.models.client import Client

        with get_sync_session() as session:
            invitation = session.execute(
                select(TeamInvitation)
                .where(TeamInvitation.id == invitation_id)
            ).scalar_one_or_none()

            if not invitation:
                return {"success": False, "error": "Invitation not found"}

            # Get inviter
            inviter = session.execute(
                select(User).where(User.id == invitation.invited_by_id)
            ).scalar_one_or_none()

            # Get client
            client = session.execute(
                select(Client).where(Client.id == invitation.client_id)
            ).scalar_one_or_none()

            return send_templated_email.apply(
                args=["team_invitation", invitation.email],
                kwargs={
                    "context": {
                        "inviter_name": inviter.name if inviter else "Team Admin",
                        "company_name": client.company_name if client else "Your Organization",
                        "role": invitation.role,
                        "invitation_url": f"https://portal.ai360.com/invitation/{invitation.token}",
                        "expires_at": invitation.expires_at.strftime("%B %d, %Y")
                    }
                }
            ).get()

    except Exception as e:
        logger.error(f"Error sending team invitation email: {str(e)}")
        return {"success": False, "error": str(e)}


@celery.task(
    name="app.workers.tasks.email_tasks.send_password_reset_email",
    queue="emails"
)
def send_password_reset_email(
    user_email: str,
    user_name: str,
    reset_token: str,
    expires_in_hours: int = 24
) -> Dict[str, Any]:
    """
    Send password reset email

    Args:
        user_email: User email
        user_name: User name
        reset_token: Password reset token
        expires_in_hours: Token expiration hours
    """
    return send_templated_email.apply(
        args=["password_reset", user_email],
        kwargs={
            "recipient_name": user_name,
            "context": {
                "name": user_name,
                "reset_url": f"https://portal.ai360.com/reset-password?token={reset_token}",
                "expires_in": expires_in_hours
            }
        }
    ).get()


@celery.task(
    name="app.workers.tasks.email_tasks.send_verification_email",
    queue="emails"
)
def send_verification_email(
    user_email: str,
    user_name: str,
    verification_token: str,
    expires_in_hours: int = 48
) -> Dict[str, Any]:
    """
    Send email verification email

    Args:
        user_email: User email
        user_name: User name
        verification_token: Email verification token
        expires_in_hours: Token expiration hours
    """
    return send_templated_email.apply(
        args=["email_verification", user_email],
        kwargs={
            "recipient_name": user_name,
            "context": {
                "name": user_name,
                "verification_url": f"https://portal.ai360.com/verify-email?token={verification_token}",
                "expires_in": expires_in_hours
            }
        }
    ).get()
