"""
Subscription Service Client
Client for interacting with subscription service functionality
"""

import structlog
from typing import Dict, Any, Optional
from sqlalchemy.ext.asyncio import AsyncSession
from fastapi import Depends

from shared.database.base import create_database_manager
from app.repositories.subscription_repository import SubscriptionRepository
from app.models.tenants import Subscription, Tenant
from app.repositories.tenant_repository import TenantRepository
from shared.subscription.plans import SubscriptionTier


logger = structlog.get_logger()


class SubscriptionServiceClient:
    """Client for subscription service operations"""
    
    def __init__(self, database_manager=None):
        self.database_manager = database_manager or create_database_manager()

    async def get_subscription(self, tenant_id: str) -> Dict[str, Any]:
        """Get subscription details for a tenant"""
        try:
            async with self.database_manager.get_session() as session:
                subscription_repo = SubscriptionRepository(Subscription, session)
                subscription = await subscription_repo.get_active_subscription(tenant_id)
                
                if not subscription:
                    # Return default starter subscription if none found
                    return {
                        'id': None,
                        'tenant_id': tenant_id,
                        'plan': SubscriptionTier.STARTER.value,
                        'status': 'active',
                        'monthly_price': 0,
                        'max_users': 5,
                        'max_locations': 1,
                        'max_products': 50,
                        'features': {}
                    }
                
                return {
                    'id': str(subscription.id) if subscription.id else None,
                    'tenant_id': tenant_id,
                    'plan': subscription.plan,
                    'status': subscription.status,
                    'monthly_price': subscription.monthly_price,
                    'max_users': subscription.max_users,
                    'max_locations': subscription.max_locations,
                    'max_products': subscription.max_products,
                    'features': subscription.features or {}
                }
        except Exception as e:
            logger.error(f"Failed to get subscription, tenant_id={tenant_id}, error={str(e)}")
            raise

    async def update_subscription_plan(self, tenant_id: str, new_plan: str) -> Dict[str, Any]:
        """Update subscription plan for a tenant"""
        try:
            async with self.database_manager.get_session() as session:
                subscription_repo = SubscriptionRepository(Subscription, session)
                
                # Get existing subscription
                existing_subscription = await subscription_repo.get_active_subscription(tenant_id)
                
                if existing_subscription:
                    # Update the existing subscription
                    updated_subscription = await subscription_repo.update_subscription(
                        existing_subscription.id, 
                        {'plan': new_plan}
                    )
                else:
                    # Create a new subscription if none exists
                    updated_subscription = await subscription_repo.create_subscription({
                        'tenant_id': tenant_id,
                        'plan': new_plan,
                        'status': 'active',
                        'created_at': None  # Let the database set this
                    })
                
                await session.commit()
                
                return {
                    'id': str(updated_subscription.id),
                    'tenant_id': tenant_id,
                    'plan': updated_subscription.plan,
                    'status': updated_subscription.status
                }
        except Exception as e:
            logger.error(f"Failed to update subscription plan, tenant_id={tenant_id}, new_plan={new_plan}, error={str(e)}")
            raise

    async def create_child_subscription(self, child_tenant_id: str, parent_tenant_id: str) -> Dict[str, Any]:
        """Create a child subscription inheriting from parent"""
        try:
            async with self.database_manager.get_session() as session:
                subscription_repo = SubscriptionRepository(Subscription, session)
                tenant_repo = TenantRepository(Tenant, session)
                
                # Get parent subscription to inherit plan
                parent_subscription = await subscription_repo.get_active_subscription(parent_tenant_id)
                
                if not parent_subscription:
                    # If parent has no subscription, create child with starter plan
                    plan = SubscriptionTier.STARTER.value
                else:
                    plan = parent_subscription.plan
                
                # Create subscription for child tenant
                child_subscription = await subscription_repo.create_subscription({
                    'tenant_id': child_tenant_id,
                    'plan': plan,
                    'status': 'active',
                    'created_at': None  # Let the database set this
                })
                
                await session.commit()
                
                # Update the child tenant's subscription tier
                await tenant_repo.update_tenant(child_tenant_id, {
                    'subscription_tier': plan
                })
                
                await session.commit()
                
                return {
                    'id': str(child_subscription.id),
                    'tenant_id': child_tenant_id,
                    'plan': child_subscription.plan,
                    'status': child_subscription.status
                }
        except Exception as e:
            logger.error("Failed to create child subscription", 
                        child_tenant_id=child_tenant_id, 
                        parent_tenant_id=parent_tenant_id, 
                        error=str(e))
            raise

    async def get_subscription_by_tenant(self, tenant_id: str) -> Optional[Dict[str, Any]]:
        """Get subscription by tenant ID"""
        return await self.get_subscription(tenant_id)

    async def get_tenant_subscription_tier(self, tenant_id: str) -> str:
        """Get the subscription tier for a tenant"""
        subscription = await self.get_subscription(tenant_id)
        return subscription.get('plan', SubscriptionTier.STARTER.value)


# Dependency function for FastAPI
async def get_subscription_service_client() -> SubscriptionServiceClient:
    """FastAPI dependency for subscription service client"""
    return SubscriptionServiceClient()