/**
 * Formata uma data do formato YYYY-MM-DD para DD/MM/YYYY sem problemas de timezone.
 * Resolve o bug de adiantamento/atraso de 1 dia causado pelo construtor new Date().
 * 
 * @param {string} dateString - Data no formato YYYY-MM-DD ou similar
 * @returns {string} Data formatada em DD/MM/YYYY
 */
export const formatDate = (dateString) => {
  if (!dateString) return '-';
  
  // Se a string contém apenas dígitos e hífens (formato ISO), fazer parsing manual para evitar timezone
  if (typeof dateString === 'string' && /^\d{4}-\d{2}-\d{2}/.test(dateString)) {
    const [year, month, day] = dateString.split('-').map(part => part.split('T')[0]);
    return `${day}/${month}/${year}`;
  }

  // Se a string já está no formato DD/MM/YYYY, retornar como está
  if (typeof dateString === 'string' && /^\d{2}\/\d{2}\/\d{4}/.test(dateString)) {
    return dateString;
  }
  
  // Se for objeto Date
  if (dateString instanceof Date) {
    const day = String(dateString.getDate()).padStart(2, '0');
    const month = String(dateString.getMonth() + 1).padStart(2, '0');
    const year = dateString.getFullYear();
    return `${day}/${month}/${year}`;
  }
  
  // Fallback para outros formatos (com try-catch)
  try {
    const date = new Date(dateString);
    if (isNaN(date.getTime())) return '-';
    
    // Fallback seguro se não for o padrão YYYY-MM-DD
    const day = String(date.getDate()).padStart(2, '0');
    const month = String(date.getMonth() + 1).padStart(2, '0');
    const year = date.getFullYear();
    return `${day}/${month}/${year}`;
  } catch {
    return dateString || '-';
  }
};

/**
 * Formata uma data com hora completa
 * @param {string} dateString - Data/hora
 * @returns {string} Data e hora formatadas (DD/MM/YYYY HH:mm:ss)
 */
export const formatDateTime = (dateString) => {
  if (!dateString) return '-';
  
  try {
    const date = new Date(dateString);
    if (isNaN(date.getTime())) return '-';
    
    return new Intl.DateTimeFormat('pt-BR', {
      day: '2-digit',
      month: '2-digit',
      year: 'numeric',
      hour: '2-digit',
      minute: '2-digit',
      second: '2-digit'
    }).format(date);
  } catch {
    return dateString || '-';
  }
};

/**
 * Formata valor monetário padrão Real Brasileiro
 * @param {number|string} value 
 * @returns {string} R$ 0,00
 */
export const formatCurrency = (value) => {
  if (value === null || value === undefined || value === '') return 'R$ 0,00';
  
  const num = typeof value === 'string' ? parseFloat(value.replace(',', '.')) : Number(value);
  
  if (isNaN(num)) return 'R$ 0,00';
  
  return new Intl.NumberFormat('pt-BR', {
    style: 'currency',
    currency: 'BRL',
    minimumFractionDigits: 2,
    maximumFractionDigits: 2
  }).format(num);
};

/**
 * Converte valor formatado em texto para número
 * @param {string} currencyText 
 * @returns {number}
 */
export const currencyToNumber = (currencyText) => {
  if (!currencyText) return 0;
  if (typeof currencyText === 'number') return currencyText;
  
  // Remove R$, espaços e pontos de milhar, troca vírgula por ponto
  const cleanValue = currencyText
    .replace('R$', '')
    .replace(/\s/g, '')
    .replace(/\./g, '')
    .replace(',', '.');
    
  return parseFloat(cleanValue) || 0;
};

/**
 * Converte string de moeda (R$ 1.234,56 ou 1234.56) em número.
 * @param {string|number} s 
 * @returns {number|string}
 */
export const parseCurrency = (s) => {
    if (s == null || s === '') return '';
    let t = String(s).trim().replace(/\s/g, '').replace(/R\$\s?/gi, '');
    if (!t) return '';
    
    // Com vírgula = BR: pontos são milhares, vírgula é decimal
    if (t.includes(',')) {
        t = t.replace(/\./g, '').replace(',', '.');
    } else if (t.includes('.')) {
        // Sem vírgula mas com ponto: "2.222.222.222" (BR milhares) vs "20.25" (US decimal)
        const lastDot = t.lastIndexOf('.');
        const afterDot = t.slice(lastDot + 1);
        const isLikelyUsDecimal = afterDot.length === 2 && /^\d\d$/.test(afterDot) && (t.match(/\./g) || []).length === 1;
        if (!isLikelyUsDecimal) {
            t = t.replace(/\./g, '');
        }
    }
    const n = parseFloat(t);
    return isNaN(n) ? '' : n;
};

/**
 * Formata um número para exibição em inputs (ex: 1234.56 -> "1.234,56")
 * @param {number|string} v 
 * @returns {string}
 */
export const formatCurrencyForInput = (v) => {
    if (v == null || v === '') return '';
    const n = Number(v);
    if (isNaN(n)) return '';
    return n.toLocaleString('pt-BR', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
};

/**
 * Formata data para gráfico (DD/MM)
 * @param {string} dateString 
 * @returns {string}
 */
export const formatDateForChart = (dateString) => {
    if (!dateString) return '-';
    try {
        // Se for DD/MM/YYYY
        if (dateString.includes('/')) {
            const parts = dateString.split('/');
            if (parts.length >= 2) return `${parts[0]}/${parts[1]}`;
        }
        // Se for YYYY-MM-DD
        if (dateString.includes('-')) {
            // Parse manual para evitar timezone (new Date() assume UTC e volta 1 dia no Brasil)
            const parts = dateString.split('T')[0].split('-');
            if (parts.length === 3) {
                const day = parts[2];
                const month = parts[1];
                return `${day}/${month}`;
            }
        }
        return dateString.substring(0, 5);
    } catch {
        return '-';
    }
};
/**
 * Formata o status do boleto para exibição amigável
 * @param {string} status 
 * @returns {string}
 */
export const formatStatus = (status) => {
    if (!status) return 'Pendente';
    const s = String(status).toUpperCase();
    const map = {
        'A_RECEBER': 'A Receber',
        'PENDENTE': 'Pendente',
        'ATRASADO': 'Atrasado',
        'VENCIDO': 'Vencido',
        'PAGO': 'Pago',
        'RECEBIDO': 'Recebido',
        'CANCELADO': 'Cancelado',
        'MARCADO_RECEBIDO': 'Marcado Recebido',
        'PIX': 'Pix'
    };
    return map[s] || status;
};

/**
 * Converte qualquer formato de data válido para YYYY-MM-DD.
 * Útil para campos <input type="date" />
 * @param {string|Date} dateString 
 * @returns {string} YYYY-MM-DD
 */
export const toISODate = (dateString) => {
    if (!dateString) return '';
    
    // Se já estiver no formato ISO YYYY-MM-DD, retorna o início da string
    if (typeof dateString === 'string' && /^\d{4}-\d{2}-\d{2}/.test(dateString)) {
        return dateString.substring(0, 10);
    }

    // Se estiver no formato brasileiro DD/MM/YYYY
    if (typeof dateString === 'string' && /^\d{2}\/\d{2}\/\d{4}/.test(dateString)) {
        const [day, month, year] = dateString.split('/');
        return `${year}-${month}-${day}`;
    }

    try {
        const date = new Date(dateString);
        if (isNaN(date.getTime())) return '';
        
        // Usamos UTC para evitar problemas de fuso horário vindo do backend
        const year = date.getUTCFullYear();
        const month = String(date.getUTCMonth() + 1).padStart(2, '0');
        const day = String(date.getUTCDate()).padStart(2, '0');
        
        return `${year}-${month}-${day}`;
    } catch {
        return '';
    }
};
