/* eslint-disable @typescript-eslint/no-explicit-any */
import PQueue from "p-queue";

let ports: chrome.runtime.Port[] = [];
const queue = new PQueue({ concurrency: 1 });
const targetUrl = "https://www.facebook.com/marketplace/you/selling";

chrome.runtime.onConnect.addListener((port) => {
  ports.push(port);
  port.onDisconnect.addListener(() => {
    ports = ports.filter((p) => p !== port);
  });
});

async function handlePublish(data: any, timeoutMs = 5 * 60 * 1000) {
  return new Promise<void>((resolve) => {
    chrome.tabs.create(
      { url: "https://www.facebook.com/marketplace/create/item", active: true },
      (tab) => {
        if (!tab?.id) return resolve();
        const tabId = tab.id;

        let resolved = false;
        const cleanup = () => {
          if (resolved) return;
          resolved = true;
          chrome.runtime.onConnect.removeListener(onConnectListener);
          chrome.tabs.onRemoved.removeListener(onTabClosed);
          clearTimeout(timeoutId);
          resolve();
          ensureMarketplaceSellingTab();
        };

        const onConnectListener = (port: chrome.runtime.Port) => {
          if (port.sender?.tab?.id === tabId) {
            port.postMessage({ type: "PUBLIST_EVENT", payload: data });
            chrome.runtime.onConnect.removeListener(onConnectListener);
          }
        };
        chrome.runtime.onConnect.addListener(onConnectListener);

        const onTabClosed = (closedTabId: number) => {
          if (closedTabId === tabId) {
            cleanup();
          }
        };
        chrome.tabs.onRemoved.addListener(onTabClosed);

        // Timeout tùy chỉnh
        const timeoutId = setTimeout(() => {
          console.warn(`Tab ${tabId} timeout (${timeoutMs}ms) - auto resolve`);
          if (tabId) chrome.tabs.remove(tabId);
          cleanup();
        }, timeoutMs);
      }
    );
  });
}

async function handleEdits(
  data: { prev: IItem; data: IItem },
  timeoutMs = 5 * 60 * 1000
) {
  return new Promise((resolve, reject) => {
    (async () => {
      try {
        if (!data.prev?.publist_id) {
          const response = await sendMessageToSellingTab<any>(
            { type: "GET_PUBLIST_ID", data },
            30000
          );

          console.log({ response });
          data.prev.publist_id = response.publist_id;
        }

        chrome.tabs.create(
          {
            url: `https://www.facebook.com/marketplace/edit/?listing_id=${data.prev.publist_id}`,
            active: true,
          },
          (tab) => {
            if (!tab?.id) resolve(data);
            const tabId = tab.id;

            let resolved = false;
            const cleanup = () => {
              if (resolved) return;
              resolved = true;
              chrome.runtime.onConnect.removeListener(onConnectListener);
              chrome.tabs.onRemoved.removeListener(onTabClosed);
              clearTimeout(timeoutId);
              resolve(data);
              ensureMarketplaceSellingTab();
            };

            const onConnectListener = (port: chrome.runtime.Port) => {
              if (port.sender?.tab?.id === tabId) {
                port.postMessage({ type: "EDIT_EVENT", payload: data });
                chrome.runtime.onConnect.removeListener(onConnectListener);
              }
            };
            chrome.runtime.onConnect.addListener(onConnectListener);

            const onTabClosed = (closedTabId: number) => {
              if (closedTabId === tabId) {
                cleanup();
              }
            };
            chrome.tabs.onRemoved.addListener(onTabClosed);

            // Timeout tùy chỉnh
            const timeoutId = setTimeout(() => {
              console.warn(
                `Tab ${tabId} timeout (${timeoutMs}ms) - auto resolve`
              );
              if (tabId) chrome.tabs.remove(tabId);
              cleanup();
            }, timeoutMs);
          }
        );
      } catch (err) {
        reject(err);
      }
    })();
  });
}

const handleListenPublists = () => {
  const evtSource = new EventSource(
    `${import.meta.env.VITE_API_URL}/products/publist-stream`
  );

  evtSource.onmessage = (event) => {
    const data = JSON.parse(event.data);
    console.log("[PUBLIST] New event:", data);
    queue.add(() => handlePublish(data, 30000));
  };

  evtSource.onerror = (err) => {
    console.error("EventSource failed:", err);
  };
};

function sendMessageToSellingTab<T = any>(
  message: any,
  timeoutMs = 10000
): Promise<T> {
  return new Promise((resolve, reject) => {
    chrome.tabs.query(
      { url: "*://www.facebook.com/marketplace/you/selling*" },
      (tabs) => {
        if (tabs.length > 0 && tabs[0].id !== undefined) {
          const tabId = tabs[0].id;

          const listener = (msg: any) => {
            if (msg?.type === "GET_PUBLIST_ID_DONE") {
              cleanup();
              resolve(msg);
            }
          };

          const cleanup = () => {
            chrome.runtime.onMessage.removeListener(listener);
            clearTimeout(timeoutId);
          };

          chrome.runtime.onMessage.addListener(listener);

          const timeoutId = setTimeout(() => {
            cleanup();
            reject(new Error("Timeout chờ phản hồi từ content script"));
          }, timeoutMs);

          chrome.tabs.sendMessage(tabId, message);
        } else {
          reject(new Error("Không tìm thấy tab Selling"));
        }
      }
    );
  });
}

const handleListenDeletes = () => {
  const evtSource = new EventSource(
    `${import.meta.env.VITE_API_URL}/products/delete-stream`
  );

  evtSource.onmessage = (event) => {
    try {
      const data = JSON.parse(event.data);
      console.log("[SSE] New event:", data);

      queue.add(() => {
        return new Promise<void>((resolve) => {
          const listener = (msg: any) => {
            if (msg?.type === "delete-done") {
              console.log("[QUEUE] Delete done signal received.");
              chrome.runtime.onMessage.removeListener(listener);
              resolve();
            }
          };
          chrome.runtime.onMessage.addListener(listener);

          // Gửi tới tab có URL khớp
          chrome.tabs.query(
            { url: "https://www.facebook.com/marketplace/you/selling" },
            (tabs) => {
              for (const tab of tabs) {
                if (tab.id) {
                  chrome.tabs.sendMessage(tab.id, {
                    type: "DELETE_STREAM_DATA",
                    payload: data,
                  });
                }
              }
            }
          );
        });
      });
    } catch (err) {
      console.error("[SSE] Parse error:", err);
    }
  };

  evtSource.onerror = (err) => {
    console.error("[SSE] Connection failed:", err);
  };

  console.log("[SSE] Listening for delete-stream events...");
};

const handleListenEdits = () => {
  const evtSource = new EventSource(
    `${import.meta.env.VITE_API_URL}/products/edit-stream`
  );

  evtSource.onmessage = (event) => {
    const data = JSON.parse(event.data) as any;
    console.log("[EDIT] New event:", data);
    queue.add(() => handleEdits(data, 30000));
  };

  evtSource.onerror = (err) => {
    console.error("EventSource failed:", err);
  };
};

function ensureMarketplaceSellingTab() {
  const targetUrl = "https://www.facebook.com/marketplace/you/selling";

  console.log({ targetUrl });
  chrome.tabs.query({}, (tabs) => {
    const existingTab = tabs.find(
      (tab) => tab.url && tab.url.startsWith(targetUrl)
    );

    if (existingTab) {
      // Nếu đã có thì refresh lại
      chrome.tabs.reload((existingTab as any).id);
    } else {
      // Nếu chưa có thì mở mới
      chrome.tabs.create({ url: targetUrl });
    }
  });
}

// Hàm check tab load xong
function waitForTargetTabLoad(): Promise<void> {
  return new Promise((resolve) => {
    // Query tab có url trước
    chrome.tabs.query({ url: targetUrl }, (tabs) => {
      if (tabs.length > 0 && tabs[0].status === "complete") {
        return resolve();
      }
    });

    // Nếu chưa load xong → lắng nghe sự kiện
    const listener = (tabId: number, changeInfo: any, tab: chrome.tabs.Tab) => {
      if (changeInfo.status === "complete" && tab.url === targetUrl) {
        chrome.tabs.onUpdated.removeListener(listener);
        resolve();
      }
    };

    chrome.tabs.onUpdated.addListener(listener);
  });
}

const init = async () => {
  handleListenPublists();
  handleListenDeletes();
  handleListenEdits();
  ensureMarketplaceSellingTab();
  createAlarm();
};

chrome.runtime.onMessage.addListener((message, sender) => {
  if (message.type === "close-tab") {
    const tabId = sender.tab?.id;
    if (tabId) chrome.tabs.remove(tabId);
  }
});

// Khởi tạo alarm (30–40 giây, random)
function createAlarm() {
  const delay = 30 + Math.floor(Math.random() * 11); // 30 → 40 giây
  chrome.alarms.create("checkQueue", { delayInMinutes: delay / 60 });
}

// Task reload extension (nằm trong queue)
async function reloadExtensionTask() {
  console.log("🔄 Reloading extension...");

  chrome.runtime.reload();
  // Sau khi reload, extension sẽ restart → task này chưa resolve.
  // => Đặt 1 flag trong storage để biết đang chờ tab load
  chrome.storage.local.set({ waitingForTab: true });
}

// Khi extension khởi động lại → check có đang chờ tab load không
chrome.runtime.onStartup.addListener(async () => {
  chrome.storage.local.get("waitingForTab", async (data) => {
    if (data.waitingForTab) {
      console.log("⏳ Extension restarted, waiting for target tab...");

      await waitForTargetTabLoad();

      console.log("✅ Target tab loaded → task done");
      chrome.storage.local.remove("waitingForTab");
    }
  });
});

// Alarm chạy định kỳ
chrome.alarms.onAlarm.addListener((alarm) => {
  if (alarm.name === "checkQueue") {
    console.log("Alarm triggered, checking queue...");

    const isIdle = queue.size === 0 && queue.pending === 0;

    if (isIdle) {
      console.log("Queue is empty → enqueue reload task");
      queue.add(reloadExtensionTask);
    } else {
      console.log("Queue still busy → skip reload");
    }

    // đặt lại alarm mới
    createAlarm();
  }
});

init();
