"""سرویس مدیریت اشتراک tenant."""
from __future__ import annotations

from uuid import UUID

from sqlalchemy.ext.asyncio import AsyncSession

from app.core.cache import cache
from app.models.subscription import TenantSubscription
from app.repositories.plan import PlanRepository
from app.repositories.subscription import SubscriptionRepository
from app.repositories.tenant import TenantRepository
from app.schemas.subscription import SubscriptionCreate
from app.services.event_service import EventService
from shared.events import CoreEventType
from shared.exceptions import NotFoundError


class SubscriptionService:
    def __init__(self, session: AsyncSession) -> None:
        self.session = session
        self.repo = SubscriptionRepository(session)
        self.tenant_repo = TenantRepository(session)
        self.plan_repo = PlanRepository(session)
        self.events = EventService(session)

    async def create(self, tenant_id: UUID, data: SubscriptionCreate) -> TenantSubscription:
        tenant = await self.tenant_repo.get(tenant_id)
        if tenant is None:
            raise NotFoundError(f"tenant یافت نشد: {tenant_id}")
        plan = await self.plan_repo.get(data.plan_id)
        if plan is None:
            raise NotFoundError(f"پلن یافت نشد: {data.plan_id}")

        subscription = TenantSubscription(
            tenant_id=tenant_id,
            plan_id=data.plan_id,
            status=data.status,
            starts_at=data.starts_at,
            ends_at=data.ends_at,
            trial_ends_at=data.trial_ends_at,
        )
        await self.repo.add(subscription)
        await self.events.record(
            event_type=CoreEventType.SUBSCRIPTION_CREATED.value,
            aggregate_type="subscription",
            aggregate_id=str(subscription.id),
            tenant_id=tenant_id,
            payload={"plan_id": str(data.plan_id), "status": data.status.value},
        )
        await self.session.commit()
        await self.session.refresh(subscription)
        # با تغییر اشتراک، cache دسترسی قابلیت‌ها باید باطل شود.
        await cache.delete_pattern(f"feature_access:{tenant_id}:*")
        await cache.delete(f"tenant:{tenant_id}:features")
        return subscription

    async def get_current(self, tenant_id: UUID) -> TenantSubscription:
        subscription = await self.repo.get_active_by_tenant(tenant_id)
        if subscription is None:
            raise NotFoundError(f"اشتراکی برای tenant یافت نشد: {tenant_id}")
        return subscription
