import { useI18n } from "vue-i18n";

/**
 * @description Corta uma string em um determinado tamanho.
 * @param {string} string string a ser cortada.
 * @param {string} size tamanho da string.
 * @returns {string} string cortada.
 */
const excerpt = (string, size = 30) => {
  if (size == null) return string;
  if (string.length > size) {
    string = string.substring(0, size) + "...";
  }
  return string;
};

/**
 * @description Formata uma data de DD/MM/YYYY para YYYY-MM-DD
 * @param {string} date data.
 * @param {string} time tempo.
 * @throws {Error} Caso a data seja nula ou invalida.
 * @returns {string} data formatada.
 */
const formatDateDMYtoYMD = (date, time) => {
  if (!date) throw new Error(useI18n().t("validation.rules.required"));
  const testDate =
    /^([0-2][0-9]|(3)[0-1])(\/)(((0)[0-9])|((1)[0-2]))(\/)\d{4}$/;
  if (testDate.test(date) === false)
    throw new Error(useI18n().t("validation.rules.date"));

  const [day, month, year] = date.split("/");
  return `${year}-${month}-${day} ${time ? time : ""}`;
};

/**
 * @description Converte uma data e hora para o formato brasileiro.
 * @param {string} dateTimeString data e hora.
 * @returns {string} data e hora no formato brasileiro.
 * @throws {Error} Caso a data seja nula ou invalida.
 * @returns {string} data formatada.
 * @example
 * // convertDateTime("2023-05-23T13:07:27.000000Z");
 * // Output: 23/05/2023 10:07:27
 */
const convertDateTime = (dateTimeString) => {
  const dateTime = new Date(dateTimeString);
  const options = {
    timeZone: "America/Sao_Paulo",
    day: "2-digit",
    month: "2-digit",
    year: "numeric",
    hour: "2-digit",
    minute: "2-digit",
    second: "2-digit",
  };
  const formattedDateTime = dateTime
    .toLocaleString("pt-BR", options)
    .replace(",", "");
  return formattedDateTime;
};

/**
 * @description Formata uma data de YYYY-MM-DD para DD/MM/YYYY
 * @param {string} dateTime data e hora.
 * @returns {string} data e hora no formato brasileiro.
 * @example
 * // formatDateYMDtoDMY("2023-05-23T13:07:27.000000Z");
 * // Output: 23/05/2023 10:07:27
 */
const formatDateYMDtoDMY = (dateTime) => {
  if (!dateTime || typeof dateTime !== "string") return "-";

  const normalizedDateTime = dateTime.trim().replace("T", " ");
  if (!normalizedDateTime) return "-";

  const [datePart, timePart] = normalizedDateTime.split(" ");
  const [year, month, day] = datePart.split("-");
  if (!year || !month || !day) return "-";

  const formattedDate = `${day}/${month}/${year}`;
  if (timePart) {
    const [hours, minutes, seconds = "00"] = timePart
      .replace("Z", "")
      .split(":");
    const formattedTime = `${hours}:${minutes}:${seconds.split(".")[0]}`;
    return `${formattedDate} ${formattedTime}`;
  }
  return formattedDate;
};

/**
 * @description Formata a moeda.
 * @param {number} value valor.
 * @returns {string} valor formatado.
 */
const formatToBRLCurrency = (value) => {
  if (value != null) {
    value = parseFloat(value);
    return value.toLocaleString("pt-BR", {
      minimumFractionDigits: 2,
      style: "currency",
      currency: "BRL",
    });
  }
  return value;
};

const normalizeString = (val) =>
  val
    .toLowerCase()
    .normalize("NFKD")
    .replace(/[\u0300-\u036f~]/g, "");

const normalizeUnitName = (value) => {
  const name = String(value ?? "").trim();
  return name && !["null", "undefined"].includes(name.toLowerCase())
    ? name
    : null;
};

const formatUnitName = (unit, fallback = "Unidade sem nome") =>
  normalizeUnitName(unit?.name) ||
  normalizeUnitName(unit?.fantasy_name) ||
  normalizeUnitName(unit?.social_reason) ||
  fallback;

const isUnderage = (birthDate, referenceDate = new Date()) => {
  if (!birthDate || typeof birthDate !== "string") return false;

  const normalizedDate = birthDate.trim().split(" ")[0];

  const parts = normalizedDate.includes("/")
    ? normalizedDate.split("/").reverse()
    : normalizedDate.split("-");

  const [year, month, day] = parts.map(Number);

  if (!year || !month || !day) return false;

  const parsedBirthDate = new Date(year, month - 1, day);

  const isValidDate =
    parsedBirthDate.getFullYear() === year &&
    parsedBirthDate.getMonth() === month - 1 &&
    parsedBirthDate.getDate() === day;

  if (!isValidDate) return false;

  const eighteenthBirthday = new Date(year + 18, month - 1, day);

  return eighteenthBirthday > referenceDate;
};

export {
  formatDateDMYtoYMD,
  formatDateYMDtoDMY,
  excerpt,
  convertDateTime,
  formatToBRLCurrency,
  normalizeString,
  formatUnitName,
  isUnderage,
};
