"""
Service de gestion des cartes physiques NFC
"""
from sqlalchemy.orm import Session
from models.models import Card, User, Transaction, Wallet
from schemas.card import CardCreate, CardUpdate, CardResponse, CardRechargeRequest
from services.commission_service import CommissionService
import uuid
from datetime import datetime

class CardService:
    @staticmethod
    def create_card(db: Session, user_id: str, phone: str) -> Card:
        """Créer une nouvelle carte physique"""
        # Vérifier que l'utilisateur existe
        user = db.query(User).filter(User.id == user_id).first()
        if not user:
            raise ValueError("Utilisateur non trouvé")

        # Vérifier que le numéro de téléphone n'est pas déjà utilisé
        existing_card = db.query(Card).filter(Card.phone == phone).first()
        if existing_card:
            raise ValueError("Cette carte est déjà liée à un autre utilisateur")
        
        # Générer un ID unique à 8 chiffres
        card_id = Card.generate_card_id()
        while db.query(Card).filter(Card.id == card_id).first():
            card_id = Card.generate_card_id()
        
        # Créer la carte
        card = Card(
            id=card_id,
            phone=phone,
            user_id=user_id,
            status="active"
        )
        
        db.add(card)
        db.commit()
        db.refresh(card)
        
        return card
    
    @staticmethod
    def get_user_cards(db: Session, user_id: str) -> list[Card]:
        """Récupérer toutes les cartes d'un utilisateur"""
        return db.query(Card).filter(Card.user_id == user_id).all()
    
    @staticmethod
    def get_card_by_id(db: Session, card_id: str) -> Card:
        """Récupérer une carte par son ID"""
        return db.query(Card).filter(Card.id == card_id).first()
    
    @staticmethod
    def get_card_by_uid(db: Session, uid: str) -> Card:
        """Récupérer une carte par son UID NFC"""
        return db.query(Card).filter(Card.uid == uid).first()
    
    @staticmethod
    def get_card_by_phone(db: Session, phone: str) -> Card:
        """Récupérer une carte par le numéro de téléphone de l'utilisateur"""
        user = db.query(User).filter(User.phone == phone).first()
        if not user:
            return None
        
        # Retourner la première carte active de l'utilisateur
        return db.query(Card).filter(
            Card.user_id == user.id,
            Card.status == "active"
        ).first()
    
    @staticmethod
    def update_card_status(db: Session, card_id: str, status: str, reason: str = None) -> Card:
        """Mettre à jour le statut d'une carte"""
        card = db.query(Card).filter(Card.id == card_id).first()
        if not card:
            raise ValueError("Carte non trouvée")
        
        card.status = status
        db.commit()
        db.refresh(card)
        
        return card
    
    @staticmethod
    def block_card(db: Session, card_id: str, reason: str = "Perte ou vol") -> Card:
        """Bloquer une carte (perte/vol)"""
        return CardService.update_card_status(db, card_id, "blocked", reason)
    
    @staticmethod
    def unblock_card(db: Session, card_id: str) -> Card:
        """Débloquer une carte"""
        return CardService.update_card_status(db, card_id, "active")
    
    @staticmethod
    def recharge_card_by_phone(db: Session, phone: str, amount: float, business_user_id: str) -> dict:
        """Recharger une carte via le numéro de téléphone (pour Tim Business)"""
        # Vérifier que l'utilisateur business existe
        business_user = db.query(User).filter(User.id == business_user_id).first()
        if not business_user:
            raise ValueError("Utilisateur business non trouvé")
        
        # Vérifier que c'est un Tim Business
        if business_user.tim_account_type != "TIM_BUSINESS":
            raise ValueError("Seuls les utilisateurs Tim Business peuvent recharger les cartes")
        
        # Trouver la carte de l'utilisateur
        card = CardService.get_card_by_phone(db, phone)
        if not card:
            raise ValueError("Aucune carte trouvée pour ce numéro de téléphone")
        
        if card.status != "active":
            raise ValueError("Cette carte est bloquée ou inactive")
        
        # Récupérer le wallet de l'utilisateur
        user = db.query(User).filter(User.phone == phone).first()
        wallet = db.query(Wallet).filter(Wallet.user_id == user.id).first()
        
        if not wallet:
            raise ValueError("Portefeuille utilisateur non trouvé")
        
        # Calculer les commissions
        commission_rates = CommissionService.get_recharge_commission_rates(db)
        total_commission, cinetpay_commission, timcash_commission = CommissionService.calculate_commissions(
            amount, 
            commission_rates['total_commission_rate'],
            commission_rates['cinetpay_commission_rate'],
            commission_rates['timcash_commission_rate']
        )
        
        # Créer la transaction
        transaction = Transaction(
            id=str(uuid.uuid4()),
            user_id=user.id,
            amount=amount,
            transaction_type="CARD_RECHARGE",
            status="completed",
            description=f"Recharge carte {card.id} par Tim Business",
            total_commission=total_commission,
            cinetpay_commission=cinetpay_commission,
            timcash_commission=timcash_commission
        )
        
        # Mettre à jour le solde du wallet
        wallet.balance += amount
        
        # Mettre à jour le stock admin avec la commission TimCash
        from models.models import AdminStock
        admin_stock = db.query(AdminStock).first()
        if admin_stock:
            admin_stock.balance += timcash_commission
            admin_stock.total_commissions += timcash_commission
        
        db.add(transaction)
        db.commit()
        db.refresh(transaction)
        
        return {
            "success": True,
            "transaction_id": transaction.id,
            "card_id": card.id,
            "amount": amount,
            "new_balance": wallet.balance,
            "commission": {
                "total": total_commission,
                "cinetpay": cinetpay_commission,
                "timcash": timcash_commission
            }
        }
    
    @staticmethod
    def get_all_cards(db: Session, skip: int = 0, limit: int = 100) -> list[Card]:
        """Récupérer toutes les cartes (pour l'admin)"""
        return db.query(Card).offset(skip).limit(limit).all()
    
    @staticmethod
    def search_cards(db: Session, query: str) -> list[Card]:
        """Rechercher des cartes par ID, UID ou numéro de téléphone"""
        # Recherche par ID de carte
        cards_by_id = db.query(Card).filter(Card.id.like(f"%{query}%")).all()
        
        # Recherche par UID
        cards_by_uid = db.query(Card).filter(Card.uid.like(f"%{query}%")).all()
        
        # Recherche par numéro de téléphone
        user = db.query(User).filter(User.phone.like(f"%{query}%")).first()
        cards_by_phone = []
        if user:
            cards_by_phone = db.query(Card).filter(Card.user_id == user.id).all()
        
        # Combiner et dédupliquer
        all_cards = list(set(cards_by_id + cards_by_uid + cards_by_phone))
        return all_cards
