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) return "—";
  const [datePart, timePart] = dateTime.split(" ");
  const [year, month, day] = datePart.split("-");
  const formattedDate = `${day}/${month}/${year}`;
  if (timePart) {
    const [hours, minutes, seconds] = timePart.split(":");
    const formattedTime = `${hours}:${minutes}:${seconds}`;
    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;
};

/**
 * @description Converte "DD/MM/YYYY" ou "YYYY-MM-DD" para Date local à meia-noite.
 * Evita `new Date(string)`, que interpreta "YYYY-MM-DD" como UTC e erra o dia.
 * @param {string} value data.
 * @returns {Date|null} data local ou null se inválida.
 */
const parseLocalDate = (value) => {
  if (!value) return null;

  const datePart = String(value).trim().split(" ")[0];
  const parts = datePart.includes("/")
    ? datePart.split("/").reverse()
    : datePart.split("-");

  if (parts.length !== 3) return null;

  const [year, month, day] = parts.map(Number);
  if (!year || !month || !day) return null;

  const date = new Date(year, month - 1, day);
  return isNaN(date) ? null : date;
};

/**
 * @description Data de hoje + N dias, à meia-noite local.
 * @param {number} days quantidade de dias.
 * @returns {Date} data resultante.
 */
const addDaysToToday = (days) => {
  const date = new Date();
  date.setHours(0, 0, 0, 0);
  date.setDate(date.getDate() + days);
  return date;
};

/**
 * @description Formata um Date para "DD/MM/YYYY".
 * @param {Date} date data.
 * @returns {string} data formatada.
 */
const formatDateBR = (date) =>
  date.toLocaleDateString("pt-BR", { day: "2-digit", month: "2-digit", year: "numeric" });

/**
 * @description Formata data + hora do agendamento para exibição.
 * @param {string} date data "YYYY-MM-DD".
 * @param {string} time hora "HH:mm" (opcional).
 * @returns {string} "DD/MM/YYYY HH:mm", "DD/MM/YYYY" ou "—".
 */
const formatDateTimeBR = (date, time) => {
  const parsed = parseLocalDate(date);
  if (!parsed) return "—";

  return time ? `${formatDateBR(parsed)} ${time}` : formatDateBR(parsed);
};

/**
 * @description Monta o link de conversa do WhatsApp a partir do telefone do parceiro.
 * @param {object} partner parceiro/convênio.
 * @param {string} [message] texto que já abre digitado na conversa.
 * @returns {string|null} URL wa.me ou null se não houver número utilizável.
 */
const whatsappUrlFor = (partner, message) => {
  const raw = partner?.whatsapp || partner?.phone;
  if (!raw) return null;

  const digits = String(raw).replace(/\D/g, "");
  if (digits.length < 10) return null;

  const url = `https://wa.me/${digits.startsWith("55") ? digits : `55${digits}`}`;

  return message ? `${url}?text=${encodeURIComponent(message)}` : url;
};

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

const getStatusColor = (status) => {
  const s = typeof status === "object" ? status?.value : status;
  if (s === "active")  return "positive";
  if (s === "pending") return "warning-light";
  if (s === "inactive") return "inactive";
  return "grey-6";
};

const getStatusI18nKey = (status) => {
  const s = typeof status === "object" ? status?.value : status;
  if (s === "active")   return "common.status.active";
  if (s === "inactive") return "common.status.inactive";
  if (s === "pending")  return "common.status.pending";
  return "common.status.inactive";
};

export {
  formatDateDMYtoYMD,
  formatDateYMDtoDMY,
  excerpt,
  convertDateTime,
  formatToBRLCurrency,
  normalizeString,
  parseLocalDate,
  addDaysToToday,
  formatDateBR,
  formatDateTimeBR,
  whatsappUrlFor,
  getStatusColor,
  getStatusI18nKey,
};
