import { MutableRefObject, useCallback, useRef, useState } from "react";
import timeAgo from "time-ago";

export function useStateWithRefPair<T>(initValue: T): [T, (v: T) => void, MutableRefObject<T>] {
  const [ value , origSetValue ] = useState<T>(initValue);
  const valueRef = useRef<T>(initValue);

  const setValue = useCallback((v: T) => {
    valueRef.current = v;
    origSetValue(valueRef.current);
  }, [origSetValue]);

  return [ value, setValue, valueRef];
}

export function niceTimeAgo(timeMs: number, isShort: boolean) {
  let timeStr;
  if ((new Date().getTime() - timeMs) < 60 * 1000) {
    timeStr = "Just now";
  } else if (isShort) {
    timeStr = `${timeAgo.ago(timeMs, true) as string} ago`;
    if (new Date().getTime() - timeMs > 1000 * 60 * 60 * 24) {
      // minutes and months are both "m", so using "mo" for month
      timeStr = timeStr.replace("m", "mo");
    }
  } else {
    timeStr = timeAgo.ago(timeMs) as string;
  }
  return timeStr;
}

export function safeJsonParse(jsonStr: string | null | undefined): unknown | null {
  if (jsonStr == null || jsonStr === "") {
    return null;
  }
  try {
    return JSON.parse(jsonStr);
  } catch (e) {
    const message = e instanceof Error ? e.message : null;
    console.error("JsonSyntaxError", message);
    return null;
  }
}

export function safeJsonStringify(obj: unknown | null | undefined): string | null {
  if (obj == null) {
    return null;
  }
  try {
    return JSON.stringify(obj);
  } catch (e) {
    const message = e instanceof Error ? e.message : null;
    console.error("TypeError", message);
    return null;
  }
}