# app/modules/messaging/routes/api/store_email_settings.py
"""
Store email settings API endpoints.

Allows stores to configure their email sending settings:
- SMTP configuration (all tiers)
- Advanced providers: SendGrid, Mailgun, SES (Business+ tier)
- Sender identity (from_email, from_name, reply_to)
- Signature/footer customization
- Configuration verification via test email

Store Context: Uses token_store_id from JWT token (authenticated store API pattern).
"""

import logging

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

from app.api.deps import get_current_store_api
from app.core.database import get_db
from app.modules.billing.services.subscription_service import subscription_service
from app.modules.messaging.services.store_email_settings_service import (
    store_email_settings_service,
)
from app.modules.tenancy.schemas.auth import UserContext

store_email_settings_router = APIRouter(prefix="/email-settings")
logger = logging.getLogger(__name__)


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


class EmailSettingsUpdate(BaseModel):
    """Schema for creating/updating email settings."""

    # Sender Identity (Required)
    from_email: EmailStr = Field(..., description="Sender email address")
    from_name: str = Field(..., min_length=1, max_length=100, description="Sender name")
    reply_to_email: EmailStr | None = Field(None, description="Reply-to email address")

    # Signature (Optional)
    signature_text: str | None = Field(None, description="Plain text signature")
    signature_html: str | None = Field(None, description="HTML signature/footer")

    # Provider
    provider: str = Field("smtp", description="Email provider: smtp, sendgrid, mailgun, ses")

    # SMTP Settings
    smtp_host: str | None = Field(None, description="SMTP server hostname")
    smtp_port: int | None = Field(587, ge=1, le=65535, description="SMTP server port")
    smtp_username: str | None = Field(None, description="SMTP username")
    smtp_password: str | None = Field(None, description="SMTP password")
    smtp_use_tls: bool = Field(True, description="Use STARTTLS")
    smtp_use_ssl: bool = Field(False, description="Use SSL/TLS (port 465)")

    # SendGrid
    sendgrid_api_key: str | None = Field(None, description="SendGrid API key")

    # Mailgun
    mailgun_api_key: str | None = Field(None, description="Mailgun API key")
    mailgun_domain: str | None = Field(None, description="Mailgun sending domain")

    # SES
    ses_access_key_id: str | None = Field(None, description="AWS access key ID")
    ses_secret_access_key: str | None = Field(None, description="AWS secret access key")
    ses_region: str | None = Field("eu-west-1", description="AWS region")


class VerifyEmailRequest(BaseModel):
    """Schema for verifying email settings."""

    test_email: EmailStr = Field(..., description="Email address to send test email to")


# Response models for API-001 compliance
class EmailSettingsResponse(BaseModel):
    """Response for email settings."""

    configured: bool
    verified: bool | None = None
    settings: dict | None = None
    message: str | None = None


class EmailStatusResponse(BaseModel):
    """Response for email status check."""

    is_configured: bool
    is_verified: bool


class ProvidersResponse(BaseModel):
    """Response for available providers."""

    providers: list[dict]
    current_tier: str | None


class EmailUpdateResponse(BaseModel):
    """Response for email settings update."""

    success: bool
    message: str
    settings: dict


class EmailVerifyResponse(BaseModel):
    """Response for email verification."""

    success: bool
    message: str


class EmailDeleteResponse(BaseModel):
    """Response for email settings deletion."""

    success: bool
    message: str


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


@store_email_settings_router.get("", response_model=EmailSettingsResponse)
def get_email_settings(
    current_user: UserContext = Depends(get_current_store_api),
    db: Session = Depends(get_db),
) -> EmailSettingsResponse:
    """
    Get current email settings for the store.

    Returns settings with sensitive fields masked.
    """
    store_id = current_user.token_store_id

    settings = store_email_settings_service.get_settings(db, store_id)
    if not settings:
        return EmailSettingsResponse(
            configured=False,
            settings=None,
            message="Email settings not configured. Configure SMTP to send emails to customers.",
        )

    return EmailSettingsResponse(
        configured=settings.is_configured,
        verified=settings.is_verified,
        settings=settings.to_dict(),
    )


@store_email_settings_router.get("/status", response_model=EmailStatusResponse)
def get_email_status(
    current_user: UserContext = Depends(get_current_store_api),
    db: Session = Depends(get_db),
) -> EmailStatusResponse:
    """
    Get email configuration status.

    Used by frontend to show warning banner if not configured.
    """
    store_id = current_user.token_store_id
    status = store_email_settings_service.get_status(db, store_id)
    return EmailStatusResponse(**status)


@store_email_settings_router.get("/providers", response_model=ProvidersResponse)
def get_available_providers(
    current_user: UserContext = Depends(get_current_store_api),
    db: Session = Depends(get_db),
) -> ProvidersResponse:
    """
    Get available email providers for current tier.

    Returns list of providers with availability status.
    """
    store_id = current_user.token_store_id

    # Get store's current tier
    tier = subscription_service.get_current_tier(db, store_id)

    return ProvidersResponse(
        providers=store_email_settings_service.get_available_providers(tier),
        current_tier=tier.value if tier else None,
    )


@store_email_settings_router.put("", response_model=EmailUpdateResponse)
def update_email_settings(
    data: EmailSettingsUpdate,
    current_user: UserContext = Depends(get_current_store_api),
    db: Session = Depends(get_db),
) -> EmailUpdateResponse:
    """
    Create or update email settings.

    Premium providers (SendGrid, Mailgun, SES) require Business+ tier.
    Raises AuthorizationException if tier is insufficient.
    Raises ValidationException if data is invalid.
    """
    store_id = current_user.token_store_id

    # Get store's current tier for validation
    tier = subscription_service.get_current_tier(db, store_id)

    # Service raises appropriate exceptions (API-003 compliance)
    settings = store_email_settings_service.create_or_update(
        db=db,
        store_id=store_id,
        data=data.model_dump(exclude_unset=True),
        current_tier=tier,
    )
    db.commit()

    return EmailUpdateResponse(
        success=True,
        message="Email settings updated successfully",
        settings=settings.to_dict(),
    )


@store_email_settings_router.post("/verify", response_model=EmailVerifyResponse)
def verify_email_settings(
    data: VerifyEmailRequest,
    current_user: UserContext = Depends(get_current_store_api),
    db: Session = Depends(get_db),
) -> EmailVerifyResponse:
    """
    Verify email settings by sending a test email.

    Sends a test email to the provided address and updates verification status.
    Raises ResourceNotFoundException if settings not configured.
    Raises ValidationException if verification fails.
    """
    store_id = current_user.token_store_id

    # Service raises appropriate exceptions (API-003 compliance)
    result = store_email_settings_service.verify_settings(db, store_id, data.test_email)
    db.commit()

    return EmailVerifyResponse(
        success=result["success"],
        message=result["message"],
    )


@store_email_settings_router.delete("", response_model=EmailDeleteResponse)
def delete_email_settings(
    current_user: UserContext = Depends(get_current_store_api),
    db: Session = Depends(get_db),
) -> EmailDeleteResponse:
    """
    Delete email settings.

    Warning: This will disable email sending for the store.
    Raises ResourceNotFoundException if settings not found.
    """
    store_id = current_user.token_store_id

    # Service raises ResourceNotFoundException if not found (API-003 compliance)
    store_email_settings_service.delete(db, store_id)
    db.commit()

    return EmailDeleteResponse(
        success=True,
        message="Email settings deleted",
    )
