// src/pages/api/upload.ts
import type { APIRoute } from 'astro';
import { parse, stringify, transform } from 'csv';
import { Readable } from 'stream';
import { client } from '../../db/typesense';
import chalk from 'chalk';
import { db, ClosePool } from '../../db/index';

// Define the transformation logic
const transformer = transform({ parallel: 1 }, async function(this: any, row: any, callback: any) {
try {
    // Specific query bsaed on tcgcollector CSV
    const query = String(Object.values(row)[1]);
    const setname = String(Object.values(row)[4]).replace(/Wizards of the coast promos/ig,'WoTC Promo');
    const cardNumber = String(Object.values(row)[7]);
    console.log(`${query} ${cardNumber} : ${setname}`);

    // Use Typesense to find the card because we can easily use the combined fields
    let cards = await client.collections('cards').documents().search({ q: query, query_by: 'productName', filter_by: `setName:\`${setname}\` && number:${cardNumber}` });
    if (cards.hits?.length === 0) {
        // Try without card number
        cards = await client.collections('cards').documents().search({ q: query, query_by: 'productName', filter_by: `setName:\`${setname}\`` });
    }
    if (cards.hits?.length === 0) {
        // Try without set name
        cards = await client.collections('cards').documents().search({ q: query, query_by: 'productName', filter_by: `number:${cardNumber}` });
    }
    if (cards.hits?.length === 0) {
        // I give up, just output the values from the csv
        console.log(chalk.red('  - not found'));
        const newRow = { ...row };
        newRow.Variant = '';
        newRow.marketPrice = '';
        this.push(newRow);
    }
    else {
        for (const card of cards.hits?.map((hit: any) => hit.document) ?? []) {
            console.log(chalk.blue(`  - ${card.cardId} : ${card.productName} : ${card.number}`), chalk.yellow(`${card.setName}`), chalk.green(`${card.variant}`));
            const variant = await db.query.cards.findFirst({
                with: { prices: true, tcgdata: true },
                where: { cardId: card.cardId }
            });
            const newRow = { ...row };
            newRow.Variant = variant?.variant;
            newRow.marketPrice = variant?.prices.find(p => p.condition === 'Near Mint')?.marketPrice;
            this.push(newRow);
        }
    }

    callback();
} catch (error) {
    callback(error);
}
});


export const POST: APIRoute = async ({ request }) => {
  try {
    const formData = await request.formData();
    const file = formData.get('file') as File;
    const inputStream = Readable.from(file.stream());

    if (!file) {
      return new Response('No file uploaded', { status: 400 });
    }

    // Pipe the streams: Read -> Parse -> Transform -> Stringify -> Write
    const outputStream = inputStream
        .on('error', (error) => console.error('Input stream error:', error))
        .pipe(parse({ columns: true, trim: true }))
        .on('error', (error) => console.error('Parse error:', error))
        .pipe(transformer)
        .on('error', (error) => console.error('Transform error:', error))
        .pipe(stringify({ header: true }))
        .on('error', (error) => console.error('Stringify error:', error));

    // outputStream.on('finish', () => {
    //     ClosePool();
    // }).on('error', (error) => {
    //     ClosePool();
    // });

    
    return new Response(outputStream as any, {
        headers: {
            'Content-Type': 'text/csv',
            'Content-Disposition': 'attachment; filename=transformed.csv',
        },
    });

  } catch (error) {
    console.error('Error processing CSV stream:', error);
    return new Response('Internal Server Error', { status: 500 });
  }
};
