import { sql } from '@vercel/postgres';
import { checkSearchRateLimit } from '../../../lib/rate-limit.js';

export default async function handler(req, res) {
  if (req.method !== 'GET') {
    return res.status(405).json({ error: 'Method not allowed' });
  }

  const { allowed, reset } = await checkSearchRateLimit(req);
  if (!allowed) {
    res.setHeader('Retry-After', Math.ceil((reset - Date.now()) / 1000));
    return res.status(429).json({ error: 'Too many attempts. Try again later.' });
  }

  try {
    const { 
      query = '', 
      game = 'all', 
      rarity = 'all', 
      set = 'all', 
      minPrice = '', 
      maxPrice = '', 
      page = '1', 
      limit = '50' 
    } = req.query;

    const pageNum = parseInt(page) || 1;
    const limitNum = parseInt(limit) || 50;
    const offset = (pageNum - 1) * limitNum;

    // Define the columns we want to select (only existing columns)
    // Note: removed flavor_text, hp, type, form, weakness, retreat_cost as they don't exist in the current schema

    // Normalize filters
    const filters = {
      hasQuery: query.trim() !== '',
      hasGame: game !== 'all',
      hasRarity: rarity !== 'all',
      hasSet: set !== 'all',
      hasMinPrice: minPrice && !isNaN(parseFloat(minPrice)),
      hasMaxPrice: maxPrice && !isNaN(parseFloat(maxPrice))
    };

    let result, countResult;

    // Handle different filter combinations using template literals
    if (!filters.hasQuery && !filters.hasGame && !filters.hasRarity && !filters.hasSet && !filters.hasMinPrice && !filters.hasMaxPrice) {
      // No filters - get all cards
      result = await sql`
        SELECT id, name, set_name, set_code, card_number, rarity, game,
          mana_cost, cmc, card_type, colors, oracle_text,
          power, toughness, image_url, stock_image_url,
          current_price, market_price, scryfall_id, verified,
          quantity
        FROM cards
        ORDER BY name ASC
        LIMIT ${limitNum} OFFSET ${offset}
      `;
      countResult = await sql`SELECT COUNT(*) as total FROM cards`;
      
    } else if (filters.hasQuery && !filters.hasGame && !filters.hasRarity && !filters.hasSet && !filters.hasMinPrice && !filters.hasMaxPrice) {
      // Search by name only
      result = await sql`
        SELECT id, name, set_name, set_code, card_number, rarity, game,
          mana_cost, cmc, card_type, colors, oracle_text,
          power, toughness, image_url, stock_image_url,
          current_price, market_price, scryfall_id, verified,
          quantity
        FROM cards
        WHERE name ILIKE ${`%${query.trim()}%`}
        ORDER BY name ASC
        LIMIT ${limitNum} OFFSET ${offset}
      `;
      countResult = await sql`SELECT COUNT(*) as total FROM cards WHERE name ILIKE ${`%${query.trim()}%`}`;
      
    } else if (!filters.hasQuery && filters.hasGame && !filters.hasRarity && !filters.hasSet && !filters.hasMinPrice && !filters.hasMaxPrice) {
      // Filter by game only
      result = await sql`
        SELECT id, name, set_name, set_code, card_number, rarity, game,
          mana_cost, cmc, card_type, colors, oracle_text,
          power, toughness, image_url, stock_image_url,
          current_price, market_price, scryfall_id, verified,
          quantity
        FROM cards
        WHERE game = ${game}
        ORDER BY name ASC
        LIMIT ${limitNum} OFFSET ${offset}
      `;
      countResult = await sql`SELECT COUNT(*) as total FROM cards WHERE game = ${game}`;
      
    } else if (!filters.hasQuery && !filters.hasGame && filters.hasRarity && !filters.hasSet && !filters.hasMinPrice && !filters.hasMaxPrice) {
      // Filter by rarity only
      result = await sql`
        SELECT id, name, set_name, set_code, card_number, rarity, game,
          mana_cost, cmc, card_type, colors, oracle_text,
          power, toughness, image_url, stock_image_url,
          current_price, market_price, scryfall_id, verified,
          quantity
        FROM cards
        WHERE rarity = ${rarity}
        ORDER BY name ASC
        LIMIT ${limitNum} OFFSET ${offset}
      `;
      countResult = await sql`SELECT COUNT(*) as total FROM cards WHERE rarity = ${rarity}`;
      
    } else if (!filters.hasQuery && filters.hasGame && filters.hasRarity && !filters.hasSet && !filters.hasMinPrice && !filters.hasMaxPrice) {
      // Filter by game and rarity
      result = await sql`
        SELECT id, name, set_name, set_code, card_number, rarity, game,
          mana_cost, cmc, card_type, colors, oracle_text,
          power, toughness, image_url, stock_image_url,
          current_price, market_price, scryfall_id, verified,
          quantity
        FROM cards
        WHERE game = ${game} AND rarity = ${rarity}
        ORDER BY name ASC
        LIMIT ${limitNum} OFFSET ${offset}
      `;
      countResult = await sql`SELECT COUNT(*) as total FROM cards WHERE game = ${game} AND rarity = ${rarity}`;
      
    } else if (filters.hasQuery && filters.hasGame && !filters.hasRarity && !filters.hasSet && !filters.hasMinPrice && !filters.hasMaxPrice) {
      // Search with game filter
      result = await sql`
        SELECT id, name, set_name, set_code, card_number, rarity, game,
          mana_cost, cmc, card_type, colors, oracle_text,
          power, toughness, image_url, stock_image_url,
          current_price, market_price, scryfall_id, verified,
          quantity
        FROM cards
        WHERE name ILIKE ${`%${query.trim()}%`} AND game = ${game}
        ORDER BY name ASC
        LIMIT ${limitNum} OFFSET ${offset}
      `;
      countResult = await sql`SELECT COUNT(*) as total FROM cards WHERE name ILIKE ${`%${query.trim()}%`} AND game = ${game}`;
      
    } else {
      // Complex filters - build query dynamically (simplified approach)
      const queryConditions = [];
      
      if (filters.hasQuery) queryConditions.push(`name ILIKE '%${query.trim()}%'`);
      if (filters.hasGame) queryConditions.push(`game = '${game}'`);
      if (filters.hasRarity) queryConditions.push(`rarity = '${rarity}'`);
      if (filters.hasSet) queryConditions.push(`set_name = '${set}'`);
      if (filters.hasMinPrice) queryConditions.push(`market_price >= ${parseFloat(minPrice)}`);
      if (filters.hasMaxPrice) queryConditions.push(`market_price <= ${parseFloat(maxPrice)}`);
      
      const whereClause = queryConditions.length > 0 ? `WHERE ${queryConditions.join(' AND ')}` : '';
      
      // For complex queries, use a fallback approach
      result = await sql`
        SELECT id, name, set_name, set_code, card_number, rarity, game,
          mana_cost, cmc, card_type, colors, oracle_text,
          power, toughness, image_url, stock_image_url,
          current_price, market_price, scryfall_id, verified,
          quantity
        FROM cards
        ORDER BY name ASC
        LIMIT ${limitNum} OFFSET ${offset}
      `;
      countResult = await sql`SELECT COUNT(*) as total FROM cards`;
      
      // Filter results in JavaScript for complex combinations
      let filteredCards = result.rows;
      
      if (filters.hasQuery) {
        filteredCards = filteredCards.filter(card => 
          card.name.toLowerCase().includes(query.trim().toLowerCase())
        );
      }
      if (filters.hasGame) {
        filteredCards = filteredCards.filter(card => card.game === game);
      }
      if (filters.hasRarity) {
        filteredCards = filteredCards.filter(card => card.rarity === rarity);
      }
      if (filters.hasSet) {
        filteredCards = filteredCards.filter(card => card.set_name === set);
      }
      if (filters.hasMinPrice) {
        filteredCards = filteredCards.filter(card => 
          card.market_price >= parseFloat(minPrice)
        );
      }
      if (filters.hasMaxPrice) {
        filteredCards = filteredCards.filter(card => 
          card.market_price <= parseFloat(maxPrice)
        );
      }
      
      // Update result with filtered data
      result = { rows: filteredCards };
      countResult = { rows: [{ total: filteredCards.length }] };
    }

    const total = parseInt(countResult.rows[0].total);
    const totalPages = Math.ceil(total / limitNum);

    // Get filter options (for dropdowns)
    const filtersResult = await sql`
      SELECT 
        ARRAY_AGG(DISTINCT game) FILTER (WHERE game IS NOT NULL) as games,
        ARRAY_AGG(DISTINCT rarity) FILTER (WHERE rarity IS NOT NULL) as rarities,
        ARRAY_AGG(DISTINCT set_name) FILTER (WHERE set_name IS NOT NULL) as sets
      FROM cards
    `;
    
    const filterData = filtersResult.rows[0];

    // Process cards data
    const cards = result.rows.map(card => {
      // Parse colors if it's a JSON string
      if (card.colors && typeof card.colors === 'string') {
        try {
          card.colors = JSON.parse(card.colors);
        } catch (e) {
          card.colors = [];
        }
      }
      return card;
    });

    res.status(200).json({
      success: true,
      cards,
      pagination: {
        page: pageNum,
        limit: limitNum,
        total,
        pages: totalPages,
        hasMore: pageNum < totalPages
      },
      filters: {
        games: filterData.games || [],
        rarities: filterData.rarities || [],
        sets: filterData.sets || []
      }
    });

  } catch (error) {
    console.error('Error searching cards:', error);
    res.status(500).json({ 
      success: false,
      error: 'Internal server error',
      message: error.message 
    });
  }
}
