"""
Core services for identity domain.
"""
from typing import Tuple


class StorageQuotaService:
    """
    Service for managing tenant storage quotas.

    Handles:
    - Checking storage quota from billing features
    - Getting current usage
    - Validating uploads against quota
    - Updating usage after upload/delete
    """

    # Default storage in GB for tenants without a subscription
    DEFAULT_STORAGE_GB = 1

    @staticmethod
    def get_quota_bytes(tenant) -> int:
        """
        Get storage quota in bytes from billing feature.

        Args:
            tenant: Tenant instance

        Returns:
            int: Storage quota in bytes
        """
        from smoothschedule.billing.services.entitlements import EntitlementService

        # Get storage_gb feature value from billing
        if hasattr(tenant, 'billing_subscription') and tenant.billing_subscription:
            storage_gb = EntitlementService.get_feature_value(
                tenant,
                'storage_gb',
                default=StorageQuotaService.DEFAULT_STORAGE_GB
            )
        else:
            storage_gb = StorageQuotaService.DEFAULT_STORAGE_GB

        # Convert GB to bytes (1 GB = 1024^3 bytes)
        return storage_gb * 1024 * 1024 * 1024

    @staticmethod
    def get_usage(tenant) -> dict:
        """
        Get current storage usage for a tenant.

        Args:
            tenant: Tenant instance

        Returns:
            dict: {
                'bytes_used': int,
                'bytes_total': int,
                'file_count': int,
                'percent_used': float
            }
        """
        from .models import TenantStorageUsage

        # Get or create usage record
        usage, _ = TenantStorageUsage.objects.get_or_create(tenant=tenant)
        quota = StorageQuotaService.get_quota_bytes(tenant)

        percent_used = (usage.bytes_used / quota * 100) if quota > 0 else 0

        return {
            'bytes_used': usage.bytes_used,
            'bytes_total': quota,
            'file_count': usage.file_count,
            'percent_used': round(percent_used, 2)
        }

    @staticmethod
    def can_upload(tenant, file_size: int) -> Tuple[bool, str]:
        """
        Check if tenant can upload a file of given size.

        Args:
            tenant: Tenant instance
            file_size: Size of file to upload in bytes

        Returns:
            Tuple of (bool, str): (can_upload, error_message)
        """
        usage = StorageQuotaService.get_usage(tenant)

        if usage['bytes_used'] + file_size > usage['bytes_total']:
            remaining = usage['bytes_total'] - usage['bytes_used']
            remaining_mb = remaining / (1024 * 1024)
            file_mb = file_size / (1024 * 1024)
            return False, (
                f'Storage quota exceeded. You have {remaining_mb:.1f} MB remaining '
                f'but the file is {file_mb:.1f} MB. Please delete some files or upgrade your plan.'
            )

        return True, ''

    @staticmethod
    def update_usage(tenant, bytes_delta: int, count_delta: int = 0):
        """
        Update storage usage after upload or delete.

        Args:
            tenant: Tenant instance
            bytes_delta: Change in bytes (positive for upload, negative for delete)
            count_delta: Change in file count (typically +1 or -1)
        """
        from .models import TenantStorageUsage

        usage, _ = TenantStorageUsage.objects.get_or_create(tenant=tenant)

        if bytes_delta > 0:
            usage.add_file(bytes_delta)
        elif bytes_delta < 0:
            usage.remove_file(abs(bytes_delta))
        elif count_delta != 0:
            # Edge case: only count changed (shouldn't happen normally)
            from django.db.models import F
            TenantStorageUsage.objects.filter(pk=usage.pk).update(
                file_count=F('file_count') + count_delta
            )

    @staticmethod
    def recalculate_usage(tenant):
        """
        Recalculate storage usage from actual files.

        Use this if usage tracking gets out of sync.

        Args:
            tenant: Tenant instance

        Returns:
            dict: Updated usage stats
        """
        from django.db import connection
        from smoothschedule.scheduling.schedule.models import MediaFile
        from .models import TenantStorageUsage

        # Switch to tenant schema to query files
        with connection.cursor() as cursor:
            cursor.execute(f"SET search_path TO {tenant.schema_name}")

        # Calculate actual usage from MediaFile table
        from django.db.models import Sum, Count
        stats = MediaFile.objects.aggregate(
            total_bytes=Sum('file_size'),
            total_files=Count('id')
        )

        bytes_used = stats['total_bytes'] or 0
        file_count = stats['total_files'] or 0

        # Update the usage record
        usage, _ = TenantStorageUsage.objects.get_or_create(tenant=tenant)
        usage.bytes_used = bytes_used
        usage.file_count = file_count
        usage.save()

        return StorageQuotaService.get_usage(tenant)
