const Chats = require("../models/Chats");
const Customers = require("../models/Customers");
const SellersCompany = require("../models/SellersCompany");
const Conversations = require("../models/Conversations");
const Sequelize = require("sequelize");
const {
  agentCustomerDetailsExcludes,
  getSellersCompanyExcludes,
} = require("../helpers/model-excludes-attributes/excludes");

exports.customerToSellerChat = async (req, res, next) => {
  try {
    const customerId = req.customerId;

    const { sellerId, message } = req.body;

    // Fetch the user details based on customerId
    const customer = await Customers.findByPk(customerId);

    if (!customer) {
      return res.status(404).json({ error: "Customer not found" });
    }

    // Fetch the seller details based on sellerId
    const seller = await SellersCompany.findByPk(sellerId);

    if (!seller) {
      return res.status(404).json({ error: "Seller not found" });
    }

    // Check if there is an existing conversation between buyer and seller
    let existingConversation = await Conversations.findOne({
      where: {
        buyer_id: customerId,
        seller_id: sellerId,
      },
    });

    let conversationId;
    // If there is no existing conversation, create a new one
    if (!existingConversation) {
      const newConversation = await Conversations.create({
        buyer_id: customerId,
        seller_id: sellerId,
        last_updated: new Date(),
      });
      conversationId = newConversation.id;
    } else {
      conversationId = existingConversation.id;
      // Update the last_updated time for the existing conversation
      await existingConversation.update({ last_updated: new Date() });
    }

    // Create a new chat entry with the fetched conversation_id
    const chatEntry = await Chats.create({
      conversation_id: conversationId.toString(),
      buyer_id: customerId,
      seller_id: null,
      message: message,
      created_on: new Date(),
      isSeen_buyer: 1,
      isSeen_seller: 0,
    });

    // Handle successful chat entry creation
    res.status(201).json({
      message: "Chat entry created successfully",
      customer,
      seller,
      chatEntry,
    });
  } catch (error) {
    // Handle errors
    console.error(error);
    return res.status(500).json({ error: "Internal Server Error" });
  }
};

exports.sellerToCustomerChat = async (req, res) => {
  try {
    const { message, customerId } = req.body;
    const { sellerId } = req.params;

    // Check if the seller_id exists in the SellersCompany model
    const sellerExists = await SellersCompany.findOne({
      where: {
        id: sellerId,
      },
    });

    // If seller_id doesn't exist, return an error
    if (!sellerExists) {
      return res.status(400).json({ message: "Invalid sellerId. Seller does not exist." });
    }

    // Fetch the buyer details based on the customerId from the request body
    const buyer = await Customers.findByPk(customerId);

    if (!buyer) {
      return res.status(404).json({ error: "Buyer not found" });
    }

    // Check if there's an existing conversation between the seller and buyer
    let existingConversation = await Conversations.findOne({
      where: {
        buyer_id: customerId, // Use customerId from the request body
        seller_id: sellerId,
      },
    });

    let conversationId;
    // If no existing conversation found, create a new one
    if (!existingConversation) {
      existingConversation = await Conversations.create({
        buyer_id: customerId, // Use customerId from the request body
        seller_id: sellerId,
        last_updated: new Date(),
      });
      conversationId = existingConversation.id;
    } else {
      conversationId = existingConversation.id;
      // Update the last_updated time for the existing conversation
      await existingConversation.update({ last_updated: new Date() });
    }

    let isSeen_buyer = 0;
    let isSeen_seller = 1; // Set isSeen_seller to 1 since the message is being sent by the seller

    // Get the current date in UTC
    const currentDateUTC = new Date();

    // Convert UTC to Singapore time (UTC +8:00)
    const singaporeTime = new Date(currentDateUTC.getTime() + 8 * 60 * 60 * 1000);

    // Create a new chat entry with the fetched conversation_id
    const chatEntry = await Chats.create({
      conversation_id: conversationId.toString(),
      buyer_id: null, // Set buyer_id to null
      seller_id: sellerId,
      message: message,
      created_on: singaporeTime,
      isSeen_buyer: isSeen_buyer,
      isSeen_seller: isSeen_seller,
    });

    // Handle successful chat entry creation
    res.status(201).json({
      message: "Chat entry created successfully",
      buyer,
      seller: sellerExists,
      chatEntry,
    });
  } catch (error) {
    // Handle errors
    console.error(error);
    return res.status(500).json({ error: "Internal Server Error" });
  }
};

exports.deleteChat = async (req, res) => {
  try {
    const { chatId } = req.params;

    // Find the chat by ID
    const chat = await Chats.findByPk(chatId);

    // If chat doesn't exist, return an error
    if (!chat) {
      return res.status(404).json({ message: "Chat not found" });
    }

    // Update the chat to mark it as deleted
    await chat.update({ isDeletedv: true });

    // Return the updated chat along with success message
    res.json({ success: "Chat marked as deleted successfully" });
  } catch (error) {
    console.error(error);
    return res.status(500).json({ message: "Server Error" });
  }
};

exports.getConversationCustomerAndSeller = (req, res, next) => {
  const { customerId } = req;

  Conversations.findAll({
    where: {
      buyer_id: customerId,
    },
    attributes: {
      exclude: ["buyer_id", "seller_id"],
    },
    include: [
      {
        model: SellersCompany,
        as: "seller_company",
        attributes: {
          exclude: getSellersCompanyExcludes(),
        },
      },
    ],
  })
    .then((conversations) => {
      const response = conversations.map(({ id, last_updated, seller_company }) => ({
        id: id,
        last_updated: last_updated,
        seller_detail: {
          id: seller_company?.id,
          name:
            seller_company?.shop_name === "" || seller_company?.shop_name === null
              ? seller_company?.company_name
              : seller_company?.shop_name,
          seller_logo: `https://buildhub.ph/img/seller/${seller_company?.seller_logo}`,
        },
      }));
      res.status(200).json({ success: true, user_conversations: response });
    })
    .catch((err) => {
      next(err);
    });
};

exports.getChatsCustomerAndSeller = (req, res, next) => {
  const { conversationId } = req.params;
  const { customerId } = req;
  const page = req.query.page ? parseInt(req.query.page) : 1;
  const pageSize = req.query.pageSize ? parseInt(req.query.pageSize) : 10;

  const offset = (page - 1) * pageSize;

  Conversations.findOne({
    where: {
      id: conversationId,
      buyer_id: customerId,
    },
  })
    .then((conversation) => {
      if (!conversation) {
        throw new Error("Conversation Id doesnt exist");
      }
      return Chats.findAndCountAll({
        where: {
          conversation_id: conversationId,
          isDeletedv: {
            [Sequelize.Op.not]: true,
          },
        },
        include: [
          {
            model: Customers,
            as: "buyer",
            attributes: {
              exclude: agentCustomerDetailsExcludes(),
            },
          },
          {
            model: SellersCompany,
            as: "seller",
            attributes: {
              exclude: getSellersCompanyExcludes(),
            },
          },
        ],
        order: [["created_on", "DESC"]],
        limit: pageSize,
        offset: offset,
      });
    })
    .then((result) => {
      const { count, rows } = result;
      const totalPages = Math.ceil(count / pageSize);

      res.status(200).json({
        success: true,
        conversationId,
        chats: rows,
        totalChats: count,
        totalPages: totalPages,
        currentPage: page,
      });
    })
    .catch((err) => {
      next(err);
    });
};

exports.getConversationBySellerId = (req, res, next) => {
  const { customerId } = req;
  const { sellerId } = req.params;

  SellersCompany.findByPk(sellerId)
    .then((seller) => {
      if (!seller) {
        return res.status(200).json({ success: false, msg: "Seller does not exist." });
      }

      return Conversations.findOne({
        where: {
          buyer_id: customerId,
          seller_id: sellerId,
        },
      });
    })
    .then((conversation) => {
      if (!conversation) {
        return Conversations.create({
          buyer_id: customerId,
          seller_id: sellerId,
          last_updated: new Date(),
        }).then((newConversation) => {
          res.status(200).json({ success: true, conversation_id: newConversation.id });
        });
      }
      res.status(200).json({ success: true, conversation_id: conversation.id });
    })
    .catch((err) => {
      next(err);
    });
};
