/* eslint-disable @typescript-eslint/no-explicit-any */
import { messageApi } from "@/api/message-api.service";

export class TeamsChatService {
  private readonly MY_NAME = "Apactech com";
  public lastMessage?: IMessage;
  public initialHistories: IMessage[] = [];

  public elTags = {
    container_scroll:
      "/html/body/div[1]/div/div/div/div[5]/div[1]/div[1]/div[2]/div[1]/div[1]/div",
    conatainer_conversations:
      "/html/body/div[1]/div/div/div/div[5]/div[1]/div[1]/div[2]/div[1]/div[1]/div/div[1]",
    container_chat: '[data-testid="message-wrapper"]',

    root_id: '[aria-selected="true"] [id^="chat-list-item"]',
    room_name: '[data-tid="chat-title"]',
    close_reply_btn:
      '[data-track-action-scenario="messageQuotedReplyDismissed"]',
    reply_btn: '[aria-label="Reply"]',
    chat_input: '[placeholder="Type a message"]',
  };

  private _getImageFormEl(el: HTMLElement): HTMLImageElement[] {
    // Tìm tất cả img có data-gallery-src trong el
    let sharedImages = Array.from(
      el.querySelectorAll("img[data-gallery-src]")
    ) as HTMLImageElement[];

    // Nếu không tìm thấy thì thử tìm trong parentElement
    if (sharedImages.length === 0 && el.parentElement) {
      sharedImages = Array.from(
        el.parentElement.querySelectorAll("img[data-gallery-src]")
      ) as HTMLImageElement[];
    }

    return sharedImages; // Luôn trả về array (có thể rỗng)
  }

  public getCurrentRoomInfo(): { room_id?: string; room_name?: string } {
    // const roomId = document
    //   .querySelector(this.elTags.root_id)
    //   ?.id?.split(":")[1];

    const roomId = document
      .querySelector(this.elTags.root_id)
      ?.id?.replace("chat-list-item_", "");

    const roomName = (
      document.querySelector(this.elTags.room_name) as HTMLElement
    )?.innerText;

    return { room_id: roomId, room_name: roomName };
  }

  _getFileLinks(el: HTMLElement) {
    const parentId = `attachments-${(el as any)?.date_time}`;

    const parent = document.getElementById(parentId);

    if (!parent) return [] as { name: string; url: string }[];

    // Lấy tất cả con trực tiếp
    const children = Array.from(parent.children);

    // Lấy title, lọc link và trả về {name, url}
    const results = children.flatMap((child) => {
      const token = this.getAssetToken();
      const title = child.getAttribute("title");
      if (!title) return [];

      // Giả sử format: "tên file \r\n link"
      const lines = title
        .split(/\r?\n/)
        .map((line) => line.trim())
        .filter(Boolean);
      const name = lines[0] || null;
      const urlMatch = lines.find((line) => /^https?:\/\//.test(line));
      if (!urlMatch) return [];

      return [{ name, url: urlMatch, token }];
    });

    return results;
  }

  // private _getMessageByEl(el: HTMLElement | null): string | string[] {
  //   if (!el) return "";

  //   // Lấy text ban đầu và loại bỏ khoảng trắng dư
  //   let message = el.innerText?.trim() || "";

  //   // Lấy danh sách ảnh (nếu có)
  //   const sharedImages = this._getImageFormEl(el) || [];

  //   if (sharedImages.length > 0) {
  //     const arrMessage = sharedImages.map(
  //       (img) => img.getAttribute("src") || ""
  //     );

  //     if (message.length > 0) {
  //       // Kiểm tra overlay
  //       const overlay = document
  //         .getElementById(`message-body-${(el as any)?.date_time}`)
  //         ?.querySelector('[data-tid="overlay-count-text"]');

  //       // Nếu overlay text === message gốc → chỉ trả về ảnh
  //       if (overlay && (overlay as HTMLElement).innerText === message) {
  //         return arrMessage;
  //       }

  //       // Nếu không, thêm message vào cuối
  //       arrMessage.push(message);
  //     }

  //     return arrMessage;
  //   }

  //   // Tìm tất cả emoji trong element
  //   const emojiImgs = Array.from(
  //     el.querySelectorAll("img[itemtype]")
  //   ) as HTMLImageElement[];

  //   const emojiAlts = emojiImgs
  //     .map((img) => img.getAttribute("alt") || "")
  //     .filter(Boolean);

  //   // Nếu có emoji thì nối vào message
  //   if (emojiAlts.length > 0) {
  //     message = `${message}${emojiAlts.join("")}`;
  //   }

  //   return message.trim();
  // }

  private _getMessageByEl(el: HTMLElement | null): string[] {
    if (!el) return [];

    const messages: string[] = [];

    // Lấy text ban đầu và loại bỏ khoảng trắng dư
    const messageText = el.innerText?.trim() || "";

    // Lấy danh sách ảnh (nếu có)
    const sharedImages = this._getImageFormEl(el) || [];

    const imageSrcs = sharedImages
      .map((img) => img.getAttribute("src"))
      .filter(Boolean) as string[];

    if (imageSrcs.length > 0) {
      // Kiểm tra overlay
      const overlay = document
        .getElementById(`message-body-${(el as any)?.date_time}`)
        ?.querySelector('[data-tid="overlay-count-text"]');

      if (overlay && (overlay as HTMLElement).innerText === messageText) {
        messages.push(...imageSrcs);
      } else {
        messages.push(...imageSrcs);
        if (messageText) messages.push(messageText);
      }
    } else if (messageText) {
      messages.push(messageText);
    }

    const fileLinks = this._getFileLinks(el) || [];

    if (fileLinks.length) {
      fileLinks.forEach((link) => {
        messages.push(JSON.stringify({ ...link, type: "file" }));
      });
    }

    // Lấy emoji
    const emojiImgs = Array.from(
      el.querySelectorAll("img[itemtype]")
    ) as HTMLImageElement[];
    const emojiAlts = emojiImgs
      .map((img) => img.getAttribute("alt") || "")
      .filter(Boolean);

    if (emojiAlts.length > 0) {
      messages.push(emojiAlts.join(""));
    }

    return messages;
  }

  public parseMessageElement(el: Element, isMine = false): IMessage | null {
    const timestampEl = el.querySelector(
      isMine ? ".fui-ChatMyMessage__timestamp" : ".fui-ChatMessage__timestamp"
    ) as HTMLElement | null;

    const authorEl = el.querySelector(
      isMine ? ".fui-ChatMyMessage__author" : ".fui-ChatMessage__author"
    ) as HTMLElement | null;

    if (!timestampEl) return null;

    const datetimeAttr = timestampEl.getAttribute("datetime");
    if (!datetimeAttr) return null;

    // const dateTime = new Date(datetimeAttr).getTime();
    const dateTime = Number.isNaN(timestampEl.id.replace("timestamp-", ""))
      ? new Date(datetimeAttr).getTime()
      : Number(timestampEl.id.replace("timestamp-", ""));

    const contentEl = document.querySelector(
      `#content-${dateTime}`
    ) as HTMLElement | null;

    (contentEl as any)["date_time"] = dateTime;

    const { room_id, room_name } = this.getCurrentRoomInfo();

    const isExitsOption = document
      .getElementById(`attachments-${dateTime}`)
      ?.querySelector('[aria-label="More attachment options"]');

    console.log({ isExitsOption });

    if (isExitsOption) {
      (isExitsOption as any)?.click();
    }

    return {
      name: authorEl?.innerText,
      message: this._getMessageByEl(contentEl),
      time: dateTime,
      room_id,
      room_name,
      date_time: new Date(datetimeAttr).getTime(),
    };
  }

  getAssetToken() {
    const tokenKey = Object.keys(localStorage).find((key) => {
      const value = localStorage[key];
      return (
        value.includes('"credentialType":"AccessToken"') &&
        value.includes('"target":"https://graph.microsoft.com/.default')
      );
    });

    const accessToken = tokenKey
      ? JSON.parse(localStorage[tokenKey]).secret
      : null;

    return accessToken;
  }

  extractAllMessages(): IMessage[] {
    const myMessages: IMessage[] = Array.from(
      document.querySelectorAll(".fui-ChatMyMessage")
    )
      .map((el) => this.parseMessageElement(el, true))
      .filter((msg): msg is IMessage => msg !== null);

    const otherMessages: IMessage[] = Array.from(
      document.querySelectorAll(".fui-ChatMessage")
    )
      .map((el) => this.parseMessageElement(el, false))
      .filter((msg): msg is IMessage => msg !== null);

    console.log({ myMessages, otherMessages });
    return [...myMessages, ...otherMessages].sort((a, b) => a.time - b.time);
  }

  // private handleNewMessage(message: IMessage) {
  //   // Gửi tới một server AI để phản hồi (nếu cần)
  //   // fetch('https://127.0.0.1:8443/reply', { ... })
  //   console.log("%c[New incoming message]", "color: #007acc;", message);
  // }

  public async detectNewMessages() {
    const allMessages = this.extractAllMessages();

    const lastIndex = allMessages.findIndex(
      (msg) => msg.time === this.lastMessage?.time
    );

    const newMessages = allMessages.slice(lastIndex + 1);
    if (newMessages.length === 0) {
      console.log("[Monitor] No new messages...");
      return;
    }

    const newMsg = newMessages[0];

    // if (newMsg.name === this.MY_NAME) {
    //   console.log("[Monitor] My new message:", newMsg);
    //   await messageApi.sendSingleMessage(newMsg);
    // } else {
    //   console.log("[Monitor] New incoming message:", newMsg);
    //   this.handleNewMessage(newMsg);
    //   messageApi.sendSingleMessage(newMsg);
    // }

    this.lastMessage = allMessages.pop();

    return newMsg;
  }

  public async start(interval = 10000) {
    console.log("[Monitor] Starting...");
    this.initialHistories = this.extractAllMessages();
    this.lastMessage = this.initialHistories.pop();

    // await messageApi.sendBulkMessages(this.initialHistories);
    setInterval(async () => await this.detectNewMessages(), interval);
  }

  private async _getConversationsInfo(
    xpath: string = this.elTags.conatainer_conversations
  ): Promise<ChatItem[]> {
    const result = document.evaluate(
      xpath,
      document,
      null,
      XPathResult.FIRST_ORDERED_NODE_TYPE,
      null
    ).singleNodeValue as HTMLElement | null;

    if (!result) {
      console.log("Không tìm thấy phần tử theo XPath.");
      messageApi.sendLog({
        type: "error",
        message: `Not found selector: ${xpath}`,
      });
      return [];
    }

    // Lọc phần tử con có role="none"
    const matchedChildren = Array.from(result.children).filter(
      (child: Element) => {
        return child.getAttribute("role") === "none";
      }
    );

    const data: ChatItem[] = matchedChildren.map((child: Element): ChatItem => {
      const id = child.id || null;
      const titleId = `title-chat-list-item_${id}`;
      const titleElement = document.getElementById(titleId);
      const spanText = titleElement?.innerText || null;

      let type: ChatItemType = null;

      if (id?.includes("@thread.skype")) {
        type = "group";
      } else if (id?.includes("@oneToOne.skype")) {
        type = "personal";
      } else {
        type = "group";
      }

      return {
        id,
        name: spanText,
        type,
      };
    });

    return data;
  }

  public async _scrollToBottomByXPath(
    xpath: string = this.elTags.container_scroll,
    options?: {
      maxStableRounds?: number; // Số vòng scroll không thay đổi trước khi dừng
      delay?: number; // Thời gian chờ giữa mỗi lần scroll (ms)
      maxScrolls?: number; // Giới hạn số lần scroll tối đa
    }
  ): Promise<void> {
    const {
      maxStableRounds = 5,
      delay = 300,
      maxScrolls = 100,
    } = options || {};

    const container = document.evaluate(
      xpath,
      document,
      null,
      XPathResult.FIRST_ORDERED_NODE_TYPE,
      null
    ).singleNodeValue as HTMLElement | null;

    if (!container) {
      console.warn("❌ Không tìm thấy phần tử với XPath:", xpath);
      messageApi.sendLog({
        type: "error",
        message: `Not found selector: ${xpath}`,
      });
      return;
    }

    return new Promise<void>((resolve) => {
      let lastHeight = -1;
      let stableCount = 0;
      let scrolls = 0;

      const interval = setInterval(() => {
        const currentHeight = container.scrollHeight;
        container.scrollTop = currentHeight;

        if (currentHeight === lastHeight) {
          stableCount++;
        } else {
          stableCount = 0;
          lastHeight = currentHeight;
        }

        scrolls++;

        if (stableCount >= maxStableRounds || scrolls >= maxScrolls) {
          clearInterval(interval);
          resolve();
        }
      }, delay);
    });
  }

  async handleGetConversations() {
    await this._scrollToBottomByXPath();
    return this._getConversationsInfo();
  }
}
