import { Request, Response, NextFunction } from "express";
import {
  ShopPurchaseModel,
  shopPurchaseValidationSchema,
} from "../models/shop_purchase";
import { ShopProductModel } from "../models/shop_product";

export const createShopPurchase = async (
  req: Request,
  res: Response,
  next: NextFunction
) => {
  try {
    const { error } = shopPurchaseValidationSchema.validate(req.body);
    if (error) {
      return res
        .status(400)
        .json({ error: { message: error.details[0].message } });
    }

    // Check if user has access to this shop
    const userRole = (req as any).user?.role;
    const assignedShopIds = (req as any).user?.assignedShopIds || [];

    if (userRole === "Shopkeeper" && !assignedShopIds.includes(req.body.shopId)) {
      return res.status(403).json({ error: "Access denied. You can only create purchases for shops assigned to you." });
    }

    // Check if shop product exists
    const shopProduct = await ShopProductModel.findByPk(req.body.productId);
    if (!shopProduct) {
      return res
        .status(404)
        .json({ error: { message: "Shop product not found" } });
    }

    // Create the shop purchase
    const shopPurchase = await ShopPurchaseModel.create(req.body);

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

    res.status(201).json({
      ...shopPurchase.toJSON(),
      message: "Shop purchase created and stock updated",
      updatedStock: shopProduct.remainingStock + req.body.quantity
    });
  } catch (error) {
    console.error("Error creating shop purchase:", error);
    next(error);
  }
};

export const getAllShopPurchases = async (
  req: Request,
  res: Response,
  next: NextFunction
) => {
  try {
    const userRole = (req as any).user?.role;
    const assignedShopIds = (req as any).user?.assignedShopIds || [];

    let shopPurchases;

    if (userRole === "Shopkeeper") {
      if (assignedShopIds.length === 0) {
        return res.status(200).json([]); // Return empty array if no shops assigned
      }
      
      // Get only purchases from shops assigned to this shopkeeper
      shopPurchases = await ShopPurchaseModel.findAll({
        where: { 
          isDeleted: false,
          shopId: assignedShopIds
        },
      });
    } else {
      // Admin can see all shop purchases
      shopPurchases = await ShopPurchaseModel.findAll({
        where: { isDeleted: false },
      });
    }

    res.status(200).json(shopPurchases);
  } catch (error) {
    next(error);
  }
};

export const getShopPurchasesByShop = async (
  req: Request,
  res: Response,
  next: NextFunction
) => {
  try {
    const shopId = parseInt(req.params.shopId);
    const userRole = (req as any).user?.role;
    const assignedShopIds = (req as any).user?.assignedShopIds || [];

    // Check if user has access to this shop
    if (userRole === "Shopkeeper" && !assignedShopIds.includes(shopId)) {
      return res.status(403).json({ error: "Access denied. You can only view purchases for shops assigned to you." });
    }

    const shopPurchases = await ShopPurchaseModel.findAll({
      where: { 
        shopId: shopId,
        isDeleted: false 
      },
    });

    res.status(200).json(shopPurchases);
  } catch (error) {
    next(error);
  }
};

export const getShopPurchaseById = async (
  req: Request,
  res: Response,
  next: NextFunction
) => {
  try {
    const { id } = req.params;
    const userRole = (req as any).user?.role;
    const assignedShopIds = (req as any).user?.assignedShopIds || [];

    const shopPurchase = await ShopPurchaseModel.findOne({
      where: { id, isDeleted: false },
    });

    if (!shopPurchase) {
      return res
        .status(404)
        .json({ error: { message: "Shop Purchase not found" } });
    }

    // Check if user has access to this shop
    if (userRole === "Shopkeeper" && !assignedShopIds.includes(shopPurchase.shopId)) {
      return res.status(403).json({ error: "Access denied. You can only view purchases for shops assigned to you." });
    }

    res.status(200).json(shopPurchase);
  } catch (error) {
    next(error);
  }
};

export const updateShopPurchase = async (
  req: Request,
  res: Response,
  next: NextFunction
) => {
  try {
    const { id } = req.params;
    const userRole = (req as any).user?.role;
    const assignedShopIds = (req as any).user?.assignedShopIds || [];

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

    // Find the shop purchase
    const shopPurchase = await ShopPurchaseModel.findOne({
      where: { id, isDeleted: false }
    });

    if (!shopPurchase) {
      return res
        .status(404)
        .json({ error: { message: "Shop Purchase not found" } });
    }

    // Check if user has access to this shop
    if (userRole === "Shopkeeper" && !assignedShopIds.includes(shopPurchase.shopId)) {
      return res.status(403).json({ error: "Access denied. You can only update purchases for shops assigned to you." });
    }

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

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

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

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

    const updatedShopPurchase = await ShopPurchaseModel.findByPk(id);
    res.status(200).json({
      ...updatedShopPurchase?.toJSON(),
      message: "Shop purchase updated and stock adjusted",
      stockAdjustment: stockDifference,
      newStock: shopProduct.remainingStock + stockDifference
    });
  } catch (error) {
    console.error("Error updating shop purchase:", error);
    next(error);
  }
};

export const deleteShopPurchase = async (
  req: Request,
  res: Response,
  next: NextFunction
) => {
  try {
    const { id } = req.params;
    const userRole = (req as any).user?.role;
    const assignedShopIds = (req as any).user?.assignedShopIds || [];
    
    // Find the shop purchase
    const shopPurchase = await ShopPurchaseModel.findOne({
      where: { id, isDeleted: false }
    });

    if (!shopPurchase) {
      return res
        .status(404)
        .json({ error: { message: "Shop Purchase not found" } });
    }

    // Check if user has access to this shop
    if (userRole === "Shopkeeper" && !assignedShopIds.includes(shopPurchase.shopId)) {
      return res.status(403).json({ error: "Access denied. You can only delete purchases for shops assigned to you." });
    }

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

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

    res.status(200).json({ 
      message: "Shop Purchase deleted successfully and stock adjusted",
      stockReduced: shopPurchase.quantity
    });
  } catch (error) {
    console.error("Error deleting shop purchase:", error);
    next(error);
  }
};
