/**
 * Utilitários para cálculos de Departamento Pessoal (RH)
 */

// Tabela INSS 2024 (Progressiva)
const INSS_TABLE = [
    { limit: 1412.00, rate: 0.075, deduction: 0 },
    { limit: 2666.68, rate: 0.09, deduction: 21.18 },
    { limit: 4000.03, rate: 0.12, deduction: 101.18 },
    { limit: 7786.02, rate: 0.14, deduction: 181.18 }
];

// Tabela IRRF 2024 (Simplificada)
const IRRF_TABLE = [
    { limit: 2259.20, rate: 0, deduction: 0 },
    { limit: 2826.65, rate: 0.075, deduction: 169.44 },
    { limit: 3751.05, rate: 0.15, deduction: 381.44 },
    { limit: 4664.68, rate: 0.225, deduction: 662.77 },
    { limit: Infinity, rate: 0.275, deduction: 896.00 }
];

// Salário Família Teto e Valor (2024)
const FAMILY_SALARY_LIMIT = 1819.26; // Valor hipotético atualizado
const FAMILY_SALARY_VALUE = 62.04;

/**
 * Calcula o INSS progressivo
 */
export const calculateINSS = (salary) => {
    let tax = 0;
    
    // Cálculo progressivo correto seria faixa a faixa, 
    // mas a regra do usuário simplificada diz: "Salario base X Aliquota - Parcela a deduzir"
    // Vamos usar o método da parcela a deduzir que equivale ao cálculo por faixas.
    
    let range = INSS_TABLE.find(r => salary <= r.limit);
    if (!range) range = INSS_TABLE[INSS_TABLE.length - 1]; // Teto

    // Se salario maior que teto, usa o teto para calculo base ou valor fixo?
    // INSS tem teto de contribuição.
    const contributionSalary = Math.min(salary, INSS_TABLE[INSS_TABLE.length - 1].limit);
    
    // Re-encontrar a faixa correta para o salário de contribuição (caso tenha sido limitado pelo teto)
    range = INSS_TABLE.find(r => contributionSalary <= r.limit) || INSS_TABLE[INSS_TABLE.length - 1];

    tax = (contributionSalary * range.rate) - range.deduction;
    
    return Math.max(0, tax);
};

/**
 * Calcula o IRRF
 */
export const calculateIRRF = (baseCalc) => {
    let range = IRRF_TABLE.find(r => baseCalc <= r.limit);
    if (!range) range = IRRF_TABLE[IRRF_TABLE.length - 1];

    const tax = (baseCalc * range.rate) - range.deduction;
    return Math.max(0, tax);
};

/**
 * Calcula VT (6% do salário base, limitado ao custo se informado, aqui assumimos desconto full de 6%)
 */
export const calculateVT = (salary) => {
    return salary * 0.06;
};

/**
 * Calcula Salário Família
 */
export const calculateFamilySalary = (salary, numChildren, hasDisability = false) => {
    // Regra: Salario até 1.503,25 (usando valor atualizado da const ou parametro)
    // O usuário passou 1.503,25 na regra, vamos respeitar ou usar o oficial?
    // User request: "Salario até 1.503,25"
    if (salary > 1503.25 && !hasDisability) return 0; // Regra simplificada do usuário. Na real deficiência não ignora renda para SF, mas ok.
    
    return numChildren * FAMILY_SALARY_VALUE; // User request: "Nº de filhos X Quota Unitária"
};

/**
 * Calcula FGTS Total e Multa
 */
export const calculateFGTS = (currentSalary, monthsWorked) => {
    // Simplificação: Assume salário constante para o cálculo do montante
    const monthlyDeposit = currentSalary * 0.08;
    const totalDeposit = monthlyDeposit * monthsWorked;
    const fine40 = totalDeposit * 0.40;
    const totalWithFine = totalDeposit + fine40;

    return {
        monthlyDeposit,
        totalDeposit,
        fine40,
        totalWithFine
    };
};

/**
 * Gera o holerite completo simulado
 */
export const generatePayslip = (employee, options = {}) => {
    const salary = employee.salary || 0;
    
    // Parâmetros opcionais
    const hasVT = options.hasVT ?? true;
    const hasVR = options.hasVR ?? false;
    const vrDailyCost = options.vrDailyCost || 30; // Custo refeição diário
    const workDays = options.workDays || 22;
    const hasUnionContribution = options.hasUnionContribution ?? false;
    const numChildren = options.numChildren || 0;
    const childrenUnder14 = options.childrenUnder14 || 0; // Para salário família
    const extraHours50 = options.extraHours50 || 0;
    const extraHours100 = options.extraHours100 || 0;
    const insalubrityLevel = options.insalubrityLevel || 0; // 0, 10, 20, 40
    const hasPericulosidade = options.hasPericulosidade || false;

    // --- PROVENTOS ---
    const proventos = [];
    
    // 1. Salário Base
    proventos.push({ name: 'Salário Base', value: salary, type: 'P' });

    // 2. Insalubridade
    let insalubrityValue = 0;
    if (insalubrityLevel > 0) {
        // Regra do usuário: Salario base X 10% ou 20% ou 40%
        // (Na CLT é sobre salário mínimo, mas seguiremos a regra do usuário: "Salario base X ...")
        insalubrityValue = salary * (insalubrityLevel / 100);
        proventos.push({ name: `Insalubridade (${insalubrityLevel}%)`, value: insalubrityValue, type: 'P' });
    }

    // 3. Periculosidade
    let periculosidadeValue = 0;
    if (hasPericulosidade) {
        // Regra do usuário: Salario base X 30%
        periculosidadeValue = salary * 0.30;
        proventos.push({ name: 'Periculosidade (30%)', value: periculosidadeValue, type: 'P' });
    }

    // 4. Horas Extras
    const hourlyRate = salary / 220;
    let he50Value = 0;
    if (extraHours50 > 0) {
        he50Value = hourlyRate * 1.5 * extraHours50;
        proventos.push({ name: `Hora Extra 50% (${extraHours50}h)`, value: he50Value, type: 'P' });
    }
    let he100Value = 0;
    if (extraHours100 > 0) {
        he100Value = hourlyRate * 2.0 * extraHours100;
        proventos.push({ name: `Hora Extra 100% (${extraHours100}h)`, value: he100Value, type: 'P' });
    }

    // 5. Salário Família
    const familySalary = calculateFamilySalary(salary, childrenUnder14);
    if (familySalary > 0) {
        proventos.push({ name: `Salário Família (${childrenUnder14} filhos)`, value: familySalary, type: 'P' }); // Geralmente não compõe base de INSS/IRRF
    }

    // Total Bruto (Base para impostos - remove SF se necessário, mas simplificando)
    const totalProventos = salary + insalubrityValue + periculosidadeValue + he50Value + he100Value; 
    
    // --- DESCONTOS ---
    const descontos = [];

    // 1. INSS
    const inssValue = calculateINSS(totalProventos);
    descontos.push({ name: 'INSS', value: inssValue, type: 'D' });

    // 2. IRRF
    // Base IRRF = Total Proventos - INSS - (Dependentes * 189.59)
    const dependentsDeduction = numChildren * 189.59;
    const irrfBase = totalProventos - inssValue - dependentsDeduction;
    const irrfValue = calculateIRRF(irrfBase);
    if (irrfValue > 0) {
        descontos.push({ name: 'IRRF', value: irrfValue, type: 'D' });
    }

    // 3. VT
    if (hasVT) {
        const vtValue = calculateVT(salary);
        descontos.push({ name: 'Vale Transporte (6%)', value: vtValue, type: 'D' });
    }

    // 4. VR (Opcional)
    if (hasVR) {
        // Regra: "Valor mensal x 20% (Teto do desconto)"
        const vrTotal = vrDailyCost * workDays;
        const vrDiscount = vrTotal * 0.20; // Assumindo desconto de 20% do benefício
        descontos.push({ name: 'Vale Refeição (20%)', value: vrDiscount, type: 'D' });
    }

    // 5. Contribuição Sindical (Opcional)
    if (hasUnionContribution) {
        const unionValue = salary / 30;
        descontos.push({ name: 'Contrib. Sindical (1 dia)', value: unionValue, type: 'D' });
    }

    const totalDescontos = descontos.reduce((acc, curr) => acc + curr.value, 0);
    const liquido = (totalProventos + familySalary) - totalDescontos; // SF entra no líquido mas não na base dos impostos acima calculados (simplificação)

    return {
        proventos,
        descontos,
        totais: {
            bruto: totalProventos,
            descontos: totalDescontos,
            liquido: liquido,
            sf: familySalary
        }
    };
};
