"""Email domains domain — FastAPI router."""
from __future__ import annotations

from uuid import UUID

from fastapi import APIRouter, Depends
from sqlalchemy.ext.asyncio import AsyncSession

from src.core.database import get_db
from src.core.dependencies import require_active_billing_for_workspace_id
from src.domain.admin.repository import SubscriptionPlanRepository
from src.domain.admin.router import require_admin
from src.domain.auth.models import User
from src.domain.auth.router import get_current_user
from src.domain.billing.plan_quota_service import PlanQuotaService
from src.domain.billing.repository import SubscriptionRepository
from src.domain.email_domains.models import WorkspaceEmailDomain
from src.domain.email_domains.repository import EmailDomainRepository, EmailQuotaRepository
from src.domain.email_domains.schemas import (
    EmailDomainCreate,
    EmailDomainResponse,
    EmailQuotaOverrideRequest,
    EmailUsageResponse,
)
from src.domain.email_domains.service import EmailDomainService, EmailQuotaService
from src.domain.workspaces.repository import WorkspaceRepository

router = APIRouter(tags=["email-domains"])


async def get_email_domain_service(db: AsyncSession = Depends(get_db)) -> EmailDomainService:
    return EmailDomainService(EmailDomainRepository(db))


async def get_email_quota_service(db: AsyncSession = Depends(get_db)) -> EmailQuotaService:
    return EmailQuotaService(
        EmailQuotaRepository(db),
        PlanQuotaService(WorkspaceRepository(db), SubscriptionRepository(db), SubscriptionPlanRepository(db)),
        SubscriptionRepository(db),
    )


def _domain_response(d: WorkspaceEmailDomain, service: EmailDomainService) -> EmailDomainResponse:
    resp = EmailDomainResponse.model_validate(d)
    resp.dns_instructions = service.dns_instructions_for(d)
    return resp


@router.post("/api/workspaces/{workspace_id}/email-domain", response_model=EmailDomainResponse)
async def add_email_domain(
    body: EmailDomainCreate,
    workspace_id: UUID = Depends(require_active_billing_for_workspace_id),
    user: User = Depends(get_current_user),
    service: EmailDomainService = Depends(get_email_domain_service),
    db: AsyncSession = Depends(get_db),
):
    d = await service.add_domain(workspace_id, body.domain, created_by=user.id)
    await db.commit()
    return _domain_response(d, service)


@router.get("/api/workspaces/{workspace_id}/email-domain", response_model=EmailDomainResponse | None)
async def get_email_domain(
    workspace_id: UUID = Depends(require_active_billing_for_workspace_id),
    user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
    service: EmailDomainService = Depends(get_email_domain_service),
):
    d = await EmailDomainRepository(db).get_by_workspace(workspace_id)
    return _domain_response(d, service) if d else None


@router.post("/api/workspaces/{workspace_id}/email-domain/verify", response_model=EmailDomainResponse)
async def verify_email_domain(
    workspace_id: UUID = Depends(require_active_billing_for_workspace_id),
    user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
    service: EmailDomainService = Depends(get_email_domain_service),
):
    from src.core.exceptions import NotFoundError

    existing = await EmailDomainRepository(db).get_by_workspace(workspace_id)
    if not existing:
        raise NotFoundError("No email domain configured for this workspace")
    d = await service.check_verification(existing.id)
    await db.commit()
    return _domain_response(d, service)


@router.delete("/api/workspaces/{workspace_id}/email-domain")
async def delete_email_domain(
    workspace_id: UUID = Depends(require_active_billing_for_workspace_id),
    user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
    service: EmailDomainService = Depends(get_email_domain_service),
):
    existing = await EmailDomainRepository(db).get_by_workspace(workspace_id)
    if existing:
        await service.delete_domain(existing.id)
        await db.commit()
    return {"message": "Email domain removed"}


@router.get("/api/workspaces/{workspace_id}/email-usage", response_model=EmailUsageResponse)
async def get_email_usage(
    workspace_id: UUID = Depends(require_active_billing_for_workspace_id),
    user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
    quota_service: EmailQuotaService = Depends(get_email_quota_service),
):
    q = await quota_service.get_status(workspace_id)
    await db.commit()
    return EmailUsageResponse(
        workspace_id=workspace_id,
        period_start=q.period_start,
        period_end=q.period_end,
        included_monthly=q.override_included_monthly if q.override_included_monthly is not None else q.included_monthly,
        consumed_monthly=q.consumed_monthly,
        daily_cap=q.override_daily_cap if q.override_daily_cap is not None else q.daily_cap,
        consumed_today=q.consumed_today,
        day_bucket_date=q.day_bucket_date.isoformat(),
        has_override=q.override_included_monthly is not None or q.override_daily_cap is not None,
    )


@router.post("/api/admin/workspaces/{workspace_id}/email-quota-override")
async def set_email_quota_override(
    workspace_id: UUID,
    body: EmailQuotaOverrideRequest,
    admin: User = Depends(require_admin),
    quota_service: EmailQuotaService = Depends(get_email_quota_service),
    db: AsyncSession = Depends(get_db),
):
    q = await quota_service.set_override(
        workspace_id,
        included_monthly=body.included_monthly,
        daily_cap=body.daily_cap,
        rate_per_1000_minor=body.rate_per_1000_minor,
        reason=body.reason,
        approved_by=admin.id,
    )
    await db.commit()
    return {
        "workspace_id": str(workspace_id),
        "override_included_monthly": q.override_included_monthly,
        "override_daily_cap": q.override_daily_cap,
        "override_rate_per_1000_minor": q.override_rate_per_1000_minor,
        "override_reason": q.override_reason,
    }
