import { NextResponse } from 'next/server'; import { sql } from '@vercel/postgres'; import { verifyToken } from '../auth-utils.js'; // GET /api/collections - Get user collections export async function GET(request) { try { const token = request.headers.get('authorization')?.replace('Bearer ', ''); const user = await verifyToken(token); if (!user) { return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }); } const { searchParams } = new URL(request.url); const collectionId = searchParams.get('id'); if (collectionId) { // Get specific collection with cards const result = await sql.query(` SELECT c.id, c.name, c.description, c.is_public, c.created_at, c.updated_at, cc.quantity, cc.condition, cc.notes, cc.purchase_price, cc.purchase_date, card.id as card_id, card.name as card_name, card.set_name, card.set_code, card.card_number, card.rarity, card.game, card.card_type, card.mana_cost, card.cmc, card.colors, card.oracle_text, card.power, card.toughness, card.image_url, card.stock_image_url, card.current_price, card.market_price FROM user_collections c LEFT JOIN collection_cards cc ON c.id = cc.collection_id LEFT JOIN cards card ON cc.card_id = card.id WHERE c.id = $1 AND c.user_id = $2 ORDER BY card.name ASC `, [collectionId, user.id]); if (result.rows.length === 0) { return NextResponse.json({ error: 'Collection not found' }, { status: 404 }); } const collection = { id: result.rows[0].id, name: result.rows[0].name, description: result.rows[0].description, is_public: result.rows[0].is_public, created_at: result.rows[0].created_at, updated_at: result.rows[0].updated_at, cards: result.rows .filter(row => row.card_id) .map(row => ({ quantity: row.quantity, condition: row.condition, notes: row.notes, purchase_price: row.purchase_price, purchase_date: row.purchase_date, card: { id: row.card_id, name: row.card_name, set_name: row.set_name, set_code: row.set_code, card_number: row.card_number, rarity: row.rarity, game: row.game, card_type: row.card_type, mana_cost: row.mana_cost, cmc: row.cmc, colors: row.colors ? JSON.parse(row.colors) : [], oracle_text: row.oracle_text, power: row.power, toughness: row.toughness, image_url: row.image_url, stock_image_url: row.stock_image_url, current_price: row.current_price, market_price: row.market_price } })) }; return NextResponse.json({ success: true, data: collection }); } else { // Get all user collections const result = await sql.query(` SELECT c.id, c.name, c.description, c.is_public, c.created_at, c.updated_at, COUNT(cc.card_id) as card_count FROM user_collections c LEFT JOIN collection_cards cc ON c.id = cc.collection_id WHERE c.user_id = $1 GROUP BY c.id, c.name, c.description, c.is_public, c.created_at, c.updated_at ORDER BY c.created_at DESC `, [user.id]); return NextResponse.json({ success: true, data: result.rows.map(row => ({ id: row.id, name: row.name, description: row.description, is_public: row.is_public, created_at: row.created_at, updated_at: row.updated_at, card_count: parseInt(row.card_count) })) }); } } catch (error) { console.error('Error fetching collections:', error); return NextResponse.json( { error: 'Failed to fetch collections', details: error.message }, { status: 500 } ); } } // POST /api/collections - Create collection or add card to collection export async function POST(request) { try { const token = request.headers.get('authorization')?.replace('Bearer ', ''); const user = await verifyToken(token); if (!user) { return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }); } const { searchParams } = new URL(request.url); const action = searchParams.get('action'); if (action === 'create') { // Create new collection const { name, description, is_public } = await request.json(); if (!name) { return NextResponse.json({ error: 'Collection name is required' }, { status: 400 }); } const result = await sql.query(` INSERT INTO user_collections (user_id, name, description, is_public) VALUES ($1, $2, $3, $4) RETURNING * `, [user.id, name, description || '', is_public || false]); return NextResponse.json({ success: true, data: result.rows[0], message: 'Collection created successfully' }); } if (action === 'add-card') { // Add card to collection const { collection_id, card_id, quantity, condition, notes, purchase_price, purchase_date } = await request.json(); if (!collection_id || !card_id) { return NextResponse.json({ error: 'Collection ID and card ID are required' }, { status: 400 }); } // Verify collection belongs to user const collectionCheck = await sql.query(` SELECT id FROM user_collections WHERE id = $1 AND user_id = $2 `, [collection_id, user.id]); if (collectionCheck.rows.length === 0) { return NextResponse.json({ error: 'Collection not found or access denied' }, { status: 404 }); } // Check if card already exists in collection const existingCard = await sql.query(` SELECT id, quantity FROM collection_cards WHERE collection_id = $1 AND card_id = $2 `, [collection_id, card_id]); if (existingCard.rows.length > 0) { // Update existing card quantity const newQuantity = (existingCard.rows[0].quantity || 0) + (quantity || 1); await sql.query(` UPDATE collection_cards SET quantity = $1, updated_at = NOW() WHERE id = $2 `, [newQuantity, existingCard.rows[0].id]); return NextResponse.json({ success: true, message: 'Card quantity updated in collection' }); } else { // Add new card to collection await sql.query(` INSERT INTO collection_cards ( collection_id, card_id, quantity, condition, notes, purchase_price, purchase_date ) VALUES ($1, $2, $3, $4, $5, $6, $7) `, [ collection_id, card_id, quantity || 1, condition || 'near-mint', notes || '', purchase_price || null, purchase_date || null ]); return NextResponse.json({ success: true, message: 'Card added to collection' }); } } return NextResponse.json({ error: 'Invalid action' }, { status: 400 }); } catch (error) { console.error('Error with collections:', error); return NextResponse.json( { error: 'Failed to process collection action', details: error.message }, { status: 500 } ); } }