# app/modules/messaging/routes/api/admin_email_templates.py
"""
Admin email template management endpoints.

Allows platform administrators to:
- View all email templates
- Edit template content for all languages
- Preview templates with sample data
- Send test emails
- View email logs
"""

import logging
from typing import Any

from fastapi import APIRouter, Depends
from pydantic import BaseModel, EmailStr, Field
from sqlalchemy.orm import Session

from app.api.deps import get_current_admin_api
from app.core.database import get_db
from app.modules.messaging.schemas.email import (
    EmailLogDetail,
    EmailLogListResponse,
    EmailLogStatsResponse,
)
from app.modules.messaging.services.email_service import EmailService
from app.modules.messaging.services.email_template_service import EmailTemplateService
from app.modules.tenancy.schemas.auth import UserContext

admin_email_templates_router = APIRouter(prefix="/email-templates")
admin_email_logs_router = APIRouter(prefix="/email-logs")
logger = logging.getLogger(__name__)


# =============================================================================
# SCHEMAS
# =============================================================================


class TemplateUpdate(BaseModel):
    """Schema for updating a platform template."""

    subject: str = Field(..., min_length=1, max_length=500)
    body_html: str = Field(..., min_length=1)
    body_text: str | None = None


class PreviewRequest(BaseModel):
    """Schema for previewing a template."""

    template_code: str
    language: str = "en"
    variables: dict[str, Any] = {}


class TestEmailRequest(BaseModel):
    """Schema for sending a test email."""

    template_code: str
    language: str = "en"
    to_email: EmailStr
    variables: dict[str, Any] = {}


class TemplateListItem(BaseModel):
    """Schema for a template in the list."""

    code: str
    name: str
    description: str | None = None
    category: str
    languages: list[str]  # Matches service output field name
    is_platform_only: bool = False
    variables: list[str] = []

    class Config:
        from_attributes = True


class TemplateListResponse(BaseModel):
    """Response schema for listing templates."""

    templates: list[TemplateListItem]


class CategoriesResponse(BaseModel):
    """Response schema for template categories."""

    categories: list[str]


# =============================================================================
# ENDPOINTS
# =============================================================================


@admin_email_templates_router.get("", response_model=TemplateListResponse)
def list_templates(
    current_user: UserContext = Depends(get_current_admin_api),
    db: Session = Depends(get_db),
):
    """
    List all platform email templates.

    Returns templates grouped by code with available languages.
    """
    service = EmailTemplateService(db)
    return TemplateListResponse(templates=service.list_platform_templates())


@admin_email_templates_router.get("/categories", response_model=CategoriesResponse)
def get_categories(
    current_user: UserContext = Depends(get_current_admin_api),
    db: Session = Depends(get_db),
):
    """Get list of email template categories."""
    service = EmailTemplateService(db)
    return CategoriesResponse(categories=service.get_template_categories())


@admin_email_templates_router.get("/{code}")
def get_template(
    code: str,
    current_user: UserContext = Depends(get_current_admin_api),
    db: Session = Depends(get_db),
):
    """
    Get a specific template with all language versions.

    Returns template metadata and content for all available languages.
    """
    service = EmailTemplateService(db)
    return service.get_platform_template(code)


@admin_email_templates_router.get("/{code}/{language}")
def get_template_language(
    code: str,
    language: str,
    current_user: UserContext = Depends(get_current_admin_api),
    db: Session = Depends(get_db),
):
    """
    Get a specific template for a specific language.

    Returns template content with variables information.
    """
    service = EmailTemplateService(db)
    template = service.get_platform_template_language(code, language)

    return {
        "code": template.code,
        "language": template.language,
        "name": template.name,
        "description": template.description,
        "category": template.category,
        "subject": template.subject,
        "body_html": template.body_html,
        "body_text": template.body_text,
        "variables": template.variables,
        "required_variables": template.required_variables,
        "is_platform_only": template.is_platform_only,
    }


@admin_email_templates_router.put("/{code}/{language}")
def update_template(
    code: str,
    language: str,
    template_data: TemplateUpdate,
    current_user: UserContext = Depends(get_current_admin_api),
    db: Session = Depends(get_db),
):
    """
    Update a platform email template.

    Updates the template content for a specific language.
    """
    service = EmailTemplateService(db)
    service.update_platform_template(
        code=code,
        language=language,
        subject=template_data.subject,
        body_html=template_data.body_html,
        body_text=template_data.body_text,
    )
    db.commit()

    return {"message": "Template updated successfully"}


@admin_email_templates_router.post("/{code}/preview")
def preview_template(
    code: str,
    preview_data: PreviewRequest,
    current_user: UserContext = Depends(get_current_admin_api),
    db: Session = Depends(get_db),
):
    """
    Preview a template with sample variables.

    Renders the template with provided variables and returns the result.
    """
    service = EmailTemplateService(db)

    # Merge with sample variables if not provided
    variables = {
        **_get_sample_variables(code),
        **preview_data.variables,
    }

    return service.preview_template(code, preview_data.language, variables)


@admin_email_templates_router.post("/{code}/test")
def send_test_email(
    code: str,
    test_data: TestEmailRequest,
    current_user: UserContext = Depends(get_current_admin_api),
    db: Session = Depends(get_db),
):
    """
    Send a test email using the template.

    Sends the template to the specified email address with sample data.
    """
    # Merge with sample variables
    variables = {
        **_get_sample_variables(code),
        **test_data.variables,
    }

    try:
        email_svc = EmailService(db)
        email_log = email_svc.send_template(
            template_code=code,
            to_email=test_data.to_email,
            variables=variables,
            language=test_data.language,
        )

        if email_log.status == "sent":
            return {
                "success": True,
                "message": f"Test email sent to {test_data.to_email}",
            }
        return {
            "success": False,
            "message": email_log.error_message or "Failed to send email",
        }
    except Exception as e:
        logger.exception(f"Failed to send test email: {e}")
        return {
            "success": False,
            "message": str(e),
        }


@admin_email_templates_router.get("/{code}/logs")
def get_template_logs(
    code: str,
    limit: int = 50,
    offset: int = 0,
    current_user: UserContext = Depends(get_current_admin_api),
    db: Session = Depends(get_db),
):
    """
    Get email logs for a specific template.

    Returns recent email send attempts for the template.
    """
    service = EmailTemplateService(db)
    logs, total = service.get_template_logs(code, limit, offset)

    return {
        "logs": logs,
        "total": total,
        "limit": limit,
        "offset": offset,
    }


# =============================================================================
# HELPERS
# =============================================================================


def _get_sample_variables(template_code: str) -> dict[str, Any]:
    """Get sample variables for testing templates."""
    samples = {
        "signup_welcome": {
            "first_name": "John",
            "merchant_name": "Acme Corp",
            "email": "john@example.com",
            "store_code": "acme",
            "login_url": "https://example.com/login",
            "trial_days": "14",
            "tier_name": "Business",
            "platform_name": "Orion",
        },
        "order_confirmation": {
            "customer_name": "Jane Doe",
            "order_number": "ORD-12345",
            "order_total": "€99.99",
            "order_items_count": "3",
            "order_date": "2024-01-15",
            "shipping_address": "123 Main St, Luxembourg City, L-1234",
            "platform_name": "Orion",
        },
        "password_reset": {
            "customer_name": "John Doe",
            "reset_link": "https://example.com/reset?token=abc123",
            "expiry_hours": "1",
            "platform_name": "Orion",
        },
        "team_invite": {
            "invitee_name": "Jane",
            "inviter_name": "John",
            "store_name": "Acme Corp",
            "role": "Admin",
            "accept_url": "https://example.com/accept",
            "expires_in_days": "7",
            "platform_name": "Orion",
        },
        "team_invitation": {
            "invited_by_name": "John Doe",
            "store_name": "Acme Corp",
            "role_name": "Manager",
            "acceptance_link": "https://example.com/store/invitation/accept?token=abc123",
            "expiry_days": "7",
            "platform_name": "Orion",
        },
        "subscription_welcome": {
            "store_name": "Acme Corp",
            "tier_name": "Business",
            "billing_cycle": "Monthly",
            "amount": "€49.99",
            "next_billing_date": "2024-02-15",
            "dashboard_url": "https://example.com/dashboard",
            "platform_name": "Orion",
        },
        "payment_failed": {
            "store_name": "Acme Corp",
            "tier_name": "Business",
            "amount": "€49.99",
            "retry_date": "2024-01-18",
            "update_payment_url": "https://example.com/billing",
            "support_email": "support@orion.lu",
            "platform_name": "Orion",
        },
        "subscription_cancelled": {
            "store_name": "Acme Corp",
            "tier_name": "Business",
            "end_date": "2024-02-15",
            "reactivate_url": "https://example.com/billing",
            "platform_name": "Orion",
        },
        "trial_ending": {
            "store_name": "Acme Corp",
            "tier_name": "Business",
            "days_remaining": "3",
            "trial_end_date": "2024-01-18",
            "upgrade_url": "https://example.com/upgrade",
            "features_list": "Unlimited products, API access, Priority support",
            "platform_name": "Orion",
        },
    }
    return samples.get(template_code, {"platform_name": "Orion"})


# =============================================================================
# EMAIL LOG (AUDIT) ENDPOINTS
# =============================================================================


@admin_email_logs_router.get("", response_model=EmailLogListResponse)
def list_email_logs(
    page: int = 1,
    per_page: int = 50,
    search: str | None = None,
    status: str | None = None,
    template_code: str | None = None,
    store_id: int | None = None,
    date_from: str | None = None,
    date_to: str | None = None,
    current_user: UserContext = Depends(get_current_admin_api),
    db: Session = Depends(get_db),
):
    """
    Get paginated email logs with filters.

    Supports filtering by recipient email search, status, template type,
    store, and date range.
    """
    filters = {}
    if search:
        filters["search"] = search
    if status:
        filters["status"] = status
    if template_code:
        filters["template_code"] = template_code
    if store_id:
        filters["store_id"] = store_id
    if date_from:
        filters["date_from"] = date_from
    if date_to:
        filters["date_to"] = date_to

    skip = (page - 1) * per_page
    service = EmailTemplateService(db)
    items, total = service.get_email_logs(filters=filters, skip=skip, limit=per_page)

    total_pages = (total + per_page - 1) // per_page

    return EmailLogListResponse(
        items=items,
        total=total,
        page=page,
        per_page=per_page,
        total_pages=total_pages,
    )


@admin_email_logs_router.get("/stats", response_model=EmailLogStatsResponse)
def get_email_log_stats(
    current_user: UserContext = Depends(get_current_admin_api),
    db: Session = Depends(get_db),
):
    """Get email log statistics: counts by status and by template type."""
    service = EmailTemplateService(db)
    return service.get_email_log_stats()


@admin_email_logs_router.get("/{log_id}", response_model=EmailLogDetail)
def get_email_log_detail(
    log_id: int,
    current_user: UserContext = Depends(get_current_admin_api),
    db: Session = Depends(get_db),
):
    """Get full detail for a single email log including body content for preview."""
    service = EmailTemplateService(db)
    return service.get_email_log_detail(log_id)
