"""
Servizio tenant – gestione organizzazioni (solo super_admin).
"""

import uuid

from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession

from app.core.exceptions import ConflictError, NotFoundError
from app.core.security import hash_password
from app.models.tenant import Tenant
from app.models.user import User
from app.schemas.tenant import TenantCreateRequest, TenantUpdateRequest


class TenantService:
    def __init__(self, db: AsyncSession) -> None:
        self.db = db

    async def create_tenant(self, data: TenantCreateRequest) -> tuple[Tenant, User]:
        """Crea un nuovo tenant con il suo utente admin iniziale."""
        # Verifica slug univoco
        existing = await self.db.execute(
            select(Tenant).where(Tenant.slug == data.slug)
        )
        if existing.scalar_one_or_none():
            raise ConflictError(f"Slug '{data.slug}' già in uso")

        tenant = Tenant(
            slug=data.slug,
            name=data.name,
            plan=data.plan,
            max_mailboxes=data.max_mailboxes,
            max_users=data.max_users,
        )
        self.db.add(tenant)
        await self.db.flush()  # ottieni tenant.id

        # Crea utente admin iniziale
        admin = User(
            tenant_id=tenant.id,
            email=data.admin_email.lower(),
            password_hash=hash_password(data.admin_password),
            full_name=data.admin_full_name,
            role="admin",
        )
        self.db.add(admin)
        await self.db.flush()

        return tenant, admin

    async def get_tenant(self, tenant_id: uuid.UUID) -> Tenant:
        tenant = await self.db.get(Tenant, tenant_id)
        if not tenant:
            raise NotFoundError("tenant")
        return tenant

    async def list_tenants(self) -> list[Tenant]:
        result = await self.db.execute(
            select(Tenant).order_by(Tenant.created_at.desc())
        )
        return list(result.scalars().all())

    async def update_tenant(
        self, tenant_id: uuid.UUID, data: TenantUpdateRequest
    ) -> Tenant:
        tenant = await self.get_tenant(tenant_id)

        if data.name is not None:
            tenant.name = data.name
        if data.plan is not None:
            tenant.plan = data.plan
        if data.is_active is not None:
            tenant.is_active = data.is_active
        if data.max_mailboxes is not None:
            tenant.max_mailboxes = data.max_mailboxes
        if data.max_users is not None:
            tenant.max_users = data.max_users

        return tenant
