/* eslint-disable @typescript-eslint/no-unused-vars */
/* eslint-disable @typescript-eslint/no-explicit-any */
import { queue } from "@/lib/queue";
import { TeamsChatService } from "./teams-chat.service";
import { EVENTS } from "@/lib/event";
import { typeingService } from "./typing.service";
import { delay } from "@/features/app";
import { messageApi } from "@/api/message-api.service";
import { conversationApi } from "@/api/conversation-api.service";

export class ContentService {
  service: TeamsChatService;
  port;
  constructor(port: any) {
    this.service = new TeamsChatService();
    this.port = port;
  }
  _forceHeightObserver: any;

  getElementByXPath(xpath: string) {
    return document.evaluate(
      xpath,
      document,
      null,
      XPathResult.FIRST_ORDERED_NODE_TYPE,
      null
    ).singleNodeValue;
  }

  forceHeight(el: HTMLElement, height = "100px") {
    if (!el) return;

    el.style.setProperty("height", height, "important");

    // Gỡ bỏ auto-resize (nếu là textarea)
    el.style.setProperty("resize", "none", "important");

    // Lặp lại khi element bị focus/input
    const keepHeight = () => {
      el.style.setProperty("height", height, "important");
    };

    el.addEventListener("focus", keepHeight);
    el.addEventListener("input", keepHeight);
    el.addEventListener("blur", keepHeight);

    // Thêm mutation observer nếu bị script khác chỉnh sửa
    const observer = new MutationObserver(() => {
      el.style.setProperty("height", height, "important");
    });

    observer.observe(el, {
      attributes: true,
      attributeFilter: ["style"],
    });

    // Lưu lại để debug nếu cần
    this._forceHeightObserver = observer;
  }

  private _clickToConversation(id: string) {
    const el = document.getElementById(`chat-list-item_${id}`);

    if (el) {
      el.scrollIntoView({
        behavior: "smooth", // hoặc "auto"
        block: "center", // cuộn sao cho phần tử nằm giữa view
      });

      // Đợi 1 chút cho scroll xong (nếu cần)
      setTimeout(() => el.click(), 200); // delay 200ms là đủ mượt
    }
    return el?.click();
  }

  private async _waitForMessagesToAppear(
    timeoutMs = 10000
  ): Promise<HTMLElement[]> {
    return new Promise((resolve, reject) => {
      const chatPaneList = document.getElementById("chat-pane-list");
      let timeout: any = null;
      if (!chatPaneList) {
        return reject(new Error("#chat-pane-list not found"));
      }

      const getChildren = () =>
        Array.from(chatPaneList.children) as HTMLElement[];

      const checkAndResolve = () => {
        const children = getChildren();
        if (children.length > 0) {
          observer.disconnect();
          if (timeout) clearTimeout(timeout);
          resolve(children);
        }
      };

      const observer = new MutationObserver(() => {
        checkAndResolve();
      });

      observer.observe(chatPaneList, {
        childList: true,
        subtree: true,
      });

      // Kiểm tra ngay lập tức nếu đã có sẵn item
      checkAndResolve();

      timeout = setTimeout(() => {
        observer.disconnect();
        reject(new Error("Timeout waiting for chat messages to appear"));
      }, timeoutMs);
    });
  }

  private async _waitForNewMessages(
    existingItems: HTMLElement[],
    timeoutMs = 10000
  ): Promise<HTMLElement[]> {
    return new Promise((resolve, reject) => {
      const chatPaneList = document.getElementById("chat-pane-list");

      if (!chatPaneList) {
        return reject(new Error("#chat-pane-list not found"));
      }

      const getChildren = () =>
        Array.from(chatPaneList.children) as HTMLElement[];

      const existingSet = new Set(existingItems);

      let timeoutHandle: any = null;

      const observer = new MutationObserver(() => {
        const currentChildren = getChildren();
        const newItems = currentChildren.filter((el) => !existingSet.has(el));

        if (newItems.length > 0) {
          observer.disconnect();
          if (timeoutHandle) clearTimeout(timeoutHandle);
          resolve(newItems);
        }
      });

      observer.observe(chatPaneList, {
        childList: true,
        subtree: true,
      });

      timeoutHandle = setTimeout(() => {
        observer.disconnect();
        reject(new Error("Timeout waiting for new messages"));
      }, timeoutMs);
    });
  }

  private async _waitToloadMessages(stableTime = 300): Promise<any> {
    return new Promise((resolve) => {
      const chatPaneList = document.getElementById("chat-pane-list");

      if (!chatPaneList) {
        throw new Error("#chat-pane-list not found");
      }

      let timeout: NodeJS.Timeout | null = null;
      let lastChildren: HTMLElement[] = [];

      const observer = new MutationObserver(() => {
        // Reset lại mỗi khi có thay đổi
        if (timeout) clearTimeout(timeout);

        // Cập nhật danh sách item mới nhất
        lastChildren = Array.from(chatPaneList.children) as HTMLElement[];

        timeout = setTimeout(() => {
          observer.disconnect(); // Khi không có thay đổi trong khoảng stableTime
          resolve(lastChildren);
        }, stableTime);
      });

      // Quan sát cả subtree nếu có nested thay đổi
      observer.observe(chatPaneList, {
        childList: true,
        subtree: true,
        attributes: true,
        characterData: true,
      });
    });
  }

  private _getTypeGeo() {
    const el = document.querySelector(".ck-placeholder");

    if (el) {
      const rect = el.getBoundingClientRect();

      return {
        top: rect.top,
        left: rect.left,
        right: rect.right,
        bottom: rect.bottom,
        width: rect.width,
        height: rect.height,
      };
    }

    return null;
  }

  private async _rightClickMessage(date_time: number) {
    const selector = this.service.elTags.container_chat;
    const itemId = `content-${date_time}`;

    const maxScrollAttempts = 30;
    const scrollStep = 200;
    let attempts = 0;

    let wrapper = document.querySelector(selector);
    if (!wrapper) {
      console.error("Wrapper not found:", selector);
      await messageApi.sendLog({
        type: "error",
        message: `Not found selector: ${selector}`,
      });
      return;
    }

    let element = document.querySelector<HTMLElement>(`#${itemId}`);

    while (!element && attempts < maxScrollAttempts) {
      const scrollContainer = wrapper;
      const prevScrollTop = scrollContainer.scrollTop;

      scrollContainer.scrollTop = Math.max(
        0,
        scrollContainer.scrollTop - scrollStep
      );
      await delay(200); // Đợi scroll và DOM render lại

      wrapper = document.querySelector(selector);
      if (!wrapper) break;

      element = wrapper.querySelector<HTMLElement>(`#${itemId}`);

      if (scrollContainer.scrollTop === prevScrollTop) break;

      attempts++;
    }

    if (!element) {
      console.log({ element });
      console.error("Không tìm thấy phần tử:", itemId);
      return;
    }

    // Scroll phần tử vào giữa màn hình
    element.scrollIntoView({ behavior: "auto", block: "center" });
    await delay(100); // Đợi scroll

    const rect = element.getBoundingClientRect();
    const event = new MouseEvent("contextmenu", {
      bubbles: true,
      cancelable: true,
      view: window,
      button: 2,
      buttons: 2,
      clientX: rect.left + rect.width / 2,
      clientY: rect.top + rect.height / 2,
    });

    element.dispatchEvent(event);
  }

  private _clickIfExists(selector: string): Promise<boolean> {
    return new Promise((resolve) => {
      const element = document.querySelector(selector);

      if (element) {
        element.scrollIntoView({ behavior: "auto", block: "center" });
        setTimeout(() => {
          (element as any)?.click();
          resolve(true);
        }, 100); // Đợi scroll một chút rồi click
      } else {
        console.warn("Không tìm thấy phần tử:", selector);
        resolve(false);
      }
    });
  }

  async getConversations(_?: IMsg<any>) {
    queue.add(async () => {
      console.log("[Queue] Handling GET_CONVERSATIONS");

      const data = await this.service.handleGetConversations();

      // Gửi dữ liệu ngược về background
      this.port.postMessage({
        type: "socket-response",
        event: EVENTS.RECEIVE_CONVERSATIONS,
        data,
      } as IMsg<any>);
    });
  }

  async getConversation(msg: IMsg<{ id: string }>) {
    queue.add(async () => {
      console.log("[Queue] Handling GET_CONVERSATION");

      if (!msg.data?.id) return;

      const { room_id } = this.service.getCurrentRoomInfo();

      // Nếu đang active room thì không cần chờ load
      if (room_id != msg.data.id) {
        this._clickToConversation(msg.data.id);

        await this._waitForMessagesToAppear();
        await this._waitToloadMessages();
      }

      const data = this.service.extractAllMessages();

      this.port.postMessage({
        type: "socket-response",
        event: EVENTS.RECEIVE_CONVERSATION,
        data,
      } as IMsg<any>);
    });
  }

  async sendMessage({
    data: { conversation_id, message },
  }: IMsg<{ conversation_id: string; message: string }>) {
    queue.add(async () => {
      console.log("[Queue] Handling SEND_MESSAGE");

      const { room_id } = this.service.getCurrentRoomInfo();

      // Nếu đang active room thì không cần chờ load
      if (room_id != conversation_id) {
        this._clickToConversation(conversation_id);
      }

      await delay(200);

      await typeingService.send(message);

      // // Sroll xuống
      // this.service._scrollToBottomByXPath();

      // const initialMessages = await this._waitForMessagesToAppear(3000); // Đợi có item đầu tiên
      // console.log("Initial messages:", initialMessages);

      // const newMessages = await this._waitForNewMessages(initialMessages, 3000);
      // console.log("New messages appeared:", newMessages);

      // await this._waitToloadMessages();

      // // Lấy hết message mới nhất
      // const data = this.service.extractAllMessages();

      // // Gửi lên server cập nhật
      // this.port.postMessage({
      //   type: "socket-response",
      //   event: EVENTS.RECEIVE_CONVERSATION,
      //   data,
      // } as IMsg<any>);
    });
  }

  async replyMessage({
    data: { conversation_id, message, time },
  }: IMsg<{ conversation_id: string; message: string; time: number }>) {
    queue.add(async () => {
      console.log("[Queue] Handling REPLY_MESSAGE");

      let initialMessages = null;
      const { room_id } = this.service.getCurrentRoomInfo();

      // Nếu đang active room thì không cần chờ load
      if (room_id != conversation_id) {
        this._clickToConversation(conversation_id);

        initialMessages = await this._waitForMessagesToAppear(); // Đợi có item đầu tiên
        await this._waitToloadMessages();
      }

      await this._clickIfExists(this.service.elTags.close_reply_btn);

      await this._rightClickMessage(time);

      const replyBtn: any = document.querySelector(
        this.service.elTags.reply_btn
      );

      if (replyBtn) {
        replyBtn.click();
      }

      await delay(200);

      console.log({ message });

      await typeingService.send(message);
    });
  }

  fixedHeightChatInput(retry = 20, interval = 2000) {
    const tryFind = () => {
      const el = document.querySelector(
        this.service.elTags.chat_input
      ) as HTMLElement;

      if (el) {
        this.forceHeight(el, "100px");
        console.log("✔ Fixed height applied to chat input");
      } else if (retry > 0) {
        setTimeout(
          () => this.fixedHeightChatInput(retry - 1, interval),
          interval
        );
      } else {
        console.warn("✘ Element not found with provided XPath after retries");
        messageApi.sendLog({
          type: "error",
          message: `Not found selector: ${this.service.elTags.chat_input}`,
        });
      }
    };

    tryFind();
  }

  async detectNewMessage(interval = 2000) {
    console.log("[Monitor] Starting...");

    // Lưu lịch sử ban đầu
    this.service.initialHistories = this.service.extractAllMessages();
    this.service.lastMessage = this.service.initialHistories.pop();

    setInterval(() => {
      queue.add(async () => {
        try {
          const currentRoom = this.service.getCurrentRoomInfo();

          // Lấy attribute aria-labelledby
          const ariaValue = document
            .querySelector(
              '[aria-labelledby^="cn-normal-notification-main-content-"]'
            )
            ?.getAttribute("aria-labelledby");

          // **CASE 1: Không có popup notification**
          if (!ariaValue) {
            const newCurrentMessage = await this.service.detectNewMessages();

            if (!newCurrentMessage) {
              console.log("[Monitor] No new message...");
              return;
            }

            if (currentRoom.room_id !== newCurrentMessage?.room_id) {
              console.log("[Monitor] Message from another room → skip");
              return;
            }

            console.log("[Monitor] Found new message:", newCurrentMessage);
            await this._sendLastMessage(newCurrentMessage);
            return;
          }

          // **CASE 2: Có popup → cần click để sync**
          const roomId = ariaValue
            .split(" ")[0]
            .replace("cn-normal-notification-main-content-", "");

          if (!roomId) {
            console.warn(
              "[Monitor] Could not extract room_id from aria-labelledby"
            );
            return;
          }

          console.log("[Monitor] Notification detected:", {
            roomId,
            ariaValue,
          });

          // Click vào conversation và xử lý
          this._clickToConversation(roomId);
          await delay(2000); // chờ load messages

          const allMessages = this.service.extractAllMessages();
          const lastMessage = allMessages.at(-1);

          if (!lastMessage) {
            console.log("[Queue] No last message found after sync");
            return;
          }

          console.log("[Queue] Sending last message:", lastMessage);
          await this._sendLastMessage(lastMessage);
        } catch (error) {
          console.error("[Monitor] Error detecting new message:", error);
        }
      });
    }, interval);
  }

  // Helper gửi tin nhắn cuối cùng
  async _sendLastMessage(message: IMessage) {
    try {
      await messageApi.sendSingleMessage(message);
      console.log("[API] Sent message successfully:", message);
    } catch (err) {
      console.error("[API] Failed to send message:", err);
    }
  }

  startSyncConversations() {
    // Tạo namespace nếu chưa tồn tại
    (window as any)._chatIntervals = (window as any)?._chatIntervals || {};

    // Kiểm tra xem interval đã tồn tại chưa
    if (!(window as any)._chatIntervals.syncConversations) {
      (window as any)._chatIntervals.syncConversations = window.setInterval(
        () => {
          this.getConversations();
        },
        120000
      );
      console.log("✅ startSyncConversations running");
    } else {
      console.log("ℹ️ startSyncConversations already running");
    }
  }

  // Interval chạy, chỉ add task vào queue
  autoSyncConversationPrefixMessages() {
    (window as any)._chatIntervals = (window as any)?._chatIntervals || {};

    if (!(window as any)._chatIntervals.syncPrefixMessages) {
      (window as any)._chatIntervals.syncPrefixMessages = (
        window as any
      ).setInterval(() => {
        queue.add(async () => {
          try {
            const { data } =
              (await conversationApi.getConversationByPrefix()) as {
                data: ChatItem[];
              };

            if (!data) return;

            for (const chat of data) {
              this._clickToConversation(chat.id as string);

              await delay(5000);

              const currentRoom = this.service.getCurrentRoomInfo();

              if (!currentRoom || currentRoom.room_id !== chat.id) return;

              const messages = this.service.extractAllMessages();

              await messageApi.createAndSendToZulip(messages);

              await delay(5000);
            }
          } catch (err) {
            console.error(
              "❌ autoSyncConversationPrefixMessages error:",
              (err as any)?.message
            );
            messageApi.sendLog({
              type: "error",
              message: `auto_to_sync_conersations: ${(err as any)?.message}`,
            });
          }
        });
      }, 40000);

      console.log("✅ autoSyncConversationPrefixMessages running with PQueue");
    } else {
      console.log("ℹ️ autoSyncConversationPrefixMessages already running");
    }
  }
}
