import { ShopModel, shopValidationSchema } from "../models/shop";
import { UserModel } from "../models/user";
import { Request, Response } from "express";

/// Get all shopkeepers for admin to assign to shops
export const getShopkeepers = async (req: Request, res: Response) => {
  try {
    const shopkeepers = await UserModel.findAll({
      where: { 
        role: "Shopkeeper",
        isDeleted: false 
      },
      attributes: ['id', 'name', 'email', 'phoneNumber']
    });
    return res.status(200).json(shopkeepers);
  } catch (ex) {
    return res.status(500).json({ error: "An unexpected error occurred." });
  }
};

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

  try {
    // If shopkeeperIds are provided, verify all users exist and are shopkeepers
    if (req.body.shopkeeperIds && req.body.shopkeeperIds.length > 0) {
      const shopkeepers = await UserModel.findAll({
        where: { 
          id: req.body.shopkeeperIds, 
          role: "Shopkeeper",
          isDeleted: false 
        },
        attributes: ['id', 'name']
      });

      if (shopkeepers.length !== req.body.shopkeeperIds.length) {
        return res.status(400).json({ error: "One or more invalid shopkeeper user IDs." });
      }

      // Auto-populate shopkeeperNames if not provided
      if (!req.body.shopkeeperNames || req.body.shopkeeperNames.length === 0) {
        req.body.shopkeeperNames = shopkeepers.map(sk => sk.name);
      }
    }

    const newShop = await ShopModel.create(req.body);
    return res
      .status(200)
      .json({ message: "Shop created successfully.", id: newShop.id });
  } catch (ex) {
    return res.status(500).json({ error: "An unexpected error occurred." });
  }
};

/// Get all shops (filtered by user role)
export const getAllShops = async (req: Request, res: Response) => {
  try {
    // Extract user info from JWT token (assuming middleware sets req.user)
    const userRole = (req as any).user?.role;
    const assignedShopIds = (req as any).user?.assignedShopIds || [];

    let shops;

    // If user is shopkeeper, only show shops assigned to them
    if (userRole === "Shopkeeper") {
      if (assignedShopIds.length === 0) {
        return res.status(200).json([]); // Return empty array if no shops assigned
      }

      shops = await ShopModel.findAll({
        where: { 
          id: assignedShopIds,
          isDeleted: false 
        }
      });
    } else {
      // Admin can see all shops
      shops = await ShopModel.findAll({
        where: { isDeleted: false }
      });
    }
    
    return res.status(200).json(shops);
  } catch (ex) {
    return res.status(500).json({ error: "An unexpected error occurred." });
  }
};

/// Get shops assigned to current user (for shopkeepers)
export const getMyShops = async (req: Request, res: Response) => {
  try {
    const userRole = (req as any).user?.role;
    const assignedShopIds = (req as any).user?.assignedShopIds || [];

    if (userRole !== "Shopkeeper") {
      return res.status(403).json({ error: "Access denied. Only shopkeepers can access this endpoint." });
    }

    if (assignedShopIds.length === 0) {
      return res.status(200).json([]); // Return empty array if no shops assigned
    }

    const shops = await ShopModel.findAll({
      where: { 
        id: assignedShopIds,
        isDeleted: false 
      }
    });
    
    return res.status(200).json(shops);
  } catch (ex) {
    return res.status(500).json({ error: "An unexpected error occurred." });
  }
};

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

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

    if (userRole === "Shopkeeper" && !assignedShopIds.includes(parseInt(req.params.id))) {
      return res.status(403).json({ error: "Access denied. You can only update shops assigned to you." });
    }

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

    // If shopkeeperIds are being updated, verify all users exist and are shopkeepers
    if (req.body.shopkeeperIds && req.body.shopkeeperIds.length > 0) {
      const shopkeepers = await UserModel.findAll({
        where: { 
          id: req.body.shopkeeperIds, 
          role: "Shopkeeper",
          isDeleted: false 
        },
        attributes: ['id', 'name']
      });

      if (shopkeepers.length !== req.body.shopkeeperIds.length) {
        return res.status(400).json({ error: "One or more invalid shopkeeper user IDs." });
      }

      // Auto-populate shopkeeperNames if not provided
      if (!req.body.shopkeeperNames || req.body.shopkeeperNames.length === 0) {
        req.body.shopkeeperNames = shopkeepers.map(sk => sk.name);
      }
    }

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

    // Send success response
    return res
      .status(200)
      .json({ message: "Shop updated successfully.", id: shop.id });
  } catch (ex) {
    console.error(`Error updating shop: ${ex}`);
    return res.status(500).json({ error: "An unexpected error occurred." });
  }
};

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

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

    if (userRole === "Shopkeeper" && !assignedShopIds.includes(parseInt(req.params.id))) {
      return res.status(403).json({ error: "Access denied. You can only delete shops assigned to you." });
    }

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

    // Send success response
    return res.status(200).json({ message: "Shop deleted successfully." });
  } catch (ex) {
    return res.status(500).json({ error: "An unexpected error occurred." });
  }
};
