import logging
from datetime import datetime
from typing import Optional
from sqlalchemy import select, delete
from sqlalchemy.ext.asyncio import AsyncSession
from app.database.models import Subscription, User

logger = logging.getLogger(__name__)


async def ensure_single_subscription(db: AsyncSession, user_id: int) -> Optional[Subscription]:
    result = await db.execute(
        select(Subscription)
        .where(Subscription.user_id == user_id)
        .order_by(Subscription.created_at.desc())
    )
    subscriptions = result.scalars().all()
    
    if len(subscriptions) <= 1:
        return subscriptions[0] if subscriptions else None
    
    latest_subscription = subscriptions[0]
    old_subscriptions = subscriptions[1:]
    
    logger.warning(f"🚨 Обнаружено {len(subscriptions)} подписок у пользователя {user_id}. Удаляем {len(old_subscriptions)} старых.")
    
    for old_sub in old_subscriptions:
        await db.delete(old_sub)
        logger.info(f"🗑️ Удалена подписка ID {old_sub.id} от {old_sub.created_at}")
    
    await db.commit()
    await db.refresh(latest_subscription)
    
    logger.info(f"✅ Оставлена подписка ID {latest_subscription.id} от {latest_subscription.created_at}")
    return latest_subscription


async def update_or_create_subscription(
    db: AsyncSession,
    user_id: int,
    **subscription_data
) -> Subscription:
    existing_subscription = await ensure_single_subscription(db, user_id)
    
    if existing_subscription:
        for key, value in subscription_data.items():
            if hasattr(existing_subscription, key):
                setattr(existing_subscription, key, value)
        
        existing_subscription.updated_at = datetime.utcnow()
        await db.commit()
        await db.refresh(existing_subscription)
        
        logger.info(f"🔄 Обновлена существующая подписка ID {existing_subscription.id}")
        return existing_subscription
    
    else:
        new_subscription = Subscription(
            user_id=user_id,
            **subscription_data
        )
        
        db.add(new_subscription)
        await db.commit()
        await db.refresh(new_subscription)
        
        logger.info(f"🆕 Создана новая подписка ID {new_subscription.id}")
        return new_subscription


async def cleanup_duplicate_subscriptions(db: AsyncSession) -> int:
    result = await db.execute(
        select(Subscription.user_id)
        .group_by(Subscription.user_id)
        .having(func.count(Subscription.id) > 1)
    )
    users_with_duplicates = result.scalars().all()
    
    total_deleted = 0
    
    for user_id in users_with_duplicates:
        subscriptions_result = await db.execute(
            select(Subscription)
            .where(Subscription.user_id == user_id)
            .order_by(Subscription.created_at.desc())
        )
        subscriptions = subscriptions_result.scalars().all()
        
        for old_subscription in subscriptions[1:]:
            await db.delete(old_subscription)
            total_deleted += 1
            logger.info(f"🗑️ Удалена дублирующаяся подписка ID {old_subscription.id} пользователя {user_id}")
    
    await db.commit()
    logger.info(f"🧹 Очищено {total_deleted} дублирующихся подписок")
    
    return total_deleted
