import { resources } from "@lib/resources.ts";

export function formatDate(date: Date): string {
  const options = { year: "numeric", month: "long", day: "numeric" } as const;
  return new Intl.DateTimeFormat("en-US", options).format(date);
}

export function safeFileName(inputString: string): string {
  let fileName = inputString.toLowerCase();
  fileName = fileName.replace(/ /g, "_");
  fileName = fileName.replace(/[^\w.-]/g, "");
  fileName = fileName.replaceAll(":", "");
  return fileName;
}

export function extractHashTags(inputString: string) {
  const hashtags = [];

  for (
    const [hashtag] of inputString.matchAll(/(?:^|\s)#\S*(?<!\))/g)
  ) {
    const cleaned = hashtag.replace(/\#/g, "").trim();
    if (cleaned.length > 2) {
      hashtags.push(cleaned);
    }
  }

  return hashtags;
}

export const isYoutubeLink = (link: string) => {
  try {
    const url = new URL(link);
    return ["youtu.be", "youtube.com", "www.youtube.com"].includes(
      url.hostname,
    );
  } catch (_err) {
    return false;
  }
};

export function extractYoutubeId(link: string) {
  const url = new URL(link);
  if (url.searchParams.has("v")) {
    const id = url.searchParams.get("v");

    if (id?.length && id.length > 4) {
      return id;
    }
  }

  return url.pathname.replace(/^\//, "");
}

export async function hash(message: string) {
  const data = new TextEncoder().encode(message);
  const hashBuffer = await crypto.subtle.digest("SHA-256", data);
  const hashArray = Array.from(new Uint8Array(hashBuffer));
  const hashHex = hashArray.map((b) => b.toString(16).padStart(2, "0")).join(
    "",
  );
  return hashHex;
}
// Helper function to calculate SHA-256 hash
export async function sha256(input: string) {
  const encoder = new TextEncoder();
  const data = encoder.encode(input);
  const hashBuffer = await crypto.subtle.digest("SHA-256", data);
  return base64urlencode(new Uint8Array(hashBuffer));
}

// Helper function to encode a byte array as a URL-safe base64 string
function base64urlencode(data: Uint8Array) {
  const base64 = btoa(String.fromCharCode(...data));
  return base64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
}
export function getCookie(name: string): string | null {
  if (typeof document === "undefined") return null;
  const nameLenPlus = name.length + 1;
  return document.cookie
    .split(";")
    .map((c) => c.trim())
    .filter((cookie) => {
      return cookie.substring(0, nameLenPlus) === `${name}=`;
    })
    .map((cookie) => {
      return decodeURIComponent(cookie.substring(nameLenPlus));
    })[0] || null;
}

const resourcePrefixes = Object.values(resources).map((v) => v.prefix).filter(
  (s) => s.length > 2,
);
export const isLocalImage = (src: string) =>
  resourcePrefixes.some((p) => src.startsWith(p));

export const isString = (input: string | undefined): input is string => {
  return typeof input === "string";
};

function componentToHex(c: number) {
  if (c <= 1) {
    c = Math.round(c * 255);
  }
  const hex = c.toString(16);
  return hex.length == 1 ? "0" + hex : hex;
}

export function getTimeCacheKey() {
  const d = new Date();
  const year = d.getFullYear();
  const month = d.getMonth().toString();
  const day = d.getDate().toString();
  const hour = d.getHours().toString();
  const minute = d.getMinutes().toString();
  const seconds = d.getSeconds().toString();
  return `${year}:${month}:${day}:${hour}:${minute}:${seconds}`;
}

export function parseTimeCacheKey(key: string) {
  const [_year, _month, _day, _hour, _minute, _second] = key.split(":")
    .slice(1).map((s) => parseInt(s));
  const d = new Date();
  d.setFullYear(_year);
  d.setMonth(_month);
  d.setDate(_day);
  d.setHours(_hour);
  d.setMinutes(_minute);
  d.setSeconds(_second);
  return d;
}

export function rgbToHex(r: number, g: number, b: number) {
  return "#" + componentToHex(r) + componentToHex(g) + componentToHex(b);
}

export function removeMarkdownFormatting(text: string): string {
  // Remove code blocks
  text = text.replace(/```[\s\S]*?```/g, "");

  // Remove inline code
  text = text.replace(/`([^`]+)`/g, "$1");

  // Remove images
  text = text.replace(/!\[.*?\]\(.*?\)/g, "");

  // Remove links
  text = text.replace(/\[([^\]]+)\]\([^\)]+\)/g, "$1");

  // Remove bold and italic formatting
  text = text.replace(/(\*\*|__)(.*?)\1/g, "$2"); // Bold
  text = text.replace(/(\*|_)(.*?)\1/g, "$2"); // Italic

  // Remove strikethrough
  text = text.replace(/~~(.*?)~~/g, "$1");

  // Remove headings
  text = text.replace(/^#{1,6}\s*(.+)$/gm, "$1");

  // Remove blockquotes
  text = text.replace(/^>\s*/gm, "");

  // Remove unordered list markers
  text = text.replace(/^[-*+]\s+/gm, "-");

  // Remove ordered list markers
  text = text.replace(/^\d+\.\s+/gm, "");

  // Remove horizontal rules
  text = text.replace(/^---+$/gm, "");

  return text;
}
