"""Card synchronization service for atproto"""
from typing import List, Dict, Any, Optional
from datetime import datetime
from sqlalchemy.ext.asyncio import AsyncSession

# from app.services.atproto import AtprotoService, CardLexicon
from app.repositories.card import CardRepository
from app.repositories.user import UserRepository
from app.models.card import Card as CardModel
from app.db.models import UserCard
from app.core.config import settings


class CardSyncService:
    """Service for syncing cards between database and atproto PDS"""
    
    def __init__(self, session: AsyncSession, atproto_session: Optional[str] = None):
        self.db_session = session
        self.card_repo = CardRepository(session)
        self.user_repo = UserRepository(session)
        self.atproto_service = AtprotoService()
        
        # Restore atproto session if provided
        if atproto_session:
            self.atproto_service.restore_session(atproto_session)
    
    async def sync_card_to_pds(self, user_card: UserCard, user_did: str) -> Optional[str]:
        """
        Sync a single card to user's PDS
        
        Args:
            user_card: Card from database
            user_did: User's DID
            
        Returns:
            Record URI if successful
        """
        if not settings.atproto_handle or not settings.atproto_password:
            # Skip if atproto credentials not configured
            return None
        
        try:
            # Login if not already
            if not self.atproto_service.client:
                await self.atproto_service.login(
                    settings.atproto_handle,
                    settings.atproto_password
                )
            
            # Convert to API model
            card_model = CardModel(
                id=user_card.card_id,
                cp=user_card.cp,
                status=user_card.status,
                skill=user_card.skill,
                owner_did=user_did,
                obtained_at=user_card.obtained_at,
                is_unique=user_card.is_unique,
                unique_id=str(user_card.unique_id) if user_card.unique_id else None
            )
            
            # Create record in PDS
            uri = await self.atproto_service.create_card_record(
                did=user_did,
                card=card_model,
                collection=CardLexicon.LEXICON_ID
            )
            
            # Store URI in database for future reference
            # (You might want to add a field to UserCard model for this)
            
            return uri
            
        except Exception as e:
            print(f"Failed to sync card to PDS: {e}")
            return None
    
    async def sync_all_user_cards(self, user_id: int, user_did: str) -> int:
        """
        Sync all user's cards to PDS
        
        Args:
            user_id: Database user ID
            user_did: User's DID
            
        Returns:
            Number of cards synced
        """
        # Get all user cards from database
        user_cards = await self.card_repo.get_user_cards(user_id)
        
        synced_count = 0
        for card in user_cards:
            uri = await self.sync_card_to_pds(card, user_did)
            if uri:
                synced_count += 1
        
        return synced_count
    
    async def import_cards_from_pds(self, user_did: str) -> int:
        """
        Import cards from user's PDS to database
        
        Args:
            user_did: User's DID
            
        Returns:
            Number of cards imported
        """
        if not self.atproto_service.client:
            return 0
        
        # Get user from database
        user = await self.user_repo.get_by_did(user_did)
        if not user:
            return 0
        
        # Get cards from PDS
        pds_cards = await self.atproto_service.get_user_cards(
            did=user_did,
            collection=CardLexicon.LEXICON_ID
        )
        
        imported_count = 0
        for pds_card in pds_cards:
            # Check if card already exists
            existing_count = await self.card_repo.count_user_cards(
                user.id, 
                pds_card.get("cardId")
            )
            
            if existing_count == 0:
                # Import card
                await self.card_repo.create_user_card(
                    user_id=user.id,
                    card_id=pds_card.get("cardId"),
                    cp=pds_card.get("cp"),
                    status=pds_card.get("status"),
                    skill=pds_card.get("skill"),
                    is_unique=pds_card.get("isUnique", False)
                )
                imported_count += 1
        
        await self.db_session.commit()
        return imported_count
    
    async def verify_card_ownership(
        self, 
        user_did: str, 
        card_id: int,
        unique_id: Optional[str] = None
    ) -> bool:
        """
        Verify user owns a card by checking both database and PDS
        
        Args:
            user_did: User's DID
            card_id: Card type ID
            unique_id: Unique ID for unique cards
            
        Returns:
            True if user owns the card
        """
        # Check database first
        user = await self.user_repo.get_by_did(user_did)
        if user:
            user_cards = await self.card_repo.get_user_cards(user.id)
            for card in user_cards:
                if card.card_id == card_id:
                    if not unique_id or str(card.unique_id) == unique_id:
                        return True
        
        # Check PDS if configured
        if self.atproto_service.client:
            try:
                pds_cards = await self.atproto_service.get_user_cards(user_did)
                for card in pds_cards:
                    if card.get("cardId") == card_id:
                        if not unique_id or card.get("uniqueId") == unique_id:
                            return True
            except Exception:
                pass
        
        return False