// content.ts
import { productApi } from "@/api/product-api.service";
import { delayRD } from "@/features/app";
import { Contants } from "@/lib/contants";
import { Queue } from "@/lib/queue";
import type { IPost } from "@/lib/utils";
import { facebookService } from "@/services/facebook.service";
import MessageService from "@/services/message.service";
import { thiefService } from "@/services/thief.service";
const msgService = new MessageService("content");
export type ToastType = "success" | "error" | "info" | "warning" | "loading";

export type Noti = { title: string; message: string; type: ToastType };

const pushNoti = async (data: Noti) => {
  await (window as any).QUEUE.enqueue(data);
};

const injectApp = () => {
  const id = Contants.ID_EXTENSION;
  if (document.getElementById(id)) return;

  const root = document.createElement("div");
  root.id = id;
  document.body.appendChild(root);

  // inject script
  const script = document.createElement("script");
  script.src = chrome.runtime.getURL("content/inject-ui.js");
  script.type = "module";
  document.body.appendChild(script);

  // inject css
  const style = document.createElement("link");
  style.rel = "stylesheet";
  style.type = "text/css";
  style.href = chrome.runtime.getURL("assets/style.css");
  document.head.prepend(style);
};

// Nhận từ background [publist]
msgService.on<{ data: IPost }>(
  "background-to-content-publish",
  async (payload) => {
    try {
      console.log("[publish] Content nhận:", payload);

      await delayRD(800, 1000);

      await facebookService.handlePublist(payload.data);

      pushNoti({
        title: "Publist Completed !",
        message: "Please review",
        type: "success",
      });
    } catch (error) {
      console.log({ error });
      pushNoti({
        title: `Publist Error - ${payload.data.title || "Unknow"}`,
        message: (error as any)?.message,
        type: "error",
      });
    } finally {
      // Gửi ngược lại bacground
      msgService.send("background", "content-to-background-publish", {
        msg: payload,
      });
    }
  }
);

// Nhận từ background [unlist]
msgService.on<{ data: IPost }>(
  "background-to-content-unlist",
  async (payload) => {
    try {
      console.log("[unlist] Content nhận:", payload);

      await delayRD(800, 1000);

      await facebookService.gotoSell();

      await delayRD(800, 1000);

      await facebookService.handleDelete(payload.data);

      await delayRD(800, 1000);

      const products = await facebookService.getProducts();

      await delayRD(800, 1000);

      await productApi.sync(products);

      pushNoti({
        title: "Unlist Completed !",
        message: "Please review",
        type: "success",
      });
    } catch (error) {
      console.log({ error });
      pushNoti({
        title: `Unlist Error - ${payload.data.title || ""}`,
        message: (error as any)?.message,
        type: "error",
      });
    } finally {
      console.log("Send su kien da unlist");
      // Gửi ngược lại bacground
      msgService.send("background", "content-to-background-unlist", {
        msg: payload,
      });
    }
  }
);

// Nhận từ background [re-publist]
msgService.on<{ data: IPost }>(
  "background-to-content-re-publist",
  async (payload) => {
    try {
      console.log("[re-publist] Content nhận:", payload);

      await delayRD(800, 1000);

      await facebookService.gotoSell();

      await delayRD(800, 1000);

      await facebookService.handleRePublist(payload.data);
    } catch (error) {
      console.log({ error });
      pushNoti({
        title: "Re-Publist Error",
        message: (error as any)?.message,
        type: "error",
      });
    } finally {
      // Gửi ngược lại bacground
      msgService.send("background", "content-to-background-re-publist", {
        msg: payload,
      });
    }
  }
);

window.addEventListener("message", async (event) => {
  if (event.source !== window) return;

  if (event.data.type === "API_REQUEST") {
    const body = event.data.payload;
    const fn = event.data.fn;
    const { requestId } = event.data;

    try {
      let data = null;

      switch (fn) {
        case "index": {
          const info = await facebookService.getInfo();

          const response = await productApi.index({ info, ...body });
          data = response.data;
          break;
        }
        case "getPublistedProducts": {
          const response = await productApi.getPublistedProducts();
          data = response.data;
          break;
        }
        case "get": {
          const response = await productApi.get(body);
          data = response.data;

          console.log({ data, body });

          break;
        }
        case "createBlobUrl": {
          msgService.send(
            "background",
            "content-to-background-create-blod-urls",
            body
          );

          data = await msgService.waitForMessage(
            "background-to-content-create-blod-urls"
          );

          break;
        }
        case "publist": {
          msgService.send("background", "content-to-background-actions", {
            type: "publist",
            data: body,
          });

          data = await msgService.waitForMessage(
            "background-to-content-actions"
          );

          break;
        }

        case "unlist": {
          msgService.send("background", "content-to-background-actions", {
            type: "unlist",
            data: body,
          });

          data = await msgService.waitForMessage(
            "background-to-content-actions"
          );

          break;
        }
        case "sync": {
          const el = await thiefService.waitForElement(
            facebookService.selectors.collection_marketplace
          );
          console.log("Element đã xuất hiện:", el);

          await facebookService.waitForPageReady(
            facebookService.sellingPath,
            facebookService.selectors.collection_marketplace
          );

          await delayRD(800, 1000);

          const products = await facebookService.getProducts();

          await productApi.sync(products);

          break;
        }
        case "dequeue": {
          data = await (window as any).QUEUE.dequeue();

          break;
        }

        case "getProductLocalServer": {
          const response = await productApi.getProductOnLocalServer(body);
          data = response.data;

          console.log({ data, body });

          break;
        }

        case "saveProductLocalServer": {
          const response = await productApi.saveProductOnLocalServer(body);
          data = response.data;

          console.log({ data, body });

          break;
        }
      }

      window.postMessage(
        {
          type: "API_RESPONSE",
          requestId,
          payload: data,
        },
        "*"
      );
    } catch (error) {
      window.postMessage(
        {
          type: "API_RESPONSE",
          requestId,
          error: (error as any).message,
        },
        "*"
      );
    }
  }
});

const runSync = () => {
  let errorCount = 0; // đếm số lần lỗi liên tiếp
  const maxErrors = 3;

  const interval = setInterval(async () => {
    if (!window.location.href.includes(facebookService.sellingPath)) return;

    try {
      const products = await facebookService.getProducts();
      await productApi.sync(products);

      // reset nếu chạy thành công
      errorCount = 0;
    } catch (err) {
      errorCount++;
      console.error("Sync error:", err);

      if (errorCount >= maxErrors) {
        clearInterval(interval); // dừng interval nếu lỗi quá 3 lần

        pushNoti({
          title: "Sync Error",
          message: (err as any).message,
          type: "error",
        });
      }
    }
  }, 10000); // 10 giây
};

(async () => {
  (window as any).QUEUE = await Queue.create<{
    message: string;
    type: string;
  }>();

  await facebookService.getInfo();

  // tiện ích khởi chạy sync + app
  const startApp = () => {
    runSync();
    injectApp();
  };

  if (window.location.href.includes(facebookService.sellingPath)) {
    try {
      await delayRD(800, 1000);

      const el = await thiefService.waitForElement(
        facebookService.selectors.collection_marketplace
      );
      console.log("Element đã xuất hiện:", el);

      await delayRD(800, 1000);
    } catch (err) {
      console.error(err);
    }
  }

  startApp();
})();
