Skip to content
import { cardCounts, openPack, PACK_COST } from "../../../lib/cards.ts";
import { initDb, transaction } from "../../../lib/db.ts";
import { type ClassId, getHero } from "../../../lib/heroes.ts";
import { define } from "../../../utils.ts";

export const handler = define.handlers({
  async POST(ctx) {
    const user = ctx.state.user;
    if (!user) return new Response("Unauthorized", { status: 401 });
    await initDb();
    if (!await getHero(user.id)) {
      return Response.json({ error: "No hero." }, { status: 404 });
    }

    const tx = await transaction();
    try {
      const result = await tx.execute({
        sql: "SELECT class, anima FROM heroes WHERE user_id = ?",
        args: [user.id],
      });
      const row = result.rows[0];
      if (!row) {
        await tx.rollback();
        return Response.json({ error: "No hero." }, { status: 404 });
      }
      const anima = Number(row.anima);
      if (anima < PACK_COST) {
        await tx.rollback();
        return Response.json(
          { error: `A pack costs ${PACK_COST} Anima.` },
          { status: 400 },
        );
      }

      const cards = openPack(String(row.class) as ClassId);
      const nextAnima = anima - PACK_COST;
      await tx.execute({
        sql: "UPDATE heroes SET anima = ? WHERE user_id = ?",
        args: [nextAnima, user.id],
      });
      for (const [cardId, quantity] of Object.entries(cardCounts(cards))) {
        await tx.execute({
          sql: `INSERT INTO card_collection (user_id, card_id, quantity)
                VALUES (?, ?, ?)
                ON CONFLICT(user_id, card_id)
                DO UPDATE SET quantity = quantity + excluded.quantity`,
          args: [user.id, cardId, quantity],
        });
      }
      await tx.commit();
      return Response.json({ cards, anima: nextAnima });
    } catch (error) {
      await tx.rollback();
      console.error("Failed to open card pack", error);
      return Response.json({ error: "The atelier is unavailable." }, {
        status: 500,
      });
    } finally {
      tx.close();
    }
  },
});