import type { APIRoute } from 'astro';
import { db } from '../../db/index';
import { inventory, priceHistory } from '../../db/schema';
import { client } from '../../db/typesense';
import { eq } from 'drizzle-orm';

const GainLoss = (purchasePrice: any, marketPrice: any) => {
    if (!purchasePrice || !marketPrice) return '<div class="fs-6 fw-semibold">N/A</div>';
    const pp = Number(purchasePrice);
    const mp = Number(marketPrice);
    if (pp === mp) return '<div class="fs-6 fw-semibold text-warning">-</div>';
    if (pp > mp) return `<div class="fs-6 fw-semibold text-danger">-$${(pp - mp).toFixed(2)}</div>`;
    return `<div class="fs-6 fw-semibold text-success">+$${(mp - pp).toFixed(2)}</div>`;
}
const DollarToInt = (dollar: any) => {
    if (dollar === null) return null;
    return Math.round(dollar * 100);
}

const getInventory = async (userId: string, cardId: number) => {

    const card = await db.query.cards.findFirst({
        where: { cardId: cardId, },
        with : { prices: {
            with: { inventories: { where: { userId: userId } }, }
        }, },
    });

    const invHtml = card?.prices?.flatMap(price => price.inventories.map(inv => {
        const marketPrice = price.marketPrice;
        const marketPriceDisplay = marketPrice ? `$${marketPrice}` : '—';
        const purchasePriceDisplay = inv.purchasePrice ? `$${Number(inv.purchasePrice).toFixed(2)}` : '—';

        return `
        <article class="border rounded-4 p-2 inventory-entry-card"
            data-inventory-id="${inv.inventoryId}"
            data-card-id="${price.cardId}"
            data-purchase-price="${inv.purchasePrice}"
            data-note="${(inv.note || '').replace(/"/g, '&quot;')}">
            <div class="d-flex flex-column">
                <!-- Top row -->
                <div class="d-flex justify-content-between gap-3">
                    <div class="min-w-0 flex-grow-1">
                        <div class="fw-semibold fs-6 text-body mb-1">${price.condition}</div>
                    </div>
                    <div class="fs-7 text-secondary">Added: ${inv.createdAt ? new Date(inv.createdAt).toLocaleDateString() : '—'}</div>
                </div>
                <!-- Middle row -->
                <div class="row g-2">
                    <div class="col-4">
                        <div class="small text-secondary">Purchase price</div>
                        <div class="fs-6 fw-semibold">${purchasePriceDisplay}</div>
                    </div>
                    <div class="col-4">
                        <div class="small text-secondary">Market price</div>
                        <div class="fs-6 text-success">${marketPriceDisplay}</div>
                    </div>
                    <div class="col-4">
                        <div class="small text-secondary">Gain / loss</div>
                        ${GainLoss(inv.purchasePrice, marketPrice)}
                    </div>
                </div>
                <!-- Bottom row -->
                <div class="d-flex justify-content-between align-items-center gap-3 flex-wrap mt-2">
                    <div class="d-flex align-items-center gap-2">
                        <span class="small text-secondary">Qty</span>
                        <div class="btn-group" role="group" aria-label="Quantity controls">
                            <button type="button" class="btn btn-outline-secondary btn-sm" data-inv-action="decrement">−</button>
                            <button type="button" class="btn btn-outline-secondary btn-sm" tabindex="-1" data-inv-qty>${inv.quantity}</button>
                            <button type="button" class="btn btn-outline-secondary btn-sm" data-inv-action="increment">+</button>
                        </div>
                    </div>
                    <div class="d-flex align-items-center gap-2 flex-wrap">
                        <!-- <button type="button" class="btn btn-sm btn-outline-secondary" data-inv-action="update">Edit</button> -->
                        <button type="button" class="btn btn-sm btn-outline-danger" data-inv-action="remove" onclick="if(!confirm('Are you sure you want to remove this card from your inventory?')) event.stopImmediatePropagation();">Remove</button>
                    </div>
                </div>
            </div>
        </article>`;
    })) || [];

    return new Response(
        invHtml.join(''),
        {
            status: 200,
            headers: { 'Content-Type': 'text/html' },
        }
    );
}


const addToInventory = async (userId: string, cardId: number, skuId: number, purchasePrice: number, quantity: number, note: string, catalogName: string) => {
    // First add to database
    const inv = await db.insert(inventory).values({
        userId: userId,
        skuId: skuId,
        catalogName: catalogName,
        purchasePrice: purchasePrice.toFixed(2),
        quantity: quantity,
        note: note,
    }).returning();
    // Get card details from the database to add to Typesense
    const card = await db.query.cards.findFirst({
        where: { cardId: cardId },
        with: { set: true },
    });

    try {
    // And then add to Typesense for searching
    await client.collections('inventories').documents().import(inv.map(i => ({
        id: i.inventoryId,
        userId: i.userId,
        catalogName: i.catalogName,
        sku_id: i.skuId.toString(),
        purchasePrice: DollarToInt(i.purchasePrice),
        productLineName: card?.productLineName,
        rarityName: card?.rarityName,
        setName: card?.set?.setName || "",
        cardType: card?.cardType || "",
        energyType: card?.energyType || "",
        card_id: card?.cardId.toString() || "",
        content: [
            card?.productName, 
            card?.productLineName, 
            card?.set?.setName || "", 
            card?.number, 
            card?.rarityName, 
            card?.artist || ""
        ].join(' '),
    })));
    } catch (error) {
        console.error('Error adding inventory to Typesense:', error);
    }
}

const removeFromInventory = async (inventoryId: string) => {
    await db.delete(inventory).where(eq(inventory.inventoryId, inventoryId));
    await client.collections('inventories').documents(inventoryId).delete();
}

const updateInventory = async (inventoryId: string, quantity: number, purchasePrice: number, note: string, catalogName: string) => {
    // Update the database
    await db.update(inventory).set({
        quantity: quantity,
        purchasePrice: purchasePrice.toFixed(2),
        note: note,
        catalogName: catalogName,
    }).where(eq(inventory.inventoryId, inventoryId));
    // Quantity/price/note aren't searched, but catalogName is faceted in Typesense.
    try {
        await client.collections('inventories').documents(inventoryId).update({ catalogName });
    } catch (error) {
        console.error('Error updating inventory catalog in Typesense:', error);
    }
}

export const POST: APIRoute = async ({ request, locals }) => {
    // Access form data from the request body
    const formData = await request.formData();
    const action = formData.get('action');
    const cardId = Number(formData.get('cardId')) || 0;
    const { userId } = locals.auth();

    switch (action) {

        case 'add':
            const purchasePrice = Number(formData.get('purchasePrice')) || 0;
            const quantity = Number(formData.get('quantity')) || 1;
            const note = formData.get('note')?.toString() || '';
            const catalogName = formData.get('catalogName')?.toString() || 'Default';
            const condition = formData.get('condition')?.toString() || 'Near Mint';
            const skuId = await db.query.skus.findFirst({
                where: { cardId: cardId, condition: condition },
                columns: { skuId: true },
            }).then(sku => sku?.skuId);
            if (!skuId) {
                return new Response('SKU not found for card', { status: 404 });
            }
            await addToInventory(userId!, cardId, skuId, purchasePrice, quantity, note, catalogName);
            break;

        case 'remove':
            const inventoryId = formData.get('inventoryId')?.toString() || '';
            await removeFromInventory(inventoryId);
            break;

        case 'update':
            const invId = formData.get('inventoryId')?.toString() || '';
            const qty = Number(formData.get('quantity')) || 1;
            const price = Number(formData.get('purchasePrice')) || 0;
            const invNote = formData.get('note')?.toString() || '';
            const invCatalog = formData.get('catalogName')?.toString() || 'Default';
            await updateInventory(invId, qty, price, invNote, invCatalog);
            break;

        default:
            // No action = list inventory for this card
            return getInventory(userId!, cardId);
    }

    // Always return current inventory after a mutation
    return getInventory(userId!, cardId);
};