"""ساخت TenantContext کامل (tenant + commercial plan + دامنه‌ها + نقش کاربر) برای frontend."""
from __future__ import annotations

from uuid import UUID

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

from app.models.commercial import CommercialTenantSubscription
from app.models.tenant import Tenant
from app.models.user import User
from app.repositories.membership import TenantMembershipRepository
from app.repositories.tenant import DomainRepository, TenantRepository
from app.schemas.domain import DomainRead
from app.schemas.onboarding import MembershipSummary, TenantContextRead
from app.schemas.tenant import TenantRead
from shared.exceptions import NotFoundError


class TenantContextService:
    def __init__(self, session: AsyncSession) -> None:
        self.session = session
        self.tenant_repo = TenantRepository(session)
        self.domain_repo = DomainRepository(session)
        self.membership_repo = TenantMembershipRepository(session)

    async def build(self, tenant: Tenant, core_user: User | None) -> TenantContextRead:
        membership = None
        if core_user is not None:
            membership = await self.membership_repo.get_by_tenant_and_user(
                tenant.id, core_user.id
            )

        domains = await self.domain_repo.list_by_tenant(tenant.id)
        primary = next((d for d in domains if d.is_primary), None)
        if primary is None and domains:
            primary = domains[0]

        commercial_sub = (
            await self.session.execute(
                select(CommercialTenantSubscription)
                .where(CommercialTenantSubscription.tenant_id == tenant.id)
                .order_by(CommercialTenantSubscription.created_at.desc())
            )
        ).scalars().first()

        plan_code = commercial_sub.plan_code if commercial_sub else None
        if commercial_sub:
            plan_name = (
                commercial_sub.plan_code
                or commercial_sub.bundle_code
                or commercial_sub.pricing_item_code
            )
        else:
            plan_name = None
        subscription_status = commercial_sub.status if commercial_sub else None

        return TenantContextRead(
            tenant=TenantRead.model_validate(tenant),
            role=membership.role if membership else None,
            is_owner=bool(membership.is_owner) if membership else False,
            plan_code=plan_code,
            plan_name=plan_name,
            subscription_status=subscription_status,
            domains=[DomainRead.model_validate(d) for d in domains],
            primary_domain=primary.domain if primary else None,
        )

    async def resolve_current_tenant(self, core_user: User) -> Tenant:
        """tenant جاری کاربر را برمی‌گرداند (بر اساس current_tenant_id یا اولین عضویت)."""
        if core_user.current_tenant_id is not None:
            tenant = await self.tenant_repo.get(core_user.current_tenant_id)
            if tenant is not None:
                return tenant

        memberships = await self.membership_repo.list_by_user(core_user.id)
        if memberships:
            tenant = await self.tenant_repo.get(memberships[0].tenant_id)
            if tenant is not None:
                return tenant

        raise NotFoundError("هیچ tenantی برای کاربر جاری یافت نشد")

    async def list_memberships_summary(self, core_user: User) -> list[MembershipSummary]:
        memberships = await self.membership_repo.list_by_user(core_user.id)
        result: list[MembershipSummary] = []
        for m in memberships:
            tenant = await self.tenant_repo.get(m.tenant_id)
            if tenant is None:
                continue
            result.append(
                MembershipSummary(
                    tenant_id=tenant.id,
                    tenant_name=tenant.name,
                    tenant_slug=tenant.slug,
                    tenant_status=tenant.status,
                    onboarding_completed=tenant.onboarding_completed,
                    role=m.role,
                    status=m.status,
                    is_owner=m.is_owner,
                )
            )
        return result
