import cssBreakpoints from "@/styles/export/breakpoints.module.scss";

import { isBrowser } from "./is-browser";
import { mapObject } from "./object";

export function getCssVar(propertyName: string, fallbackValue: string = "") {
  if (isBrowser) {
    const value = getComputedStyle(document.documentElement).getPropertyValue(
      `--${propertyName}`,
    );
    return value || fallbackValue;
  }
  return fallbackValue;
}

export function setCssVar(propertyName: string, value: string) {
  if (isBrowser) {
    document.documentElement.style.setProperty(`--${propertyName}`, value);
  } else {
    console.warn("Attempted to set CSS variable in a non-browser environment.");
  }
}

export function removeCssVar(propertyName: string) {
  if (isBrowser) {
    document.documentElement.style.removeProperty(`--${propertyName}`);
  } else {
    console.warn("Attempted to set CSS variable in a non-browser environment.");
  }
}

export function getUnits(value: string | number) {
  if (typeof value === "string") {
    if (isNaN(parseFloat(value))) return null;
    const match = value.match(/(px|em|rem|vh|vw|%)$/);
    return match ? match[0] : "none";
  }
  return "none";
}

export function unitsToPx(value: string | number) {
  switch (getUnits(value)) {
    case "px":
      return value;
    case "rem":
      return remToPx(value);
    default:
      return value;
  }
}

export function remToPx(rem: string | number) {
  const remValue = typeof rem === "number" ? rem : parseFloat(rem);

  if (isBrowser) {
    return (
      remValue * parseFloat(getComputedStyle(document.documentElement).fontSize)
    );
  } else {
    return remValue;
  }
}

export const mediaQueries = {
  minWidth: mapObject(cssBreakpoints, (n) => `(min-width: ${n})`),
  maxWidth: mapObject(cssBreakpoints, (n) => `(max-width: ${n})`),
};

export const breakpoints = Object.keys(cssBreakpoints).reduce(
  (acc, key) => {
    acc[key as keyof typeof cssBreakpoints] = parseInt(cssBreakpoints[key], 10);
    return acc;
  },
  {} as Record<keyof typeof cssBreakpoints, number>,
);
