import _ from "lodash";
import { outBid, pushPrice, updateBid } from "../../system/apis/bid.js";
import { sendMessage } from "../../system/apis/notification.js";
import { createOutBidLog } from "../../system/apis/out-bid-log.js";
import configs from "../../system/config.js";
import CONSTANTS from "../../system/constants.js";
import {
  convertAETtoUTC,
  isTimeReached,
  removeFalsyValues,
  takeSnapshot,
} from "../../system/utils.js";
import { ProductBid } from "../product-bid.js";
import axios from "../../system/axios.js";

export class AllbidsProductBid extends ProductBid {
  constructor({ ...prev }) {
    super(prev);
  }

  async waitForApiResponse() {
    if (!this.page_context) return;
    try {
      // Chờ cho Angular load (có thể tùy chỉnh thời gian nếu cần)
      await this.page_context.waitForFunction(
        () => window.angular !== undefined
      );

      const auctionData = await this.page_context.evaluate(() => {
        let data = null;
        const elements = document.querySelectorAll(".ng-scope");

        for (let i = 0; i < elements.length; i++) {
          try {
            const scope = angular.element(elements[i]).scope();
            if (
              scope?.auction &&
              scope?.auction.aucID === this.model &&
              scope?.auction?.aucBidIncrement
            ) {
              data = scope.auction;
              break;
            }

            // Thử lấy từ $parent nếu không thấy
            if (scope?.$parent?.auction) {
              data = scope.$parent.auction;
              break;
            }
          } catch (e) {
            // Angular element có thể lỗi nếu phần tử không hợp lệ
            continue;
          }
        }

        return data;
      });

      return auctionData;
    } catch (error) {
      console.log(
        `[${this.id}] Error in waitForApiResponse: ${error?.message}`
      );
    }
  }

  async getHistoriesData() {
    if (!this.page_context) return;
    try {
      // Chờ cho Angular load (có thể tùy chỉnh thời gian nếu cần)
      await this.page_context.waitForFunction(
        () => window.angular !== undefined
      );

      const historiesData = await this.page_context.evaluate(() => {
        let data = null;
        const elements = document.querySelectorAll(".ng-scope");

        for (let i = 0; i < elements.length; i++) {
          try {
            const scope = angular.element(elements[i]).scope();
            if (scope?.bidHistory) {
              data = scope.bidHistory;
              break;
            }

            // Thử lấy từ $parent nếu không thấy
            if (scope?.$parent?.bidHistory) {
              data = scope.$parent.bidHistory;
              break;
            }
          } catch (e) {
            // Angular element có thể lỗi nếu phần tử không hợp lệ
            continue;
          }
        }

        return data;
      });

      return historiesData;
    } catch (error) {
      console.log(
        `[${this.id}] Error in waitForApiResponse: ${error?.message}`
      );
    }
  }

  async handleUpdateBid({
    lot_id,
    close_time,
    name,
    current_price,
    reserve_price,
    model,
    metadata,
  }) {
    const response = await updateBid(this.id, {
      lot_id,
      close_time,
      name,
      current_price,
      reserve_price: Number(reserve_price) || 0,
      model,
      metadata,
    });

    if (response) {
      this.lot_id = response.lot_id;
      this.close_time = response.close_time;
      this.start_bid_time = response.start_bid_time;
    }
  }

  async handlePlaceBidLive() {
    if (!this.page_context) return;

    const response = await this.page_context.evaluate(
      async (aucID, bidAmount, submitUrl) => {
        try {
          const url = `${submitUrl}?aucID=${aucID}&bidAmount=${bidAmount}`;

          const res = await fetch(url, {
            method: "POST",
          });

          if (!res.ok) {
            return { success: false, message: `HTTP error ${res.status}` };
          }

          const data = await res.json();

          return data;
        } catch (error) {
          return { success: false, message: error.message || "Fetch failed" };
        }
      },
      this.model,
      this.max_price,
      configs.WEB_CONFIGS.ALLBIDS.PLACE_BID
    );

    return response;
  }

  async handlePlaceBidSanbox() {
    if (!this.page_context) return;

    const response = await this.page_context.evaluate(
      async (aucID, submitUrl) => {
        try {
          const url = `${submitUrl}?aucID=${aucID}&bidAmount=${0}&bidType=maximum`;

          const res = await fetch(url, {
            method: "POST",
          });

          if (!res.ok) {
            return { success: false, message: `HTTP error ${res.status}` };
          }

          const data = await res.json();

          return data;
        } catch (error) {
          return { success: false, message: error.message || "Fetch failed" };
        }
      },
      this.model,
      configs.WEB_CONFIGS.ALLBIDS.PLACE_BID
    );

    return response;
  }

  update = async () => {
    if (!this.page_context) return;

    console.log(`🔄 [${this.id}] Call update for ID: ${this.id}`);

    // 📌 Chờ phản hồi API từ trang, tối đa 10 giây
    const result = await this.waitForApiResponse();

    const historiesData = await this.getHistoriesData();

    // 📌 Nếu không có dữ liệu trả về thì dừng
    if (!result) {
      console.log(`⚠️ [${this.id}] No valid data received, skipping update.`);
      return;
    }

    // 📌 Loại bỏ các giá trị không hợp lệ và bổ sung thông tin cần thiết
    const data = removeFalsyValues(
      {
        // model: result?.pid || null,
        lot_id: String(result?.aucCurrentBidID) || null,
        reserve_price: result?.aucBidIncrement || null,
        current_price: result.aucCurrentBid || null,
        close_time: result?.aucCloseUtc
          ? new Date(result.aucCloseUtc).toUTCString()
          : null,
        // close_time: close_time && !this.close_time ? String(close_time) : null, // test
        name: result?.aucTitle || null,
        metadata: {
          competor_histories: historiesData,
        },
      },
      ["close_time"]
    );

    console.log(`🚀 [${this.id}] Processed data ready for update`);

    // 📌 Gửi dữ liệu cập nhật lên hệ thống
    await this.handleUpdateBid(data);

    console.log("✅ Update successful!");

    return { ...response, name: data.name, close_time: data.close_time };
  };

  async handlePlaceBid() {
    if (!this.page_context) {
      console.log(
        `⚠️ [${this.id}] No page context found, aborting bid process.`
      );
      return;
    }
    const page = this.page_context;

    if (global[`IS_PLACE_BID-${this.id}`]) {
      console.log(`⚠️ [${this.id}] Bid is already in progress, skipping.`);
      return;
    }

    try {
      console.log(`🔄 [${this.id}] Starting bid process...`);
      global[`IS_PLACE_BID-${this.id}`] = true;

      // Đợi phản hồi từ API
      const response = await this.waitForApiResponse();

      if (
        !response ||
        isTimeReached(new Date(response.aucCloseUtc).toUTCString())
      ) {
        console.log(
          `⚠️ [${this.id}] Outbid detected, calling outBid function.`
        );
        await outBid(this.id);
        return;
      }

      // Kiểm tra nếu giá hiện tại lớn hơn giá tối đa cộng thêm giá cộng thêm
      if (this.current_price > this.max_price + this.plus_price) {
        console.log(`⚠️ [${this.id}] Outbid bid`); // Ghi log cảnh báo nếu giá hiện tại vượt quá mức tối đa cho phép
        return; // Dừng hàm nếu giá đã vượt qua giới hạn
      }

      // Kiểm tra thời gian bid
      if (this.start_bid_time && !isTimeReached(this.start_bid_time)) {
        console.log(
          `⏳ [${this.id}] Not yet time to bid. Skipping Product: ${
            this.name || "None"
          }`
        );
        return;
      }

      // Kiểm tra nếu phản hồi không tồn tại hoặc nếu giá đấu của người dùng bằng với giá tối đa hiện tại
      if (
        !response ||
        (response?.aucUserMaxBid && response.aucUserMaxBid == this.max_price) ||
        response?.aucBidIncrement > this.max_price
      ) {
        console.log(
          `⚠️ [${this.id}] No response or myBid equals max_price:`,
          response
        ); // Ghi log nếu không có phản hồi hoặc giá đấu của người dùng bằng giá tối đa
        return; // Nếu không có phản hồi hoặc giá đấu bằng giá tối đa thì dừng hàm
      }

      const bidHistoriesItem = _.maxBy(this.histories, "price");
      console.log(`📜 [${this.id}] Current bid history:`, this.histories);

      if (
        bidHistoriesItem &&
        bidHistoriesItem?.price === this.current_price &&
        this.max_price == response?.aucUserMaxBid
      ) {
        console.log(
          `🔄 [${this.id}] You have already bid on this item! (Bid Price: ${bidHistoriesItem.price})`
        );
        return;
      }

      console.log("---------------------BIDDING--------------------");

      if (this.isSandbox()) {
        await this.handleCallActionSanbox();
      } else {
        await this.handleCallActionLive();
      }
    } catch (error) {
      console.log(`🚨 [${this.id}] Error placing bid: ${error.message}`);
    } finally {
      console.log(`🔚 [${this.id}] Resetting bid flag.`);
      global[`IS_PLACE_BID-${this.id}`] = false;
    }
  }

  async handleCallActionLive() {
    const data = await this.handlePlaceBidLive();

    await this.page_context.reload({ waitUntil: "networkidle0" });

    // const { aucUserMaxBid } = await this.waitForApiResponse();
    console.log(`📡 [${this.id}] API Response received:`, {
      aucUserMaxBid: this.max_price,
    });

    // 📌 Kiểm tra trạng thái đấu giá từ API
    if (
      data?.bidResult?.result ||
      data?.bidResult?.bidAmount == this.max_price
    ) {
      console.log(`📸 [${this.id}] Taking bid success snapshot...`);

      // sendMessage(this);

      pushPrice({
        bid_id: this.id,
        price: this.max_price,
      });

      await takeSnapshot(
        this.page_context,
        this,
        "bid-success",
        CONSTANTS.TYPE_IMAGE.SUCCESS
      );

      console.log(`✅ [${this.id}] Bid placed successfully!`);
      return;
    }

    console.log(
      `⚠️ [${this.id}] Bid action completed, but status is still "None".`
    );
  }

  async handleCallActionSanbox() {
    const result = await this.handlePlaceBidSanbox();

    await axios({
      url: this.ACTION_URL({ type: "api" }),
      data: {
        id: this.id,
        data: JSON.stringify(result),
      },
      method: "POST",
    });

    await this.close();

    return result;
  }

  action = async () => {
    try {
      const page = this.page_context;

      // 📌 Kiểm tra nếu trang chưa tải đúng URL thì điều hướng đến URL mục tiêu
      if (!page.url() || !page.url().includes(this.url)) {
        console.log(`🔄 [${this.id}] Navigating to target URL: ${this.url}`);
        await this.gotoLink();
      }

      await this.handlePlaceBid();
    } catch (error) {
      console.error(`🚨 [${this.id}] Error navigating the page: ${error}`);
    }
  };
}
