import { Bid } from '@/modules/bids/entities/bid.entity';
import { ScrapItem } from '@/modules/scraps/entities/scrap-item.entity';
import * as moment from 'moment';

export function extractModelId(url: string): string | null {
  switch (extractDomain(url)) {
    case 'https://www.grays.com': {
      const match = url.match(/\/lot\/([\d-]+)\//);
      return match ? match[1] : null;
    }
    case 'https://www.langtons.com.au': {
      const match = url.match(/auc-var-\d+/);
      return match[0];
    }
    case 'https://www.lawsons.com.au': {
      const match = url.split('_');
      return match ? match[1] : null;
    }
    case 'https://www.pickles.com.au': {
      const model = url.split('/').pop();
      return model ? model : null;
    }
    case 'https://www.allbids.com.au': {
      const match = url.match(/-(\d+)(?:[\?#]|$)/);
      return match ? match[1] : null;
    }
  }
}

export function subtractMinutes(timeStr: string, minutes: number) {
  const date = new Date(timeStr); // Chuyển chuỗi thành đối tượng Date
  date.setMinutes(date.getMinutes() - minutes); // Trừ đi số phút
  return date.toISOString(); // Trả về dạng chuẩn ISO
}

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 subtractSeconds(time: string, seconds: number) {
  const date = new Date(time);
  date.setSeconds(date.getSeconds() - seconds);
  return date.toUTCString();
}

export function isTimeReached(targetTime: string) {
  const targetDate = new Date(targetTime);
  const now = new Date();

  return now >= targetDate;
}

export function isTimePassedByMinutes(
  targetTime: string,
  minutes: number,
): boolean {
  const targetDate = new Date(targetTime);
  const now = new Date();

  const diffMs = now.getTime() - targetDate.getTime(); // hiệu số milliseconds
  const diffMinutes = diffMs / (1000 * 60);

  return diffMinutes >= minutes;
}

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

export function escapeMarkdownV2(text: string) {
  return text.replace(/[_*[\]()~`>#+\-=|{}.!\\]/g, '\\$&');
}

export function extractVerifyCodeLANGTONS(content: string) {
  const match = content.match(/Your\s+(\w+)\s+verific.*?code\s+is:\s+(\d+)/i);

  if (match) {
    const name = match[1]; // LANGTONS
    const code = match[2]; // 012152

    return {
      name,
      code,
    };
  } else {
    return null;
  }
}

export function extractVerifyCodeLAWSONS(content: string) {
  if (!content) return null;

  // Loại bỏ các ký tự `=` không cần thiết do email encoding (quoted-printable)
  content = content.replace(/=\r\n/g, '').replace(/=3D/g, '=');

  // Regex để tìm mã xác minh (6 chữ số)
  const codeMatch = content.match(/Verification code:\s*(\d{6})/);
  const code = codeMatch ? codeMatch[1] : null;

  // Regex để tìm tên (trong đoạn "Lawsons | Sydney, AU")
  const nameMatch = content.match(/([\w\s]+)\s*\|\s*[\w\s,]+/);
  const name = nameMatch ? nameMatch[1].trim() : null;

  // Nếu không tìm thấy cả hai giá trị, trả về null
  if (!code && !name) {
    return null;
  }

  return { code, name };
}

export function verifyCode(content: string) {
  // Kiểm tra mã xác minh từ LANGTONS
  const langtonsResult = extractVerifyCodeLANGTONS(content);

  if (langtonsResult) {
    return langtonsResult;
  }

  // Nếu không có kết quả, tiếp tục kiểm tra mã xác minh từ LAWSONS
  const lawsonsResult = extractVerifyCodeLAWSONS(content);

  if (lawsonsResult) {
    return lawsonsResult; // Trả về kết quả đúng thay vì langtonsResult
  }

  // Nếu không tìm thấy mã xác minh, trả về null
  return null;
}

export function shouldResetTool(
  bids: Bid[],
  lastResetTime: Date | null,
  now: Date = new Date(),
) {
  const ONE_MINUTE = 60 * 1000;
  const ONE_HOUR = 60 * ONE_MINUTE;
  const TWO_HOURS = 2 * ONE_HOUR;
  const TWENTY_MINUTES = 20 * ONE_MINUTE;
  const FIVE_MINUTES = 5 * ONE_MINUTE;

  // Nếu đã reset trong 1 giờ gần đây => không reset
  if (lastResetTime && now.getTime() - lastResetTime.getTime() < ONE_HOUR) {
    return {
      shouldReset: false,
    };
  }

  // 1. Kiểm tra bid gần nhất có close_time trong vòng 20 phút tới
  const futureBids = bids
    .filter((b) => b.close_time)
    .map((b) => ({
      ...b,
      closeTime: new Date(b.close_time!),
    }))
    .filter((b) => b.closeTime.getTime() > now.getTime())
    .sort((a, b) => a.closeTime.getTime() - b.closeTime.getTime());

  const closest = futureBids[0];
  const hasBidCloseSoon =
    closest && closest.closeTime.getTime() - now.getTime() <= TWENTY_MINUTES;

  if (hasBidCloseSoon) {
    return {
      shouldReset: true,
      reason: 'Bid close_time is within 20 minutes',
      bidId: closest.id,
      closeTime: closest.close_time,
    };
  }

  // 2. Kiểm tra bid chưa có lot_id hoặc close_time, được tạo > 5 phút và cách reset trước > 2 tiếng
  // Đồng thời không có bid nào sắp close trong 20 phút tới
  if (!hasBidCloseSoon) {
    for (const bid of bids) {
      const createdAt = new Date(bid.created_at);
      if (
        (!bid.lot_id || !bid.close_time) &&
        now.getTime() - createdAt.getTime() > FIVE_MINUTES &&
        (!lastResetTime || now.getTime() - lastResetTime.getTime() > TWO_HOURS)
      ) {
        return {
          shouldReset: true,
          reason:
            'Bid is missing info and older than 5 mins, last reset > 2h, and no urgent bids',
          bidId: bid.id,
          closeTime: bid.close_time,
        };
      }
    }
  }

  return {
    shouldReset: false,
  };
}

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

export function formatEndTime(
  closeTime: string | Date,
  extended: boolean,
): string {
  return `${moment(closeTime).format('YYYY-MM-DD HH:mm')} (${extended ? 'extended' : 'no extension'})`;
}

export const delay = (ms: number) =>
  new Promise((resolve) => setTimeout(resolve, ms));

export const isHotItemFn = (item: ScrapItem, hotItems: any[]) => {
  return hotItems.some((obj) =>
    item.name.toLowerCase().includes(obj.name.toLowerCase()),
  );
};

export function parseVideoFileName(fileName: string) {
  // Loại bỏ phần mở rộng .mp4
  const nameWithoutExt = fileName.replace(/\.mp4$/, '');

  // Tách phần ID đầu tiên
  const firstUnderscoreIndex = nameWithoutExt.indexOf('_');
  const id = nameWithoutExt.slice(0, firstUnderscoreIndex);

  // Tách phần timestamp cuối cùng
  const lastUnderscoreIndex = nameWithoutExt.lastIndexOf('_');
  const timestamp = nameWithoutExt.slice(lastUnderscoreIndex + 1);

  // Tên sản phẩm nằm giữa 2 phần còn lại
  const name = nameWithoutExt.slice(
    firstUnderscoreIndex + 1,
    lastUnderscoreIndex,
  );

  return {
    bid_id: Number(id),
    name,
    original_name: fileName,
    timestamp: Number(timestamp),
  };
}
