/* eslint-disable @typescript-eslint/no-explicit-any */
// content.ts
import { productApi } from "./api/product-api.service";
import { delay } from "./features/app";
import axios from "./lib/axios";
import { thiefService } from "./services/thief.service";
const selectors = {
  file__image_input: 'input[type="file"]',
  title_input:
    "/html/body/div[1]/div/div[1]/div/div[3]/div/div/div[1]/div[1]/div[1]/div/div[2]/div[1]/div[2]/div/div/div[5]/div/div/div/label/div/input",
  price_input:
    "/html/body/div[1]/div/div[1]/div/div[3]/div/div/div[1]/div[1]/div[1]/div/div[3]/div[1]/div[2]/div/div/div[6]/div/div/div/label/div/input",
  brand_input:
    "/html/body/div[1]/div/div[1]/div/div[3]/div/div/div[1]/div[1]/div[1]/div/div[3]/div[1]/div[2]/div/div/div[9]/div/div/div[2]/div/div/div/label/div/input",
  brand_input_fallback:
    "/html/body/div[1]/div/div[1]/div/div[3]/div/div/div[1]/div[1]/div[1]/div/div[3]/div[1]/div[2]/div/div/div[10]/div/div/div[2]/div/div/div/label/div/input",
  description_input:
    "/html/body/div[1]/div/div[1]/div/div[3]/div/div/div[1]/div[1]/div[1]/div/div[3]/div[1]/div[2]/div/div/div[9]/div/div/div[3]/div/div/div/label/div/div/textarea",
  description_input_falback:
    "/html/body/div[1]/div/div[1]/div/div[3]/div/div/div[1]/div[1]/div[1]/div/div[3]/div[1]/div[2]/div/div/div[10]/div/div/div[3]/div/div/div/label/div/div/textarea",
  sku_input:
    "/html/body/div[1]/div/div[1]/div/div[3]/div/div/div[1]/div[1]/div[1]/div/div[3]/div[1]/div[2]/div/div/div[9]/div/div/div[6]/div/div/div[1]/label/div/input",
  sku_input_fallback:
    "/html/body/div[1]/div/div[1]/div/div[3]/div/div/div[1]/div[1]/div[1]/div/div[3]/div[1]/div[2]/div/div/div[10]/div/div/div[6]/div/div/div[1]/label/div/input",
  category_select: {
    wraper:
      "/html/body/div[1]/div/div[1]/div/div[3]/div/div/div[1]/div[1]/div[1]/div/div[3]/div[1]/div[2]/div/div/div[7]/div/div/div/div",
    container:
      "/html/body/div[1]/div/div[1]/div/div[3]/div/div/div[2]/div/div/div[1]/div[1]/div/div/div/div/div/span/div",
  },
  condition_select: {
    wraper:
      "/html/body/div[1]/div/div[1]/div/div[3]/div/div/div[1]/div[1]/div[1]/div/div[3]/div[1]/div[2]/div/div/div[8]/div/div/div/div",
    container:
      "/html/body/div[1]/div/div[1]/div/div[3]/div/div/div[2]/div/div/div[1]/div[1]/div/div/div/div/div[1]/div",
  },
  tags_input: {
    input:
      "/html/body/div[1]/div/div[1]/div/div[3]/div/div/div[1]/div[1]/div[1]/div/div[3]/div[1]/div[2]/div/div/div[9]/div/div/div[5]/div/div/div/div[1]/label/div/div/div[2]/div/textarea",
    input_falback:
      "/html/body/div[1]/div/div[1]/div/div[3]/div/div/div[1]/div[1]/div[1]/div/div[3]/div[1]/div[2]/div/div/div[10]/div/div/div[5]/div/div/div/div[1]/label/div/div/div[2]/div/textarea",
    plus_btn:
      "/html/body/div[1]/div/div[1]/div/div[3]/div/div/div[1]/div[1]/div[1]/div/div[3]/div[1]/div[2]/div/div/div[9]/div/div/div[5]/div/div/div/div[1]/label/div/div/div[2]/div[2]",
  },

  location_select: {
    input:
      "/html/body/div[1]/div/div[1]/div/div[3]/div/div/div[1]/div[1]/div[1]/div/div[3]/div[1]/div[2]/div/div/div[9]/div/div/div[7]/div/div/div/div/div/div/div/div/label/div[2]/input",
    input_fallback:
      "/html/body/div[1]/div/div[1]/div/div[3]/div/div/div[1]/div[1]/div[1]/div/div[3]/div[1]/div[2]/div/div/div[10]/div/div/div[7]/div/div/div/div/div/div/div/div/label/div[2]/input",
    wraper:
      "/html/body/div[1]/div/div[1]/div/div[3]/div/div/div[1]/div[1]/div[1]/div/div[3]/div[1]/div[2]/div/div/div[9]/div/div/div[7]/div/div/div/div/div/div/div/div",
    container:
      "/html/body/div[1]/div/div[1]/div/div[3]/div/div/div[2]/div/div/div[1]/div[1]/div/ul",
    container_fallback:
      "/html/body/div[1]/div/div[1]/div/div[3]/div/div/div[2]/div/div/div[1]/div[1]/div/ul",
  },
  next_btn:
    "/html/body/div[1]/div/div[1]/div/div[3]/div/div/div[1]/div[1]/div[1]/div/div[5]/div/div/div",
  publish_btn:
    "/html/body/div[1]/div/div[1]/div/div[3]/div/div/div[1]/div[1]/div[1]/div/div[4]/div[2]/div/div",
  products:
    "/html/body/div[1]/div/div[1]/div/div[3]/div/div/div[1]/div[1]/div[2]/div/div/div[2]/div[1]/div/div[2]/div/div/span/div/div",
  products_fallback:
    "/html/body/div[1]/div/div[1]/div/div[3]/div/div/div[1]/div[1]/div[2]/div/div/div[2]/div[1]/div/div[2]/div[2]/div",
};

const uploadImages = async (item: IItem) => {
  // Tạo DataTransfer để giả lập FileList
  const dt: DataTransfer = new DataTransfer();

  for (const image of item.images) {
    const base64 = await thiefService.imageUrlToBase64(image);

    console.log("Base64:", image.slice(0, 50) + "...");
    const file = thiefService.base64ToFile(
      base64,
      item.sku,
      thiefService.getImageExtension(image) || "jpg"
    );

    dt.items.add(file);
  }

  // Tìm input file của Facebook
  const input: HTMLInputElement | null = document.querySelector(
    selectors.file__image_input
  );

  if (input) {
    // Gán file vào input
    input.files = dt.files;

    // Gửi event change
    input.dispatchEvent(new Event("change", { bubbles: true }));
  } else {
    console.error("Không tìm thấy input[type='file']");
  }
};

const chooseSelect = async (
  value: string,
  xpaths: { wraper: string; container: string }
) => {
  const el = await thiefService.getElementByXPath(xpaths.wraper);
  if (!el) throw new Error("Wrapper xpath not found");

  thiefService.scrollToElement(el);
  thiefService.clickByPoint(el);

  await delay(200);
  const container = await thiefService.getElementByXPath(xpaths.container);
  if (!container) throw new Error("Container xpath not found");

  // Tìm phần tử con có nội dung giống value
  const matchingChild = Array.from(container.children).find((child) =>
    child.textContent
      ?.trim()
      .toLocaleLowerCase()
      .replace(/–/g, "-")
      .includes(value.toLocaleLowerCase())
  ) as HTMLElement | undefined;

  if (!matchingChild) throw new Error(`No child found with text "${value}"`);

  thiefService.scrollToElement(matchingChild);

  await delay(200);
  thiefService.clickByPoint(matchingChild);
};

const chooseLocation = async (
  value: string,
  {
    input,
    ...xpaths
  }: {
    wraper: string;
    container: string;
    container_fallback?: string;
    input: string;
    input_fallback?: string;
  }
) => {
  await thiefService.writeToInput(value, input, xpaths.input_fallback);

  await delay(200);

  const container = await thiefService.getElementByXPath(xpaths.container, {
    xpathFallback: xpaths.container_fallback,
  });
  if (!container) throw new Error("Container xpath not found");

  thiefService.scrollToElement(container);

  // Tìm phần tử con có nội dung giống value
  const matchingChild = Array.from(container.children).find((child) =>
    child.textContent
      ?.trim()
      .toLocaleLowerCase()
      .includes(value.toLocaleLowerCase())
  ) as HTMLElement | undefined;

  if (!matchingChild) throw new Error(`No child found with text "${value}"`);

  thiefService.scrollToElement(matchingChild);

  await delay(200);
  thiefService.clickByPoint(matchingChild);
};

const writeTags = async (
  tags: string[],
  xpaths: { input: string; input_falback?: string; plus_btn: string }
) => {
  const input = await thiefService.getElementByXPath(xpaths.input, {
    xpathFallback: xpaths?.input_falback,
  });

  if (!input) throw new Error("Input is not found");

  thiefService.scrollToElement(input);

  await delay(200);
  for (const tag of tags) {
    await thiefService.writeToInput(tag, xpaths.input, xpaths?.input_falback);

    await delay(200);

    thiefService.pressEnter(input);
  }
};

const finistPublist = async (
  item: IItem,
  values: { error?: string; published: boolean }
) => {
  const { data } = await axios({
    url: "products/publist-finish/" + item.id,
    method: "POST",
    data: values,
  });

  return data;
};

const finistDelete = async (
  item: IItem,
  values: { error?: string; published: boolean }
) => {
  const { data } = await axios({
    url: "products/delete-finish/" + item.id,
    method: "POST",
    data: values,
  });

  return data;
};

const clickNext = async () => {
  const btn = await thiefService.getElementByXPath(selectors.next_btn);

  if (!btn) throw new Error("Next button is not found");

  thiefService.clickByPoint(btn);
};

const clickPublist = async () => {
  const btn = await thiefService.getElementByXPath(selectors.publish_btn);

  if (!btn) throw new Error("Publist button is not found");

  thiefService.clickByPoint(btn);
};

function extractListings(productsEl: HTMLElement) {
  const children = Array.from(productsEl.children);

  return children.map((child) => {
    // Lấy title (thường là span hoặc div có dir="auto")
    const titleEl = child.querySelector('span[dir="auto"], div[dir="auto"]');
    const title = titleEl?.textContent?.trim() || "";

    // Lấy giá (span có attribute dir="auto")
    const priceEl = Array.from(child.querySelectorAll('span[dir="auto"]')).find(
      (el) =>
        /\d/.test(el.textContent || "") && /[AU$]/.test(el.textContent || "")
    );

    // Tách lấy số, ví dụ: "AU$20" -> "20"
    const priceMatch = priceEl?.textContent?.match(/\d+(?:\.\d+)?/);
    const price = priceMatch ? parseFloat(priceMatch[0]) : 0;

    return { title, price, el: productsEl };
  });
}

/**
 * B1. Upload images
 * B2. Write title
 * B3. Write price
 * B4. Select category
 * B5. Select condition
 *
 */
const handle = async (item: IItem) => {
  console.log({ item });

  await delay(1000);
  // B1. Upload images
  await uploadImages(item);

  await delay(200);
  // B2. Write title
  thiefService.writeToInput(item.title, selectors.title_input);

  await delay(200);
  // B3. Write price
  thiefService.writeToInput(String(item.price), selectors.price_input);

  await delay(200);
  // B4. Select category
  await chooseSelect(item.category, selectors.category_select);

  await delay(200);
  // B5. Select condition
  await chooseSelect(item.condition, selectors.condition_select);

  if (item.brand) {
    await delay(200);
    // B6. Write brand
    await thiefService.writeToInput(
      item.brand,
      selectors.brand_input,
      selectors.brand_input_fallback
    );
  }

  await delay(200);
  // B7. Write description
  await thiefService.writeToInput(
    item.description,
    selectors.description_input,
    selectors.description_input_falback
  );

  await delay(200);

  await writeTags(item.tags, selectors.tags_input);

  await delay(200);
  // B8. Write sku
  await thiefService.writeToInput(
    item.sku,
    selectors.sku_input,
    selectors.sku_input_fallback
  );

  if (item?.location) {
    await delay(200);

    await chooseLocation(item.location, selectors.location_select);
  }

  await delay(200);

  await clickNext();

  await delay(200);

  await clickPublist();

  return true;
};

const getProducts = async () => {
  let products = await thiefService.getElementByXPath(selectors.products);
  if (!products) {
    products = await thiefService.getElementByXPath(
      selectors.products_fallback
    );
  }

  if (!products) return [];

  return extractListings(products) as ISyncItem[];
};

const syncListing = async () => {
  const url = window.location.href;
  if (!url.includes("https://www.facebook.com/marketplace/you/selling")) return;

  const products = await getProducts();

  if (!products.length) return;

  const response = await productApi.sync(
    products.map((item) => ({
      title: item.title,
      price: item.price,
    })) as ISyncItem[]
  );

  console.log({ response });
};

const closeTab = async (data: IItem) => {
  chrome.runtime.sendMessage({
    type: "close-tab",
    payload: data,
  });
};

const handleDelete = async (payload: IItem) => {
  const products = await getProducts();

  const product = products.find((product) => {
    return product.title == payload.title && product.price == payload.price;
  });

  console.log({ payload, product, products });

  if (!product) return;

  const el = product.el;

  const optionEl = el.querySelector(
    `[aria-label="More options for ${product.title}"]`
  );

  console.log({ optionEl });
  if (!optionEl) return;

  (optionEl as any).click?.();

  await delay(2000);

  const items = Array.from(document.querySelectorAll('[role="menuitem"]'));

  console.log({ items });
  const deleteItem = items.find((item) =>
    item.textContent.toLocaleLowerCase().includes("delete")
  );

  (deleteItem as any).click?.();

  await delay(1000);

  const btnDelete = await thiefService.getElementByXPath(
    "/html/body/div[1]/div/div[1]/div/div[4]/div/div/div[1]/div/div[2]/div/div/div/div/div/div/div[3]/div/div/div/div/div[1]/div",
    {
      xpathFallback:
        "/html/body/div[1]/div/div[1]/div/div[4]/div/div/div[1]/div/div[2]/div/div/div/div[3]/div[2]/div/div[2]/div[1]",
    }
  );

  console.log({ btnDelete });

  btnDelete?.click();

  const closeModal = await thiefService.getElementByXPath(
    "/html/body/div[1]/div/div[1]/div/div[4]/div/div/div[1]/div/div[2]/div/div/div/div[2]/div"
  );

  closeModal?.click();

  await finistDelete(payload, { published: false });

  chrome.runtime.sendMessage({ type: "delete-done" });
};

const port = chrome.runtime.connect();

port.onMessage.addListener(async (message) => {
  if (message.type === "publist-event") {
    const data = message.payload as IItem;

    if (!data) return;

    console.log("Received new product event:", data);

    // data.images = ["images/1.png", "images/2.png"];

    try {
      await delay(500);
      await handle(data);
    } catch (error) {
      await finistPublist(data, {
        error: (error as { message: string }).message,
        published: false,
      });
    } finally {
      await finistPublist(data, { published: true });

      await delay(5000);

      await closeTab(data);
    }
  }
});

// content.js
chrome.runtime.onMessage.addListener((message) => {
  if (message.type === "DELETE_STREAM_DATA") {
    console.log("Nhận dữ liệu từ background:", message.payload);

    handleDelete(message.payload);
  }
});

async function init() {
  // const { data } = await axios.get("products/33");

  // if (!data.data) return;

  // const item = data.data as IItem;

  // await handle(item);

  await syncListing();
}

init();
