from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select, and_
from app.models.social import ServiceProvider, Vote, ModerationStatus, Competition, UserScore
from app.models.user import User
from datetime import datetime
from app.services.gamification_service import GamificationService
from app.schemas.social import ServiceProviderCreate

async def create_service_provider(db: AsyncSession, obj_in: ServiceProviderCreate, user_id: int):
    new_provider = ServiceProvider(**obj_in.dict(), added_by_user_id=user_id)
    db.add(new_provider)
    await db.flush() 
    await GamificationService.award_points(db, user_id, 50, f"Új szolgáltató: {new_provider.name}")
    await db.commit()
    await db.refresh(new_provider)
    return new_provider

async def vote_for_provider(db: AsyncSession, voter_id: int, provider_id: int, vote_value: int):
    res = await db.execute(select(Vote).where(and_(Vote.user_id == voter_id, Vote.provider_id == provider_id)))
    if res.scalars().first(): return {"message": "User already voted"}
    new_vote = Vote(user_id=voter_id, provider_id=provider_id, vote_value=vote_value)
    db.add(new_vote)
    p_res = await db.execute(select(ServiceProvider).where(ServiceProvider.id == provider_id))
    provider = p_res.scalars().first()
    if not provider: return {"error": "Provider not found"}
    provider.validation_score += vote_value
    if provider.status == ModerationStatus.pending:
        if provider.validation_score >= 5:
            provider.status = ModerationStatus.approved
            await _reward_submitter(db, provider.added_by_user_id, provider.name)
        elif provider.validation_score <= -3:
            provider.status = ModerationStatus.rejected
            await _penalize_user(db, provider.added_by_user_id, provider.name)
    await db.commit()
    return {"message": "Vote cast", "new_score": provider.validation_score, "status": provider.status}

async def get_leaderboard(db: AsyncSession, limit: int = 10):
    return await GamificationService.get_top_users(db, limit)

async def _reward_submitter(db: AsyncSession, user_id: int, provider_name: str):
    if not user_id: return
    await GamificationService.award_points(db, user_id, 100, f"Validált szolgáltató: {provider_name}")
    u_res = await db.execute(select(User).where(User.id == user_id))
    user = u_res.scalars().first()
    if user: user.reputation_score = (user.reputation_score or 0) + 1
    now = datetime.utcnow()
    c_res = await db.execute(select(Competition).where(and_(Competition.is_active == True, Competition.start_date <= now, Competition.end_date >= now)))
    comp = c_res.scalars().first()
    if comp:
        s_res = await db.execute(select(UserScore).where(and_(UserScore.user_id == user_id, UserScore.competition_id == comp.id)))
        us = s_res.scalars().first()
        if not us:
            us = UserScore(user_id=user_id, competition_id=comp.id, points=0)
            db.add(us)
        us.points += 10

async def _penalize_user(db: AsyncSession, user_id: int, provider_name: str):
    if not user_id: return
    await GamificationService.award_points(db, user_id, -50, f"Elutasított szolgáltató: {provider_name}")
    u_res = await db.execute(select(User).where(User.id == user_id))
    user = u_res.scalars().first()
    if user:
        user.reputation_score = (user.reputation_score or 0) - 2
        if user.reputation_score <= -10: user.is_active = False