from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy import select from sqlalchemy.dialects.postgresql import insert from app.models.collection import CollectionCard from app.services.imports.models import RawCardRow from app.services import scryfall async def enrich_and_upsert(rows: list[RawCardRow], user_id: int, db: AsyncSession) -> int: # Try set+collector first for exact matches enriched = {} name_lookup = [] for row in rows: if row.set_code and row.collector_number: card = await scryfall.get_card_by_set_and_collector(row.set_code, row.collector_number) if card: enriched[row.card_name.lower()] = card continue name_lookup.append(row.card_name) # Batch enrich remaining by name if name_lookup: name_map = await scryfall.batch_enrich_by_name(name_lookup) enriched.update(name_map) count = 0 for row in rows: sf_data = enriched.get(row.card_name.lower()) if not sf_data: continue scryfall_id = sf_data["id"] # Upsert — add quantities if card already exists result = await db.execute( select(CollectionCard).where( CollectionCard.owner_id == user_id, CollectionCard.scryfall_id == scryfall_id, ) ) existing = result.scalar_one_or_none() if existing: existing.quantity += row.quantity existing.foil_quantity += row.foil_quantity existing.scryfall_data = sf_data else: db.add(CollectionCard( owner_id=user_id, card_name=sf_data.get("name", row.card_name), set_code=sf_data.get("set", row.set_code), collector_number=sf_data.get("collector_number", row.collector_number), quantity=row.quantity, foil_quantity=row.foil_quantity, scryfall_id=scryfall_id, scryfall_data=sf_data, )) count += 1 await db.commit() return count