const { empty, removeNull } = require("../Helpers/Common");
const moment = require("moment");
const crypto = require("crypto");
let currentDate = Math.round(moment().valueOf() / 1000);
const Chat = require('../models/chatModel')
const Admin = require('../models/admin');
const { sendMessageToPhoneNumber } = require("./teams");
const { SEND_EMAIL_MUTE } = require("../constants/constant");
const { messageNotificationEmail } = require("../constants/emailTemplates");
const { transporter } = require("./product");

const addChat = async (req, res) => {
  try {
    const { type, groupName, createdBy, members } = req.body;
    if (!type || !createdBy || !Array.isArray(members) || members.length === 0) {
      return res.send({ status: 0, message: "Invalid data!" });
    }
    const created_at = moment().unix();
    let conversationData = {
      type: type,
      group_name: type === "group" ? groupName : null, // Group name only for group chats
      created_by: createdBy,
      created_at: created_at,
    };
    const conversationId = await Chat.createConversation(conversationData, members, created_at);
    if (conversationId) {
      res.send({ status: 1, message: `Conversation created successfully`, conversationId });
    } else {
      res.send({ status: 0, message: `Error creating conversation!` });
    }
  } catch (error) {
    res.send({ status: 500, message: 'Error creating conversation', error: error });
  }
};
const readChats = async (req, res) => {
  try {
    const { messageId, userId, conversationId, conversationType } = req.body;
    if (!messageId || !userId || !conversationId || !conversationType) {
      return res.send({ status: 0, message: "Invalid data!" });
    }
    const readMessages = await Chat.readMessages(messageId, userId, conversationId, conversationType);
    if (readMessages) {
      res.send({ status: 1, message: `Message Read Successfully` });
    } else {
      res.send({ status: 0, message: `Error reading conversation!` });
    }
  } catch (error) {
    res.send({ status: 500, message: 'Error reading conversation', error: error });
  }
};

const getChatList = async (req, res) => {
  try {
    const { usersId } = req.body;
    console.log('userId+++++++', req.body)

    if (!usersId) {
      return res.send({ status: 0, message: "User ID is required." });
    }

    const chatList = await Chat.getChatList(usersId);
    if (!chatList) {
      return res.send({ status: 0, message: "Error fetching chat list." });
    }
    let totalUnreadCount = 0;

    chatList.forEach(chat => {
      if (chat.unread_messages && chat.unread_messages > 0) {
        totalUnreadCount += 1;
      }
    });



    res.send({ status: 1, data: chatList, totalUnreadCount });
  } catch (error) {
    console.error("Error fetching chat list:", error);
    res.send({ status: 0, message: "Server error" });
  }
};
const readMessages = async (req, res) => {

  try {
    const { conversationId, userId } = req.body;
    console.log('userId+++++++', req.body)

    if (!usersId) {
      return res.send({ status: 0, message: "User ID is required." });
    }

    const removeCount = await Chat.readMessages(conversationId, userId);

    if (!removeCount) {
      return res.send({ status: 0, message: "Error remove unread counts" });
    }

    res.send({ status: 1, data: chatList });
  } catch (error) {
    console.error("Error fetching chat list:", error);
    res.send({ status: 0, message: "Server error" });
  }
};
const muteNotification = async (req, res) => {

  try {
    const { phone_notif, email_notif, conversationId, userId, conversation_type, receiver_id } = req.body;

    if (!userId || !conversation_type) {
      return res.send({ status: 0, message: "Missing required fields." });
    }
    let userData = await Admin.getUserById(userId)
  let alertStatus= userData[0]?.alert_status
  if(alertStatus===0){
     return res.send({ status: 2, message: "Please turn on SMS/Email Alerts" });
  }

    let data = {
      phone_notif: phone_notif,
      email_notif: email_notif,
    };
    let muteSuccess = false;
    if (conversation_type === 'group') {
      muteSuccess = await Chat.updateConversationMembers(data, conversationId, userId);
    } else {
      if (!userId || !receiver_id) {
        return res.send({ status: 0, message: "Missing required fields." });
      }
      let chatExists = await Chat.isSingleChatMembersExists(receiver_id, userId);
      
      let singlechatId = null;
      if (!chatExists) {
        let conversationData = {
          sender_id: userId,
          receiver_id: receiver_id,
        }
        singlechatId = await Chat.addSingleChatMembers(conversationData);
      } else {
        singlechatId = chatExists;
      }
      muteSuccess = await Chat.updateSingleChatMembers(data, singlechatId);
    }
    if (!muteSuccess) {
      return res.send({ status: 0, message: "Error in mute notiification" });
    }

    res.send({ status: 1, message: "Notification settings updated successfully", phone_notif, email_notif });
  } catch (error) {
    console.error("Error fetching chat list:", error);
    res.send({ status: 0, message: "Server error" });
  }
};
const getNotificationStatus = async (req, res) => {

  try {
    const { conversationId, userId, conversation_type, receiver_id } = req.body;
    console.log('userId+++++++', req.body)

    if (!userId) {
      return res.send({ status: 0, message: "User ID is required." });
    }
    let userData = [];
    if (conversation_type == "group") {
      userData = await Chat.getConversationMembers(conversationId, userId);
    } else {
      userData = await Chat.singleChatMemberData(receiver_id, userId);

    }

    let phone_notif = userData?.phone_notif || 0;
    let email_notif = userData?.email_notif || 0;
    let user = await Admin.getUserById(userId)
    let alertStatus= user[0]?.alert_status;
    if(alertStatus===0){
      phone_notif = 1;
      email_notif = 1;
    }

    if (!userData) {
      return res.send({ status: 0, message: "Error in mute notiification" });
    }

    res.send({ status: 1, phone_notif, email_notif });
  } catch (error) {
    console.error("Error fetching chat list:", error);
    res.send({ status: 0, message: "Server error" });
  }
};

const sendWelcomeMessage = async ({ conversationId, createdBy }) => {
  try {
    const welcomeText = "🎉 A new group has been created! Welcome everyone — let the conversation begin!";
    const timestamp = moment().unix();

    // Create chat log
    const chatlogData = {
      name: welcomeText,
      conversation_id: conversationId,
      timestamp: timestamp
    };
    const chatLogId = await Chat.addChatLog(chatlogData);

    // Prepare message
    const messageData = {
      conversation_id: conversationId,
      chat_log_id: chatLogId,
      sender_id: createdBy,
      message: welcomeText,
      chat_log_msg: welcomeText,
      message_type: "text",
      attachment_url: null,
      conversation_type: 2,  //"group",
      created_at: timestamp
    };

    const messageId = await Chat.sendMessage(messageData);
    return messageId ? { status: 1, messageId } : { status: 0, message: "Failed to send welcome message" };
  } catch (error) {
    console.error("❌ Error sending welcome message:", error);
    return { status: 0, message: "Server error while sending welcome message", error };
  }
};


const createGroupChat = async (req, res) => {
  try {
    const { groupName, createdBy, members } = req.body;
    const created_at = moment().unix();
    if (!groupName || !createdBy || !Array.isArray(members) || members.length === 0) {
      return res.send({ status: 0, message: "Invalid input data" });
    }
    members.push(createdBy);
    const result = await Chat.createGroup(groupName, createdBy, members, created_at);

    if (result.status === 1) {
      await sendWelcomeMessage({ conversationId: result.conversationId, createdBy });
      res.send({ status: 1, message: "Group chat created successfully", conversationId: result.conversationId });
    } else {
      res.send({ status: 0, message: result.message });
    }
  } catch (error) {
    console.error("❌ Error creating group chat:", error);
    res.send({ status: 0, message: "Server error" });
  }
};

const changeGroupName = async (req, res) => {
  try {
    const { conversationId, newGroupName } = req.body;

    if (!conversationId || !newGroupName) {
      return res.send({ status: 0, message: "Missing required parameters." });
    }

    const updated = await Chat.updateGroupName(conversationId, newGroupName);

    if (updated) {
      res.send({ status: 1, message: "Group name updated successfully." });
    } else {
      res.send({ status: 0, message: "Failed to update group name." });
    }
  } catch (error) {
    console.error("❌ Error in changeGroupName:", error);
    res.send({ status: 500, error: "Internal Server Error" });
  }
};

const sendMessage = async (req, res) => {
  try {
    const { chatLogId, conversation_id, message, sender_id, message_type, attachment_url, conversationType } = req.body;

    let messageData = {
      conversation_id: conversation_id,
      chat_log_id: chatLogId,
      sender_id: sender_id,
      message: message,
      chat_log_msg: message,
      message_type: message_type,
      attachment_url: attachment_url,
      conversation_type: conversationType,
      created_at: moment().unix(),
    };

    if (!chatLogId) {
      const chatlogData = {
        name: message,
        conversation_id: conversation_id,
        timestamp: moment().unix()
      }
      const chatlogId = await Chat.addChatLog(chatlogData);
      messageData.chat_log_id = chatlogId;      
    }else{
     const chatlogData = {
        timestamp: moment().unix()
      }
      const chatlogId = await Chat.updateChatLog(chatlogData,chatLogId);

    }
    const messageId = await Chat.sendMessage(messageData);
    if (conversationType === 2) {
      let messageCountData = {
        conversation_id: conversation_id,
        message_id: messageId,
        read_status: 1,
      }

      await Chat.CreateReadMessage(messageCountData, sender_id)
    }
    if(!chatLogId)
      {
        if (conversationType === 2) {        
      let groupsData = await Chat.getConversationMembersData(conversation_id, sender_id);
      for (const groupData of groupsData) {
        try{
        if (groupData.alert_status===1&& groupData.phone_notif === 0 ) {
          let user = await Admin.getUserById(groupData.user_id);
          let senderData = await Admin.getUserById(sender_id);
          if (!user?.[0] || !senderData?.[0]) {
            console.warn(`Missing user or sender data for user_id ${groupData.user_id}`);
            continue;
          }
          const { first_name, last_name } = user[0];
          const senderFirstName = senderData[0].first_name;
          const PhoneNumber = await Admin.getPhoneNumber(user[0]);
          const Phone_country_code = await Admin.getCountryCodeNumber(user[0])
          const messageContents = 
`SignWise Solutions -

Hello ${first_name} ${last_name},

You have an new message in "${groupData.group_name}" from ${senderFirstName}`;


        
          if (PhoneNumber) {
             await sendMessageToPhoneNumber(PhoneNumber, messageContents,Phone_country_code)
          } else {
            console.warn(`No phone number found for user_id ${groupData.user_id}`);
          }
        }
        if (groupData.alert_status===1 && groupData.email_notif === 0) {
          let user = await Admin.getUserById(groupData.user_id);
          let senderData = await Admin.getUserById(sender_id);
          if (!user?.[0] || !senderData?.[0]) {
            console.warn(`Missing user or sender data for user_id ${groupData.user_id}`);
            continue;
          }
          const { first_name, last_name } = user[0];
          const senderFirstName = senderData[0].first_name;
          const email = user[0].email;
          const emailHtml = messageNotificationEmail({
            first_name: user[0].first_name,
            last_name: user[0].last_name,
            senderFirstName: senderData[0].first_name,
            isGroup: true, // true if group chat
            group_name: groupData.group_name || '',
            portalName: "SignWise Solutions",
          });
          const mailOptions = {
            to: email,
            from: '"SignWise Solutions" <noreply@signwisesolutions.com>',
            subject: `New Message from ${senderFirstName}`,
            // text: `You have a new message from ${senderFirstName} in "${groupData.group_name}". Please visit ${BASE_URL} to view it.`,
            text: `You have a new message from ${senderFirstName} in "${groupData.group_name}".`,
            html: emailHtml
          };
        
          try {
            if (SEND_EMAIL_MUTE) {
              const info = await transporter.sendMail(mailOptions);
              console.log(`✅ Email sent to ${email}: ${info.messageId}`);
            } else {
              console.log(`✉️ Email sending is disabled. Would have sent to: ${email}`);
            }
          } catch (error) {
            console.error(`❌ Failed to send email to ${email}:`, error);
          }
        }
      } catch (err) {
        console.error(`Error processing user_id ${groupData.user_id}:`, err);
      }
      }

    } else {
const messageMembersData = await Chat.singleChatMemberData(sender_id,conversation_id);
console.log('messageMembersData++++++++++++', messageMembersData)
let IsPhoneNotification = messageMembersData?.phone_notif || 0;
let IsEmailNotification = messageMembersData?.email_notif || 0;
let alertStatus = messageMembersData?.sender_alert_status || 1;
console.log('IsPhoneNotification', IsPhoneNotification,IsEmailNotification)

if (alertStatus===1 && IsPhoneNotification === 0) {
  let user = await Admin.getUserById(messageMembersData.sender_id);
  console.log('PhoneNumber+++++++', user)
  let senderData = await Admin.getUserById(sender_id);
  if (!user?.[0] || !senderData?.[0]) {
    console.warn(`Missing user or sender data for user_id ${messageMembersData.receiver_id}`);
    
  }
  const { first_name, last_name } = user[0];
  const senderFirstName = senderData[0].first_name + ' ' + senderData[0].last_name;
  const PhoneNumber = await Admin.getPhoneNumber(user[0]);
  const Phone_country_code = await Admin.getCountryCodeNumber(user[0])
  const messageContents = 
`SignWise Solutions -

Hello ${first_name} ${last_name},

You have an new message from ${senderFirstName}`;



  if (PhoneNumber) {
     await sendMessageToPhoneNumber(PhoneNumber, messageContents,Phone_country_code)
  } else {
    console.warn(`No phone number found for user_id ${messageMembersData.receiver_id}`);
  }
}
if (alertStatus===1 && IsEmailNotification === 0) {
  let user = await Admin.getUserById(messageMembersData.sender_id);
  let senderData = await Admin.getUserById(sender_id);
  if (!user?.[0] || !senderData?.[0]) {
    console.warn(`Missing user or sender data for user_id ${messageMembersData.sender_id}`);    
  }
  const { first_name, last_name } = user[0];
  const senderFirstName = senderData[0].first_name + ' ' + senderData[0].last_name;
  const email = user[0].email;
  const emailHtml = messageNotificationEmail({
    first_name: first_name,
    last_name: last_name,
    senderFirstName: senderFirstName,
    isGroup: false, // true if group chat
    group_name: '',
    portalName: "SignWise Solutions",
  });
  const mailOptions = {
    to: email,
    from: '"SignWise Solutions" <noreply@signwisesolutions.com>',
    subject: `New Message from ${senderFirstName}`,
    // text: `You have a new message from ${senderFirstName} in "${groupData.group_name}". Please visit ${BASE_URL} to view it.`,
    text: `You have a new message from ${senderFirstName}".`,
    html: emailHtml
  };

  try {
    if (SEND_EMAIL_MUTE) {
      const info = await transporter.sendMail(mailOptions);
      console.log(`✅ Email sent to ${email}: ${info.messageId}`);
    } else {
      console.log(`✉️ Email sending is disabled. Would have sent to: ${email}`);
    }
  } catch (error) {
    console.error(`❌ Failed to send email to ${email}:`, error);
  }
}
    }}
    // if(conversationType===2){await Chat.incrementNotifiCount(conversation_id,sender_id,1)}
    if (messageId) {

      res.send({ status: 1, message: `Message sent successfully`, messageId });
    } else {
      res.send({ status: 0, message: `failed to send message!` });
    }
  } catch (error) {
    res.send({ status: 500, message: 'Error sending message', error: error });
  }
};

const fetchMessages = async (req, res) => {
  try {
    const { conversationId, userId, conversationType, chatOpenTime, selectedChatLogId } = req.body;
    const messageResult = await Chat.fetchNewMessages(conversationId, userId, conversationType, chatOpenTime, selectedChatLogId);
    const historyMessageResult = await Chat.fetchMessages(conversationId, userId, conversationType, chatOpenTime);
    if (messageResult) {
      res.send({ status: 1, message: `Messages fetched successfully`, messageResult, historyMessageResult });
    } else {
      res.send({ status: 0, message: `failed to fetch messages!` });
    }
  } catch (error) {
    res.send({ status: 500, message: 'Error fetching messages', error: error });
  }
};

const editMessage = async (req, res) => {
  try {
    const { messageId, sender_id, message } = req.body;

    if (!messageId || !sender_id) {
      return res.send({ status: 0, message: "Invalid data!" });
    }

    const updated = await Chat.editMessage({
      messageId: Number(messageId),
      senderId: Number(sender_id),
      message: message ?? ''
    });

    if (updated) {
      res.send({ status: 1, message: "Message updated successfully" });
    } else {
      res.send({ status: 0, message: "Failed to update message" });
    }
  } catch (error) {
    res.send({ status: 500, message: "Error updating message", error: error });
  }
};

const updateChatStatus = async (req, res) => {
  try {
    let { userId, newStatus } = req.body
    let data = {}
    data['chat_status'] = newStatus;
    let update = await Admin.updateUser(userId, data);
    if (update) {
      res.send({ status: 1, message: 'Status updated successfully' });
    } else {
      res.send({ status: 0, message: 'Status not updated' });
    }
  } catch (error) {
    console.log('Error updateChatStatus : ', error);
    res.send({ status: 500, message: 'Error updating status' });
  }
}

const getChatStatusByUserId = async (req, res) => {
  try {
    let { userId } = req.body;
    let result = await Chat.getChatStatusByUserId(userId);
    if (result) {
      res.send({ status: 1, message: 'Status fetched successfully', result });
    } else {
      res.send({ status: 0, message: 'Status not found' });
    }
  } catch (error) {
    console.log('Error updateChatStatus : ', error);
    res.send({ status: 500, message: 'Error finding status' });
  }
}

const renameChatLog = async (req, res) => {
  try {
    const { chatLogId, chatTitle } = req.body;
    console.log('chatLogId--', chatLogId)
    console.log('chatTitle--', chatTitle)
    let updated = false;
    if (chatLogId) {
      const chatlogData = {
        name: chatTitle,
        timestamp: moment().unix()
      }
      updated = await Chat.updateChatLog(chatlogData, chatLogId);
    }

    if (updated) {
      res.send({ status: 1, message: `Chat log renamed successfully` });
    } else {
      res.send({ status: 0, message: `failed to rename chatlog!` });
    }
  } catch (error) {
    console.log('renameChatLog error : ', error);
    res.send({ status: 500, message: 'Error updating chatlog title', error: error });
  }
};

const deleteChatLog = async (req, res) => {
  try {
    const { chatLogId } = req.body;
    let deleted = await Chat.deleteChatLog(chatLogId);
    let messagesDeleted = await Chat.deleteMessagesByChatLogId(chatLogId);

    if (deleted) {
      res.send({ status: 1, message: `Chat log deleted successfully` });
    } else {
      res.send({ status: 0, message: `failed to deleted chatlog!` });
    }
  } catch (error) {
    console.log('deleteChatLog error : ', error);
    res.send({ status: 500, message: 'Error deleting chatlog', error: error });
  }
};

const exitGroup = async (req, res) => {
  try {
    const { conversationId, userId } = req.body;

    const isAvailable = await Chat.checkIfAnyOtherGroupAdminIsAvailable(conversationId, userId);
    if (!isAvailable) {
      return res.send({ status: 2, message: `You are the only admin. Assign another admin before leaving.` });
    }

    const removeMemberResult = await Chat.removeMemberFromGroup(conversationId, userId);

    if (removeMemberResult) {
      res.send({ status: 1, message: `You have successfully left the group.` });
    } else {
      res.send({ status: 0, message: `Unable to leave the group. Please try again.` });
    }
  } catch (error) {
    console.log('exitGroup error : ', error);
    res.send({ status: 500, message: 'An unexpected error occurred while leaving the group. Please try again later.', error: error });
  }
};

const toggleAdminStatus = async (req, res) => {
  try {
    const { conversationId, userId, isAdmin } = req.body;
    const updateData = {
      is_admin: (isAdmin == 0) ? 1 : 0
    };

    const userData = await Admin.getUserById(userId);
    const fullName = userData && userData.length > 0 ? `${userData[0].first_name || ''} ${userData[0].last_name || ''}`.trim() : 'User';

    if (isAdmin == 1) {
      const isAvailable = await Chat.checkIfAnyOtherGroupAdminIsAvailable(conversationId, userId);
      if (!isAvailable) {
        return res.send({ status: 2, message: `You are the only admin. Please assign another admin before stepping down.` });
      }
    }

    const updateResult = await Chat.updateConversationMembers(updateData, conversationId, userId);

    if (updateResult) {
      const message = !isAdmin ? `${fullName} is now an admin.` : `Admin privileges removed from ${fullName} successfully.`;
      res.send({ status: 1, message });
    } else {
      res.send({ status: 0, message: `Failed to update admin status.` });
    }
  } catch (error) {
    console.log('toggleAdminStatus error : ', error);
    res.send({ status: 500, message: 'An error occurred while updating admin status.', error: error });
  }
};

const removeMemberFromGroup = async (req, res) => {
  try {
    const { conversationId, userId, fullName } = req.body;

    const isAvailable = await Chat.checkIfAnyOtherGroupAdminIsAvailable(conversationId, userId);
    if (!isAvailable) {
      return res.send({ status: 2, message: `${fullName} is the only admin. Assign another admin before removing them.` });
    }

    const removeMemberResult = await Chat.removeMemberFromGroup(conversationId, userId);

    if (removeMemberResult) {
      res.send({ status: 1, message: `${fullName} has been removed from the group.` });
    } else {
      res.send({ status: 0, message: `Unable to remove ${fullName}. Please try again.` });
    }
  } catch (error) {
    console.log('Error removing member from group : ', error);
    res.send({ status: 500, message: 'An unexpected error occurred while trying to remove a member from the group. Please try again later.', error: error });
  }
};

const addMembersToGroup = async (req, res) => {
  try {
    const { conversationId, userId, selectedMembers } = req.body;

    const memberData = selectedMembers?.map((member) => ({
      conversation_id: conversationId,
      user_id: member?.user_id,
      added_at: moment().unix(),
      is_admin: 0
    }));

    const addMemberResult = await Chat.addMembersToGroup(memberData);

    if (addMemberResult) {
      res.send({ status: 1, message: `Members have been added to the group.` });
    } else {
      res.send({ status: 0, message: `Unable to add members. Please try again.` });
    }
  } catch (error) {
    console.log('Error adding members to group : ', error);
    res.send({ status: 500, message: 'Error adding members to the group. Please try again later.', error: error });
  }
};
const updateUserAlertStatus=async(req,res)=>{
  try{
  const {userId,status}=req.body;
  data={
    alert_status:status
  }
  let resp = Admin.updateUser(userId,data)
  if (resp) {
      res.send({ status: 1, message: `changed status` });
    } else {
      res.send({ status: 0, message: `Please try again.` });
    }
}catch(error){
   console.log('Error adding members to group : ', error);
    res.send({ status: 500, message: 'Error', error: error });
}
}
const getUserAlertStatus=async(req,res)=>{
  try{
    const {userId}=req.body;
  let data = await Admin.getUserById(userId)
  let alertStatus= data[0]?.alert_status
  if (data) {
      res.send({ status: 1, data:alertStatus });
    } else {
      res.send({ status: 0, message: `Please try again.` });
    }
}catch(error){
   console.log('Error adding members to group : ', error);
    res.send({ status: 500, message: 'Error', error: error });
}
}

module.exports = {
  addChat,
  getChatList,
  readChats,
  createGroupChat,
  changeGroupName,
  sendMessage,
  fetchMessages,
  editMessage,
  updateChatStatus,
  getChatStatusByUserId,
  renameChatLog,
  deleteChatLog,
  exitGroup,
  toggleAdminStatus,
  removeMemberFromGroup,
  addMembersToGroup,
  readMessages,
  muteNotification,
  getNotificationStatus,
  updateUserAlertStatus,
  getUserAlertStatus
};
