import { PurchaseModel, purchaseValidationSchema } from "../models/purchase";
import { ProductModel } from "../models/product";
import { Request, Response } from "express";

/// Create new purchase
export const createPurchase = async (req: Request, res: Response) => {
  const { error } = purchaseValidationSchema.validate(req.body);
  if (error) return res.status(400).json({ error: error.details[0].message });

  try {
    // Check if product exists
    const product = await ProductModel.findByPk(req.body.productId);
    if (!product) {
      return res.status(404).json({ error: "Product not found." });
    }

    // Create the purchase
    const newPurchase = await PurchaseModel.create(req.body);

    // Update product stock (increase by purchased quantity)
    await product.update({
      remainingStock: product.remainingStock + req.body.quantity
    });

    return res
      .status(200)
      .json({ 
        message: "Purchase created successfully and stock updated.", 
        id: newPurchase.id,
        updatedStock: product.remainingStock + req.body.quantity
      });
  } catch (ex) {
    console.error("Error creating purchase:", ex);
    return res.status(500).json({ error: "An unexpected error occurred." });
  }
};

/// Get all purchases
export const getAllPurchases = async (req: Request, res: Response) => {
  try {
    const purchases = await PurchaseModel.findAll({
      where: { isDeleted: false },
    });
    return res.status(200).json(purchases);
  } catch (ex) {
    return res.status(500).json({ error: "An unexpected error occurred." });
  }
};

/// Update existing purchase
export const updatePurchase = async (req: Request, res: Response) => {
  try {
    // Find the purchase by ID
    const purchase = await PurchaseModel.findByPk(req.params.id);
    if (!purchase)
      return res.status(404).json({ error: "Purchase not found." });

    // Validate the request body
    const { error } = purchaseValidationSchema.validate(req.body);
    if (error) return res.status(400).json({ error: error.details[0].message });

    // Find the product
    const product = await ProductModel.findByPk(purchase.productId);
    if (!product) {
      return res.status(404).json({ error: "Associated product not found." });
    }

    // Calculate stock difference
    const oldQuantity = purchase.quantity;
    const newQuantity = req.body.quantity;
    const stockDifference = newQuantity - oldQuantity;

    // Update the purchase details
    await purchase.update(req.body);

    // Update product stock
    await product.update({
      remainingStock: product.remainingStock + stockDifference
    });

    // Send success response
    return res
      .status(200)
      .json({ 
        message: "Purchase updated successfully and stock adjusted.", 
        id: purchase.id,
        stockAdjustment: stockDifference,
        newStock: product.remainingStock + stockDifference
      });
  } catch (ex) {
    console.error(`Error updating purchase: ${ex}`);
    return res.status(500).json({ error: "An unexpected error occurred." });
  }
};

/// Delete a purchase
export const deletePurchase = async (req: Request, res: Response) => {
  try {
    // Find the purchase by ID
    const purchase = await PurchaseModel.findByPk(req.params.id);
    if (!purchase)
      return res.status(404).json({ error: "Purchase not found." });

    // Find the product to adjust stock
    const product = await ProductModel.findByPk(purchase.productId);
    if (product) {
      // Decrease stock by the purchased quantity (reverse the purchase)
      await product.update({
        remainingStock: Math.max(0, product.remainingStock - purchase.quantity)
      });
    }

    // Soft delete the purchase
    await purchase.update({ isDeleted: true });

    // Send success response
    return res.status(200).json({ 
      message: "Purchase deleted successfully and stock adjusted.",
      stockReduced: purchase.quantity
    });
  } catch (ex) {
    console.error("Error deleting purchase:", ex);
    return res.status(500).json({ error: "An unexpected error occurred." });
  }
};
