/* eslint-disable @typescript-eslint/no-unused-vars */
/* eslint-disable @typescript-eslint/no-explicit-any */
import { clsx, type ClassValue } from "clsx";
import { twMerge } from "tailwind-merge";
import moment from "moment";
import { IBid, IMetadata, IWebBid } from "../system/type";
import _ from "lodash";

export function cn(...args: ClassValue[]) {
  return twMerge(clsx(args));
}

export const formatTime = (time: string, patent = "DD/MM/YYYY") => {
  return moment(time).format(patent);
};

export function removeFalsyValues<T extends Record<string, any>>(
  obj: T,
  excludeKeys: (keyof T)[] = []
): Partial<T> {
  return Object.entries(obj).reduce((acc, [key, value]) => {
    if (value || excludeKeys.includes(key as keyof T)) {
      acc[key as keyof T] = value;
    }
    return acc;
  }, {} as Partial<T>);
}

export function isValidJSON(str: string): boolean {
  if (!str || str.length <= 0) return false;

  try {
    JSON.parse(str);
    return true;
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
  } catch (e) {
    return false;
  }
}

export function copyToClipboard(text: string, onSuccess?: () => void): void {
  if (!navigator.clipboard) {
    const textarea = document.createElement("textarea");
    textarea.value = text;
    textarea.style.position = "fixed";
    document.body.appendChild(textarea);
    textarea.focus();
    textarea.select();

    try {
      document.execCommand("copy");
      if (onSuccess) onSuccess();
    } catch (err) {
      console.error("Không thể copy nội dung: ", err);
    }

    document.body.removeChild(textarea);
  } else {
    navigator.clipboard
      .writeText(text)
      .then(() => {
        if (onSuccess) onSuccess();
      })
      .catch((err) => console.error("Lỗi khi copy nội dung: ", err));
  }
}

export function base64ToFile(base64String: string, fileName: string): File {
  const [header, base64Content] = base64String.split(",");

  const mimeTypeMatch = header.match(/:(.*?);/);
  if (!mimeTypeMatch || mimeTypeMatch.length < 2) {
    throw new Error("Invalid base64 string");
  }
  const mimeType = mimeTypeMatch[1];

  const binaryString = atob(base64Content);

  const byteArray = new Uint8Array(binaryString.length);
  for (let i = 0; i < binaryString.length; i++) {
    byteArray[i] = binaryString.charCodeAt(i);
  }

  return new File([byteArray], fileName, { type: mimeType });
}

export function toSlug(str: string, maxLength = 60): string {
  if (typeof str !== "string") return ""; // Kiểm tra giá trị đầu vào

  // Kiểm tra nếu môi trường hỗ trợ `normalize`
  const normalizedStr = str.normalize ? str.normalize("NFD") : str;

  return normalizedStr
    .replace(/[\u0300-\u036f]/g, "") // Xóa dấu
    .replace(/[^a-zA-Z0-9\s-]/g, "") // Chỉ giữ chữ cái, số, khoảng trắng và dấu "-"
    .trim() // Xóa khoảng trắng đầu/cuối
    .replace(/\s+/g, "-") // Thay khoảng trắng bằng "-"
    .replace(/-+/g, "-") // Gộp nhiều dấu "-" thành 1
    .toLowerCase() // Chuyển về chữ thường
    .slice(0, maxLength) // Giới hạn độ dài
    .replace(/^-+|-+$/g, ""); // Xóa "-" đầu/cuối
}

export function estimateReadingTimeInSeconds(
  content: string,
  wordsPerMinute = 200
): number {
  if (!content || typeof content !== "string") return 0;

  const wordCount = content.trim().split(/\s+/).length;
  return Math.ceil((wordCount / wordsPerMinute) * 60);
}

export function extractDomain(url: string): string | null {
  try {
    const parsedUrl = new URL(url);
    return parsedUrl.origin;
  } catch (error) {
    return null;
  }
}

// Hash chuỗi thành số nguyên
export function hashStringToInt(str: string): number {
  let hash = 0;
  for (let i = 0; i < str.length; i++) {
    hash = str.charCodeAt(i) + ((hash << 5) - hash);
    hash = hash & hash; // convert to 32bit integer
  }
  return Math.abs(hash);
}

// Biến số thành màu HEX
export function intToHexColor(int: number): string {
  const r = (int >> 16) & 0xff;
  const g = (int >> 8) & 0xff;
  const b = int & 0xff;
  return `#${[r, g, b].map((x) => x.toString(16).padStart(2, "0")).join("")}`;
}

export function stringToColor(str: string): string {
  const colorPalette = [
    "#FF6B6B",
    "#FFD93D",
    "#FF9F1C",
    "#F76C6C",
    "#6BCB77",
    "#4ECDC4",
    "#F7B801",
    "#FF6F91",
    "#00C9A7",
  ];
  const hash = hashStringToInt(str);
  const index = hash % colorPalette.length;
  return colorPalette[index];
}

export function findEarlyLoginTime(webBid: IWebBid): string | null {
  const now = new Date();

  // Bước 1: Lọc ra những bid có close_time hợp lệ
  const validChildren = webBid.children.filter((child) => child.close_time);

  if (validChildren.length === 0) return null;

  // Bước 2: Tìm bid có close_time gần hiện tại nhất
  const closestBid = validChildren.reduce((closest, current) => {
    const closestDiff = Math.abs(
      new Date(closest.close_time!).getTime() - now.getTime()
    );
    const currentDiff = Math.abs(
      new Date(current.close_time!).getTime() - now.getTime()
    );
    return currentDiff < closestDiff ? current : closest;
  });

  if (!closestBid.close_time) return null;

  // Bước 3: Tính toán thời gian login sớm
  const closeTime = new Date(closestBid.close_time);
  closeTime.setSeconds(
    closeTime.getSeconds() - (webBid.early_tracking_seconds || 0)
  );

  return closeTime.toISOString();
}

export function extractDomainSmart(url: string) {
  const PUBLIC_SUFFIXES = ["com.au", "co.uk", "com.vn", "org.au", "gov.uk"];

  try {
    const hostname = new URL(url).hostname.replace(/^www\./, ""); // remove "www."
    const parts = hostname.split(".");

    for (let i = 0; i < PUBLIC_SUFFIXES.length; i++) {
      if (hostname.endsWith(PUBLIC_SUFFIXES[i])) {
        return parts[parts.length - PUBLIC_SUFFIXES[i].split(".").length - 1];
      }
    }

    return parts[parts.length - 2];
  } catch (e) {
    return url;
  }
}

export function findNearestClosingChild(webBid: IWebBid) {
  const now = Date.now();

  const validChildren = webBid.children.filter(
    (child) => child.close_time && !isNaN(new Date(child.close_time).getTime())
  );

  if (validChildren.length === 0) {
    return null;
  }

  const nearestChild = _.minBy(validChildren, (child) => {
    return Math.abs(new Date(child.close_time!).getTime() - now);
  });

  return nearestChild || null;
}

export function extractNumber(str: string) {
  const match = str.match(/\d+(\.\d+)?/);
  return match ? parseFloat(match[0]) : null;
}

export function subtractMinutes(time: string, minutes: number) {
  const date = new Date(time);
  date.setMinutes(date.getMinutes() - minutes);
  return date.toUTCString();
}

export function subtractSeconds(time: string, seconds: number) {
  const date = new Date(time);
  date.setSeconds(date.getSeconds() - seconds);
  return date.toUTCString();
}

export function isTimeReached(targetTime: string) {
  if (!targetTime) return false;

  const targetDate = new Date(targetTime);
  const now = new Date();

  return now >= targetDate;
}

export function formatTimeFromMinutes(minutes: number): string {
  // Tính ngày, giờ, phút từ số phút
  const days = Math.floor(minutes / (60 * 24));
  const hours = Math.floor((minutes % (60 * 24)) / 60);
  const mins = minutes % 60;

  let result = "";

  if (days > 0) result += `${days} ${days > 1 ? "days" : "day"} `;
  if (hours > 0) result += `${hours} ${hours > 1 ? "hours" : "hour"} `;
  if (mins > 0 || result === "") result += `${mins} minutes`;

  return result.trim();
}

export const getMode = (row: IBid) => {
  return (
    row.metadata.find((item) => item.key_name === "mode_key")?.value || "live"
  );
};

export const getEarlyTrackingSeconds = (row: IBid) => {
  const mode = getMode(row);

  return (
    row.metadata.find(
      (item) => item.key_name === `early_tracking_seconds_${mode}`
    )?.value || row.web_bid.early_tracking_seconds
  );
};

export const getResponseDemo = (data: IBid) => {
  if (!data?.metadata) return null;

  return (
    (data?.metadata.find(
      (item) => item.key_name === "demo_response"
    ) as IMetadata) || null
  );
};
