"""
Deck management router endpoints for per-user deck building.

Provides CRUD operations for user decks with card management,
deck finalization, precedent templates, and card search integration.
"""
from fastapi import APIRouter, Depends, HTTPException, Query, status
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select, func, or_, update, delete
from typing import Optional, List

from app.core.database import get_db, mtg_get_db
from app.core.security import get_current_user
from app.models.models import User, DecklistFolder, MtgonlineCard
from app.models.mtg_models import MtgCard, MtgSet
from app.models.user_deck import UserDeck, UserDeckCard, DeckPrecedent, DeckPrecedentCard, CardSuggestion
from app.schemas.user_deck_schemas import (
    UserDeckCreate, UserDeckUpdate, UserDeckResponse, UserDeckListResponse,
    DeckCardCreate, DeckCardUpdate, DeckCardResponse, DeckCardWithDetailsResponse, DeckCardListResponse,
    PrecedentCreate, PrecedentUpdate, PrecedentResponse, PrecedentListResponse,
    SuggestionCreate, SuggestionResponse, SuggestionListResponse,
    DeckFinalizeRequest, DeckFinalizeResponse,
    CardSearchRequest,
)
from app.schemas.card_search_schemas import CardSearchResponse
from app.schemas.generic_schemas import MessageResponse, CountResponse
from app.services.deck_manager import DeckManager
from app.services.deck_parser import DeckParser

router = APIRouter()

_deck_mgr = DeckManager()
_deck_parser = DeckParser()


# ===== Deck CRUD =====

@router.get("/", response_model=UserDeckListResponse)
async def list_user_decks(
    status_filter: Optional[str] = None,
    folder_id: Optional[int] = None,
    is_precedent: Optional[bool] = None,
    page: int = Query(1, ge=1),
    page_size: int = Query(50, ge=1, le=100),
    db: AsyncSession = Depends(get_db),
    current_user: dict = Depends(get_current_user),
):
    """List user's decks with optional filtering."""
    user_id = int(current_user["user_id"])
    try:
        decks = await _deck_mgr.list_decks(
            db=db,
            user_id=user_id,
            status_filter=status_filter,
            folder_id=folder_id,
            is_precedent=is_precedent,
            page=page,
            page_size=page_size,
        )

        # Build response with card counts
        deck_ids = [d.id for d in decks]
        card_counts = {}
        if deck_ids:
            count_subquery = (
                select(UserDeckCard.deck_id, func.count().label('cnt'))
                .where(UserDeckCard.deck_id.in_(deck_ids))
                .group_by(UserDeckCard.deck_id)
                .subquery()
            )
            count_stmt = select(count_subquery.c.deck_id, count_subquery.c.cnt).where(
                count_subquery.c.deck_id.in_(deck_ids)
            )
            count_result = await db.execute(count_stmt)
            card_counts = {row[0]: row[1] for row in count_result.fetchall()}

        deck_responses = []
        for deck in decks:
            deck_data = UserDeckResponse.model_validate(deck)
            deck_data.card_count = card_counts.get(deck.id, 0)
            deck_data.is_owner = True
            deck_responses.append(deck_data)

        total = len(decks)
        return UserDeckListResponse(
            decks=deck_responses,
            total=total,
            page=page,
            page_size=page_size,
            total_pages=(total + page_size - 1) // page_size,
        )
    except ValueError as e:
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))


@router.post("/", response_model=UserDeckResponse, status_code=status.HTTP_201_CREATED)
async def create_user_deck(
    request: UserDeckCreate,
    db: AsyncSession = Depends(get_db),
    current_user: dict = Depends(get_current_user),
):
    """Create a new user deck (DRAFT status)."""
    user_id = int(current_user["user_id"])
    try:
        new_deck = await _deck_mgr.create_deck(
            db=db,
            user_id=user_id,
            name=request.name,
            folder_id=request.folder_id,
            format=request.format,
            notes=request.notes,
            is_precedent=request.is_precedent,
            precedent_name=request.precedent_name,
        )
        deck_data = UserDeckResponse.model_validate(new_deck)
        deck_data.card_count = 0
        deck_data.is_owner = True
        return deck_data
    except HTTPException:
        raise
    except ValueError as e:
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))
    except Exception as e:
        raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e))


@router.get("/{deck_id}", response_model=UserDeckResponse)
async def get_user_deck(
    deck_id: int,
    db: AsyncSession = Depends(get_db),
    current_user: dict = Depends(get_current_user),
):
    """Get a specific user deck."""
    user_id = int(current_user["user_id"])
    try:
        deck = await _deck_mgr.get_deck(db=db, deck_id=deck_id, user_id=user_id)
        if not deck:
            raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Deck not found")

        # Get card count
        count_stmt = select(func.count()).select_from(UserDeckCard).where(UserDeckCard.deck_id == deck_id)
        count_result = await db.execute(count_stmt)
        card_count = count_result.scalar() or 0

        deck_data = UserDeckResponse.model_validate(deck)
        deck_data.card_count = card_count
        deck_data.is_owner = True
        return deck_data
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e))


@router.patch("/{deck_id}", response_model=UserDeckResponse)
async def update_user_deck(
    deck_id: int,
    request: UserDeckUpdate,
    db: AsyncSession = Depends(get_db),
    current_user: dict = Depends(get_current_user),
):
    """Update a user deck."""
    user_id = int(current_user["user_id"])
    try:
        update_data = request.model_dump(exclude_unset=True)
        if "status" in update_data and update_data["status"]:
            update_data["status"] = update_data["status"].value

        updated_deck = await _deck_mgr.update_deck(
            db=db,
            deck_id=deck_id,
            user_id=user_id,
            **update_data,
        )

        if not updated_deck:
            raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Deck not found")

        # Get card count
        count_stmt = select(func.count()).select_from(UserDeckCard).where(UserDeckCard.deck_id == deck_id)
        count_result = await db.execute(count_stmt)
        card_count = count_result.scalar() or 0

        deck_data = UserDeckResponse.model_validate(updated_deck)
        deck_data.card_count = card_count
        deck_data.is_owner = True
        return deck_data
    except HTTPException:
        raise
    except ValueError as e:
        if "not found" in str(e).lower():
            raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))


@router.delete("/{deck_id}", response_model=MessageResponse)
async def delete_user_deck(
    deck_id: int,
    db: AsyncSession = Depends(get_db),
    current_user: dict = Depends(get_current_user),
):
    """Delete a user deck."""
    user_id = int(current_user["user_id"])
    try:
        result = await _deck_mgr.delete_deck(db=db, deck_id=deck_id, user_id=user_id)
        if not result:
            raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Deck not found")
        return MessageResponse(message="Deck deleted successfully")
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e))


# ===== Deck Finalize =====

@router.post("/{deck_id}/finalize", response_model=DeckFinalizeResponse)
async def finalize_user_deck(
    deck_id: int,
    db: AsyncSession = Depends(get_db),
    current_user: dict = Depends(get_current_user),
):
    """Transition a deck from DRAFT to FINAL status."""
    user_id = int(current_user["user_id"])
    try:
        deck = await _deck_mgr.finalize_deck(db=db, deck_id=deck_id, user_id=user_id)
        if not deck:
            raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Deck not found")
        return DeckFinalizeResponse(
            deck_id=deck_id,
            status="FINAL",
            message="Deck finalized successfully",
        )
    except HTTPException:
        raise
    except ValueError as e:
        if "not found" in str(e).lower():
            raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))


# ===== Deck Card Management =====

@router.post("/{deck_id}/cards", response_model=DeckCardResponse, status_code=status.HTTP_201_CREATED)
async def add_deck_card(
    deck_id: int,
    request: DeckCardCreate,
    db: AsyncSession = Depends(get_db),
    current_user: dict = Depends(get_current_user),
):
    """Add a card to a user's deck."""
    user_id = int(current_user["user_id"])

    # Verify deck exists and belongs to user
    deck_stmt = select(UserDeck).where(UserDeck.id == deck_id, UserDeck.user_id == user_id)
    deck_result = await db.execute(deck_stmt)
    deck = deck_result.scalar_one_or_none()
    if not deck:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Deck not found")

    if deck.status == "FINAL":
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="Cannot modify a finalized deck")

    # Verify card exists in local mirror
    card_stmt = select(MtgonlineCard).where(MtgonlineCard.id == request.card_id)
    card_result = await db.execute(card_stmt)
    card = card_result.scalar_one_or_none()
    if not card:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Card not found in database")

    # Check for duplicate (same card, same zone)
    existing_stmt = select(UserDeckCard).where(
        UserDeckCard.deck_id == deck_id,
        UserDeckCard.card_id == request.card_id,
        UserDeckCard.zone == request.zone.value,
    )
    existing_result = await db.execute(existing_stmt)
    existing = existing_result.scalar_one_or_none()

    if existing:
        # Update quantity
        new_qty = existing.quantity + request.quantity
        stmt = update(UserDeckCard).where(UserDeckCard.id == existing.id).values(quantity=new_qty)
        await db.execute(stmt)
        await db.flush()

        stmt = select(UserDeckCard).where(UserDeckCard.id == existing.id)
        result = await db.execute(stmt)
        updated = result.scalar_one_or_none()
    else:
        new_card = UserDeckCard(
            deck_id=deck_id,
            card_id=request.card_id,
            quantity=request.quantity,
            zone=request.zone.value,
            position=request.position,
        )
        db.add(new_card)
        await db.flush()
        updated = new_card

    return DeckCardResponse.model_validate(updated)


@router.get("/{deck_id}/cards", response_model=DeckCardListResponse)
async def get_deck_cards(
    deck_id: int,
    zone: Optional[str] = None,
    db: AsyncSession = Depends(get_db),
    current_user: dict = Depends(get_current_user),
):
    """Get all cards in a user's deck."""
    user_id = int(current_user["user_id"])

    # Verify deck exists and belongs to user
    stmt = select(UserDeck).where(UserDeck.id == deck_id, UserDeck.user_id == user_id)
    result = await db.execute(stmt)
    deck = result.scalar_one_or_none()

    if not deck:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Deck not found")

    # Use service to get cards
    deck_cards = await _deck_mgr.get_deck_cards(db=db, deck_id=deck_id, zone=zone)

    # Fetch card details from local mirror
    card_ids = [dc.card_id for dc in deck_cards]
    card_details = {}
    if card_ids:
        card_stmt = select(MtgonlineCard).where(MtgonlineCard.id.in_(card_ids))
        card_result = await db.execute(card_stmt)
        for c in card_result.scalars().all():
            card_details[c.id] = c

    card_responses = []
    for dc in deck_cards:
        card = card_details.get(dc.card_id)
        response = DeckCardWithDetailsResponse.model_validate(dc)
        response.card_name = card.name if card else f"Card#{dc.card_id}"
        response.card_type_line = card.type_line if card else ""
        response.card_image = card.image if card else None
        card_responses.append(response)

    return DeckCardListResponse(cards=card_responses, total=len(card_responses))


@router.patch("/{deck_id}/cards/{card_id}", response_model=DeckCardResponse)
async def update_deck_card(
    deck_id: int,
    card_id: int,
    request: DeckCardUpdate,
    db: AsyncSession = Depends(get_db),
    current_user: dict = Depends(get_current_user),
):
    """Update a card's quantity or zone in a deck."""
    user_id = int(current_user["user_id"])

    # Verify deck exists and belongs to user
    stmt = select(UserDeck).where(UserDeck.id == deck_id, UserDeck.user_id == user_id)
    result = await db.execute(stmt)
    deck = result.scalar_one_or_none()

    if not deck:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Deck not found")

    if deck.status == "FINAL":
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="Cannot modify a finalized deck")

    # Find the card entry
    stmt = select(UserDeckCard).where(
        UserDeckCard.deck_id == deck_id,
        UserDeckCard.card_id == card_id,
    )
    result = await db.execute(stmt)
    deck_card = result.scalar_one_or_none()

    if not deck_card:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Card not found in deck")

    update_data = request.model_dump(exclude_unset=True)
    if "zone" in update_data and update_data["zone"]:
        update_data["zone"] = update_data["zone"].value

    stmt = update(UserDeckCard).where(UserDeckCard.id == deck_card.id).values(**update_data)
    await db.execute(stmt)
    await db.flush()

    stmt = select(UserDeckCard).where(UserDeckCard.id == deck_card.id)
    result = await db.execute(stmt)
    updated = result.scalar_one_or_none()

    return DeckCardResponse.model_validate(updated)


@router.delete("/{deck_id}/cards/{card_id}", response_model=MessageResponse)
async def remove_deck_card(
    deck_id: int,
    card_id: int,
    db: AsyncSession = Depends(get_db),
    current_user: dict = Depends(get_current_user),
):
    """Remove a card from a user's deck."""
    user_id = int(current_user["user_id"])

    # Verify deck exists and belongs to user
    stmt = select(UserDeck).where(UserDeck.id == deck_id, UserDeck.user_id == user_id)
    result = await db.execute(stmt)
    deck = result.scalar_one_or_none()

    if not deck:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Deck not found")

    if deck.status == "FINAL":
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="Cannot modify a finalized deck")

    # Find the card entry
    stmt = select(UserDeckCard).where(
        UserDeckCard.deck_id == deck_id,
        UserDeckCard.card_id == card_id,
    )
    result = await db.execute(stmt)
    deck_card = result.scalar_one_or_none()

    if not deck_card:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Card not found in deck")

    await db.execute(delete(UserDeckCard).where(UserDeckCard.id == deck_card.id))
    await db.flush()

    return MessageResponse(message="Card removed from deck")


# ===== Deck Precedents =====
# Note: Precedent endpoints use direct DB operations as DeckManager
# does not yet have precedent-specific methods.

@router.get("/precedents", response_model=PrecedentListResponse)
async def list_precedents(
    page: int = Query(1, ge=1),
    page_size: int = Query(50, ge=1, le=100),
    format_filter: Optional[str] = None,
    db: AsyncSession = Depends(get_db),
    current_user: dict = Depends(get_current_user),
):
    """List available deck precedents."""
    offset = (page - 1) * page_size

    conditions = [DeckPrecedent.is_public == True]
    if format_filter:
        conditions.append(DeckPrecedent.format == format_filter)

    # Count total
    count_stmt = select(func.count()).select_from(DeckPrecedent).where(*conditions)
    total_result = await db.execute(count_stmt)
    total = total_result.scalar() or 0

    # Fetch precedents
    stmt = select(DeckPrecedent).where(*conditions).order_by(DeckPrecedent.created_at.desc()).offset(offset).limit(page_size)
    result = await db.execute(stmt)
    precedents = result.scalars().all()

    # Get card counts
    prec_ids = [p.id for p in precedents]
    card_counts = {}
    if prec_ids:
        count_subquery = (
            select(DeckPrecedentCard.precedent_id, func.count().label('cnt'))
            .where(DeckPrecedentCard.precedent_id.in_(prec_ids))
            .group_by(DeckPrecedentCard.precedent_id)
            .subquery()
        )
        count_stmt = select(count_subquery.c.precedent_id, count_subquery.c.cnt).where(
            count_subquery.c.precedent_id.in_(prec_ids)
        )
        count_result = await db.execute(count_stmt)
        card_counts = {row[0]: row[1] for row in count_result.fetchall()}

    prec_responses = []
    for p in precedents:
        prec_data = PrecedentResponse.model_validate(p)
        prec_data.card_count = card_counts.get(p.id, 0)
        prec_responses.append(prec_data)

    return PrecedentListResponse(
        precedents=prec_responses,
        total=total,
        page=page,
        page_size=page_size,
        total_pages=(total + page_size - 1) // page_size,
    )


@router.post("/precedents", response_model=PrecedentResponse, status_code=status.HTTP_201_CREATED)
async def create_precedent(
    request: PrecedentCreate,
    db: AsyncSession = Depends(get_db),
    current_user: dict = Depends(get_current_user),
):
    """Create a deck precedent (template)."""
    user_id = int(current_user["user_id"])

    new_precedent = DeckPrecedent(
        name=request.name,
        description=request.description,
        format=request.format,
        is_public=request.is_public,
        created_by=user_id,
    )
    db.add(new_precedent)
    await db.flush()

    prec_data = PrecedentResponse.model_validate(new_precedent)
    prec_data.card_count = 0
    return prec_data


@router.get("/precedents/{precedent_id}", response_model=PrecedentResponse)
async def get_precedent(
    precedent_id: int,
    db: AsyncSession = Depends(get_db),
    current_user: dict = Depends(get_current_user),
):
    """Get a specific deck precedent."""
    stmt = select(DeckPrecedent).where(DeckPrecedent.id == precedent_id)
    result = await db.execute(stmt)
    precedent = result.scalar_one_or_none()

    if not precedent:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Precedent not found")

    # Get card count
    count_stmt = select(func.count()).select_from(DeckPrecedentCard).where(DeckPrecedentCard.precedent_id == precedent_id)
    count_result = await db.execute(count_stmt)
    card_count = count_result.scalar() or 0

    prec_data = PrecedentResponse.model_validate(precedent)
    prec_data.card_count = card_count
    return prec_data


@router.post("/precedents/{precedent_id}/use")
async def use_precedent(
    precedent_id: int,
    db: AsyncSession = Depends(get_db),
    current_user: dict = Depends(get_current_user),
):
    """Clone a precedent into a new draft deck for the current user."""
    user_id = int(current_user["user_id"])

    try:
        new_deck = await _deck_mgr.clone_precedent(
            db=db,
            precedent_id=precedent_id,
            user_id=user_id,
        )
        return {
            "message": "Precedent cloned into new deck",
            "deck_id": new_deck.id,
            "deck_name": new_deck.name,
            "card_count": len(await _deck_mgr.get_deck_cards(db=db, deck_id=new_deck.id)),
        }
    except ValueError as e:
        if "not found" in str(e).lower():
            raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))


# ===== Card Search Integration =====

@router.post("/search/cards", response_model=CardSearchResponse)
async def search_cards_for_deck(
    request: CardSearchRequest,
    db: AsyncSession = Depends(get_db),
    current_user: dict = Depends(get_current_user),
):
    """Search MTG cards for use in deck building."""
    offset = (request.offset // request.limit) * request.limit

    # Search across multiple fields using local mirror
    stmt = (
        select(MtgonlineCard)
        .where(
            or_(
                MtgonlineCard.name.ilike(f"%{request.query}%"),
                MtgonlineCard.type_line.ilike(f"%{request.query}%"),
                MtgonlineCard.mana_cost.ilike(f"%{request.query}%"),
            )
        )
        .offset(offset)
        .limit(request.limit)
    )

    result = await db.execute(stmt)
    cards = result.scalars().all()

    card_list = []
    for card in cards:
        card_data = {
            "id": card.id,
            "name": card.name,
            "mana_cost": card.mana_cost,
            "type_line": card.type_line,
            "oracle_text": card.oracle_text,
            "power": card.power,
            "toughness": card.toughness,
            "rarity": card.rarity,
            "layout": card.layout,
            "artist": card.artist,
            "flavor_text": card.flavor_text,
            "set_code": card.set_code,
            "set_name": card.set_name,
            "identifiers": card.identifiers,
            "images": card.images,
        }
        card_list.append(card_data)

    # Get total count
    count_stmt = select(func.count()).select_from(MtgonlineCard).where(
        or_(
            MtgonlineCard.name.ilike(f"%{request.query}%"),
            MtgonlineCard.type_line.ilike(f"%{request.query}%"),
            MtgonlineCard.mana_cost.ilike(f"%{request.query}%"),
        )
    )
    total_result = await db.execute(count_stmt)
    total = total_result.scalar() or 0

    return CardSearchResponse(
        cards=card_list,
        total=total,
        page=request.offset // request.limit + 1,
        page_size=request.limit,
        total_pages=(total + request.limit - 1) // request.limit,
    )


# ===== Card Suggestions =====
# Note: Suggestion endpoints use direct DB operations as DeckManager
# does not yet have suggestion-specific methods.

@router.get("/{deck_id}/suggestions", response_model=SuggestionListResponse)
async def get_deck_suggestions(
    deck_id: int,
    suggestion_type: Optional[str] = None,
    db: AsyncSession = Depends(get_db),
    current_user: dict = Depends(get_current_user),
):
    """Get card suggestions for a deck."""
    user_id = int(current_user["user_id"])

    # Verify deck exists and belongs to user
    stmt = select(UserDeck).where(UserDeck.id == deck_id, UserDeck.user_id == user_id)
    result = await db.execute(stmt)
    deck = result.scalar_one_or_none()

    if not deck:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Deck not found")

    conditions = [CardSuggestion.deck_id == deck_id]
    if suggestion_type:
        conditions.append(CardSuggestion.suggestion_type == suggestion_type)

    # Fetch suggestions
    stmt = select(CardSuggestion).where(*conditions).order_by(CardSuggestion.created_at.desc())
    result = await db.execute(stmt)
    suggestions = result.scalars().all()

    # Fetch card names from local mirror
    card_ids = [s.card_id for s in suggestions]
    card_names = {}
    if card_ids:
        card_stmt = select(MtgonlineCard).where(MtgonlineCard.id.in_(card_ids))
        card_result = await db.execute(card_stmt)
        for c in card_result.scalars().all():
            card_names[c.id] = c.name

    sugg_responses = []
    for s in suggestions:
        sugg_data = SuggestionResponse.model_validate(s)
        sugg_data.card_name = card_names.get(s.card_id, f"Card#{s.card_id}")
        sugg_responses.append(sugg_data)

    return SuggestionListResponse(
        suggestions=sugg_responses,
        total=len(sugg_responses),
    )


@router.post("/{deck_id}/suggestions", response_model=SuggestionResponse, status_code=status.HTTP_201_CREATED)
async def add_suggestion(
    deck_id: int,
    request: SuggestionCreate,
    db: AsyncSession = Depends(get_db),
    current_user: dict = Depends(get_current_user),
):
    """Add a card suggestion to a deck."""
    user_id = int(current_user["user_id"])

    # Verify deck exists and belongs to user
    stmt = select(UserDeck).where(UserDeck.id == deck_id, UserDeck.user_id == user_id)
    result = await db.execute(stmt)
    deck = result.scalar_one_or_none()

    if not deck:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Deck not found")

    if deck.status == "FINAL":
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="Cannot modify a finalized deck")

    new_suggestion = CardSuggestion(
        deck_id=deck_id,
        card_id=request.card_id,
        source_card_id=request.source_card_id,
        suggestion_type=request.suggestion_type.value,
        confidence=request.confidence,
        notes=request.notes,
    )
    db.add(new_suggestion)
    await db.flush()

    return SuggestionResponse.model_validate(new_suggestion)
