export function formatMoney(value: number): string {
  return new Intl.NumberFormat("pt-BR", {
    style: "currency",
    currency: "BRL",
  }).format(value || 0);
}

export function formatMeasureInput(value: unknown): string {
  const MEASURE_MAX_DECIMALS = 3;
  const MEASURE_SCALE = 10 ** MEASURE_MAX_DECIMALS;

  function sanitizeMeasureInput(raw: string): string {
    const normalized = raw
      .replace(/\s/g, "")
      .replace(/\./g, ",")
      .replace(/[^0-9,]/g, "");

    if (!normalized) return "";

    const commaIndex = normalized.indexOf(",");
    if (commaIndex === -1) {
      const intPart = normalized.replace(/^0+(?=\d)/, "");
      return intPart || "0";
    }

    const intRaw = normalized.slice(0, commaIndex).replace(/,/g, "");
    const fracRaw = normalized.slice(commaIndex + 1).replace(/,/g, "");
    const intPart = (intRaw || "0").replace(/^0+(?=\d)/, "");
    const fracPart = fracRaw.slice(0, MEASURE_MAX_DECIMALS);

    return `${intPart},${fracPart}`;
  }

  function formatDigitsAsMeasure(digitsOnly: string): string {
    const parsed = Number.parseInt(digitsOnly, 10);
    if (!Number.isFinite(parsed)) return "";

    const number = parsed / MEASURE_SCALE;
    return new Intl.NumberFormat("pt-BR", {
      minimumFractionDigits: 2,
      maximumFractionDigits: MEASURE_MAX_DECIMALS,
    }).format(number);
  }

  if (value === null || value === undefined) return "";
  if (typeof value === "number") {
    if (!Number.isFinite(value)) return "";
    return new Intl.NumberFormat("pt-BR", {
      minimumFractionDigits: 2,
      maximumFractionDigits: MEASURE_MAX_DECIMALS,
    }).format(value);
  }
  if (typeof value !== "string") return "";

  const normalized = value.replace(/\s/g, "").replace(/\./g, ",");
  if (!normalized) return "";

  if (normalized.includes(",")) {
    const [, fracRaw = ""] = normalized.split(",");
    if (fracRaw.replace(/\D/g, "").length > MEASURE_MAX_DECIMALS) {
      const digits = normalized.replace(/\D/g, "");
      if (!digits) return "";
      return formatDigitsAsMeasure(digits);
    }
    return sanitizeMeasureInput(normalized);
  }

  const digits = normalized.replace(/\D/g, "");
  if (!digits) return "";
  return formatDigitsAsMeasure(digits);
}

export function parseMeasureInput(value: unknown): number {
  const MEASURE_MAX_DECIMALS = 3;
  const MEASURE_SCALE = 10 ** MEASURE_MAX_DECIMALS;

  function sanitizeMeasureInput(raw: string): string {
    const normalized = raw
      .replace(/\s/g, "")
      .replace(/\./g, ",")
      .replace(/[^0-9,]/g, "");

    if (!normalized) return "";

    const commaIndex = normalized.indexOf(",");
    if (commaIndex === -1) {
      const intPart = normalized.replace(/^0+(?=\d)/, "");
      return intPart || "0";
    }

    const intRaw = normalized.slice(0, commaIndex).replace(/,/g, "");
    const fracRaw = normalized.slice(commaIndex + 1).replace(/,/g, "");
    const intPart = (intRaw || "0").replace(/^0+(?=\d)/, "");
    const fracPart = fracRaw.slice(0, MEASURE_MAX_DECIMALS);

    return `${intPart},${fracPart}`;
  }

  if (value === null || value === undefined) return 0;
  if (typeof value === "number") return Number.isFinite(value) ? value : 0;
  if (typeof value !== "string") return 0;

  const normalizedInput = value.replace(/\s/g, "").replace(/\./g, ",");
  if (!normalizedInput) return 0;

  if (normalizedInput.includes(",")) {
    const [, fracRaw = ""] = normalizedInput.split(",");
    if (fracRaw.replace(/\D/g, "").length > MEASURE_MAX_DECIMALS) {
      const digits = normalizedInput.replace(/\D/g, "");
      if (!digits) return 0;
      const parsedDigits = Number.parseInt(digits, 10);
      if (!Number.isFinite(parsedDigits)) return 0;
      return Math.round((parsedDigits / MEASURE_SCALE) * 1000) / 1000;
    }
  }

  if (!normalizedInput.includes(",")) {
    const digits = normalizedInput.replace(/\D/g, "");
    if (!digits) return 0;

    const parsedDigits = Number.parseInt(digits, 10);
    if (!Number.isFinite(parsedDigits)) return 0;
    return Math.round((parsedDigits / MEASURE_SCALE) * 1000) / 1000;
  }

  const sanitized = sanitizeMeasureInput(value);
  if (!sanitized) return 0;

  const normalized = sanitized.replace(",", ".");
  const parsed = Number.parseFloat(normalized);
  if (!Number.isFinite(parsed)) return 0;

  return Math.round(parsed * 1000) / 1000;
}

export function formatMoneyInput(value: unknown): string {
  if (value === null || value === undefined) return "";
  if (typeof value === "number") {
    if (!Number.isFinite(value)) return "";
    return new Intl.NumberFormat("pt-BR", {
      minimumFractionDigits: 2,
      maximumFractionDigits: 2,
    }).format(value);
  }
  if (typeof value !== "string") return "";
  const digits = value.replace(/\D/g, "");
  
  // Se não tem nada, retorna vazio
  if (!digits) return "";
  
  // Converte para número e divide por 100 para ter 2 casas decimais
  const number = parseInt(digits) / 100;
  
  // Formata usando Intl
  return new Intl.NumberFormat("pt-BR", {
    minimumFractionDigits: 2,
    maximumFractionDigits: 2,
  }).format(number);
}

export function parseMoneyInput(value: unknown): number {
  if (value === null || value === undefined) return 0;
  if (typeof value === "number") return Number.isFinite(value) ? value : 0;
  if (typeof value !== "string") return 0;
  
  const digits = value.replace(/\D/g, "");
  if (!digits) return 0;
  
  const number = parseInt(digits, 10) / 100;
  return isNaN(number) ? 0 : number;
}

export function formatPercentInput(value: string): string {
  if (!value) return "";
  const sanitized = value.replace(/[^\d,]/g, "");
  if (!sanitized) return "";
  const [intRaw, fracRaw] = sanitized.split(",");
  const intPart = (intRaw || "").replace(/^0+(?=\d)/, "") || "0";
  const fracPart = (fracRaw || "").replace(/\D/g, "").slice(0, 2);
  if (sanitized.includes(",")) return `${intPart},${fracPart}`;
  return intPart;
}

export function parsePercentInput(value: string): number {
  if (!value) return 0;
  const normalized = value.replace(/\./g, "").replace(",", ".");
  const number = parseFloat(normalized);
  return isNaN(number) ? 0 : number;
}

export function formatDateBr(value: string | null | undefined) {
  if (!value) return "";
  const normalized = value.split("T")[0];
  const parts = normalized.split("-");
  if (parts.length === 3 && parts[0].length === 4) {
    const [y, m, d] = parts;
    return `${d}/${m}/${y}`;
  }
  const dt = new Date(value);
  if (!Number.isFinite(dt.getTime())) return normalized;
  return dt.toLocaleDateString("pt-BR");
}

export function parseDateValue(value: string | Date | null | undefined) {
  if (!value) return null;
  if (value instanceof Date) {
    return Number.isFinite(value.getTime()) ? new Date(value) : null;
  }

  const normalized = String(value).trim();
  const dateOnly = /^(\d{4})-(\d{2})-(\d{2})$/.exec(normalized);
  if (dateOnly) {
    const year = Number(dateOnly[1]);
    const month = Number(dateOnly[2]);
    const day = Number(dateOnly[3]);
    const date = new Date(year, month - 1, day, 0, 0, 0, 0);
    return Number.isFinite(date.getTime()) ? date : null;
  }

  const date = new Date(normalized);
  return Number.isFinite(date.getTime()) ? date : null;
}

export function unitLabel(unitType: string) {
  switch (unitType) {
    case "meter":
      return "Metro";
    case "linear_meter":
      return "Metro Linear";
    case "square_meter":
      return "Metro Quadrado";
    case "box":
      return "Caixa";
    case "ream":
      return "Resma";
    case "kg":
      return "Quilo (kg)";
    case "l":
      return "Litro (l)";
    case "m":
      return "Metro (m)";
    case "m2":
      return "Metro Quadrado (m²)";
    case "unit":
    default:
      return "Unidade";
  }
}
