import { dbConnection } from "db";
import type { NextApiRequest, NextApiResponse } from "next";
import { gameConfig } from "@/utils/gameLogic";

export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse
) {
  try {
    if (req.method === "GET") {
      // Get all owned items

      const { userId } = req.query;
      const db = await dbConnection;
      const inventorySql = `
        SELECT id, store_item_id as storeItemId, tier as currentTierIndex
        FROM inventory_item WHERE user_id = ?`;
      const inventoryItems = await db.all(inventorySql, [userId]);
      return res.status(200).json(inventoryItems);

    } else if (req.method === "POST") {
      // Buy a new item
      const { userId } = req.query;
      const { itemId } = req.body;
      const db = await dbConnection;

      const storeItem = gameConfig.store.find((item) => item.id == itemId);

      if (storeItem == undefined) {
        return res.status(400).json({ error: "Item does not exist" });
      }
      const itemPrice = storeItem.price;
      // TODO: Split the try catch to report already owned item error
      try {
        await db.run("BEGIN");
        await db.run(`UPDATE bank_account SET balance = balance - ?
                      WHERE user_id = ?`, [itemPrice, userId]);
        await db.run(`INSERT INTO inventory_item (user_id, store_item_id)
                      VALUES (?, ?)`, [userId, itemId]);
        await db.run("COMMIT");
      } catch (error) {
        await db.exec("ROLLBACK");
        return res.status(400).json({ error: "Either Insufficient funds or item is already owned" });
      }
      return res.status(200).json({ message: "Item purchased successfully" });

    } else if (req.method === "PUT") {
      // Upgrade an existing item
      const { userId } = req.query;
      const { inventoryItemId, storeItemId } = req.body;
      const db = await dbConnection;

      const invItem = await db.get(`SELECT id,tier,store_item_id FROM inventory_item
                                    WHERE id = ? AND user_id = ?`, [inventoryItemId, userId]);

      const storeItem = gameConfig.store.find((item) => item.id == invItem.store_item_id);
      if (storeItem == undefined) {
        return res.status(400).json({ error: "Item does not exist" });
      }

      const tier = invItem.tier;
      if (tier == undefined) {
        return res.status(400).json({ error: "Item does not exist" });
      }
      if (tier >= storeItem.upgrades.length) {
        return res.status(400).json({ error: "Max upgrade reached" });
      }
      const upgradePrice = storeItem.upgrades[tier].price;
      try {
        await db.run("BEGIN");
        await db.run(`UPDATE bank_account SET balance = balance - ?
                      WHERE user_id = ?`, [upgradePrice, userId]);
        await db.run(`UPDATE inventory_item SET tier = tier + 1 WHERE id = ?`, [inventoryItemId]);
        await db.run("INSERT INTO upgrade_event(inventory_item_id) VALUES ( ? )", [invItem.store_item_id]);
        await db.run("COMMIT");
      } catch (error) {
        await db.exec("ROLLBACK");
        return res.status(400).json({ error: "Insufficient funds" });
      }
      return res.status(200).json({ message: "Successfully upgraded item" });
    }
  } catch (error) {
    if(error instanceof Error){
      res.status(500).json(error.message);
    }else {
      res.status(500).json("Unknow Error");
    }
  }
}
