/**
 * TDS (Tax Deducted at Source) Calculation Utilities for Indian Income Tax
 * Production-ready payroll-grade TDS calculation with FY-based configuration
 * Supports latest Indian income tax rules, surcharge, marginal relief, and cess
 */

// Supported Financial Years
export type FinancialYear = "FY_2024_25" | "FY_2025_26";

// Tax slab structure
export interface TaxSlab {
  min: number;
  max: number;
  rate: number;
}

// Surcharge thresholds and rates
export interface SurchargeConfig {
  thresholds: Array<{
    min: number;
    max: number;
    rate: number;
  }>;
  newRegimeCap: number; // 25% cap for new regime
}

// FY-specific tax configuration
export interface FYTaxConfig {
  taxSlabs: {
    OLD_REGIME: TaxSlab[];
    NEW_REGIME: TaxSlab[];
  };
  standardDeduction: {
    OLD_REGIME: number;
    NEW_REGIME: number;
  };
  section87ARebate: {
    OLD_REGIME: {
      INCOME_LIMIT: number;
      MAX_REBATE: number;
    };
    NEW_REGIME: {
      INCOME_LIMIT: number;
      MAX_REBATE: number;
    };
  };
  surcharge: SurchargeConfig;
  cessRate: number;
  hraExemptionRate: number; // Only for old regime
}

// Financial Year Configurations
export const FY_CONFIGS: Record<FinancialYear, FYTaxConfig> = {
  FY_2024_25: {
    taxSlabs: {
      OLD_REGIME: [
        { min: 0, max: 250000, rate: 0 },
        { min: 250000, max: 500000, rate: 5 },
        { min: 500000, max: 1000000, rate: 20 },
        { min: 1000000, max: Infinity, rate: 30 },
      ],
      NEW_REGIME: [
        { min: 0, max: 300000, rate: 0 },
        { min: 300000, max: 600000, rate: 5 },
        { min: 600000, max: 900000, rate: 10 },
        { min: 900000, max: 1200000, rate: 15 },
        { min: 1200000, max: 1500000, rate: 20 },
        { min: 1500000, max: Infinity, rate: 30 },
      ],
    },
    standardDeduction: {
      OLD_REGIME: 50000,
      NEW_REGIME: 75000,
    },
    section87ARebate: {
      OLD_REGIME: {
        INCOME_LIMIT: 500000,
        MAX_REBATE: 12500,
      },
      NEW_REGIME: {
        INCOME_LIMIT: 700000,
        MAX_REBATE: Infinity,
      },
    },
    surcharge: {
      thresholds: [
        { min: 0, max: 5000000, rate: 0 },
        { min: 5000000, max: 10000000, rate: 10 },
        { min: 10000000, max: 20000000, rate: 15 },
        { min: 20000000, max: 50000000, rate: 25 },
        { min: 50000000, max: Infinity, rate: 37 },
      ],
      newRegimeCap: 25,
    },
    cessRate: 4,
    hraExemptionRate: 0.5,
  },
  FY_2025_26: {
    taxSlabs: {
      OLD_REGIME: [
        { min: 0, max: 250000, rate: 0 },
        { min: 250000, max: 500000, rate: 5 },
        { min: 500000, max: 1000000, rate: 20 },
        { min: 1000000, max: Infinity, rate: 30 },
      ],
      NEW_REGIME: [
        { min: 0, max: 400000, rate: 0 }, // 0–4L → 0%
        { min: 400000, max: 800000, rate: 5 }, // 4–8L → 5%
        { min: 800000, max: 1200000, rate: 10 }, // 8–12L → 10%
        { min: 1200000, max: 1600000, rate: 15 }, // 12–16L → 15%
        { min: 1600000, max: 2000000, rate: 20 }, // 16–20L → 20%
        { min: 2000000, max: 2400000, rate: 25 }, // 20–24L → 25%
        { min: 2400000, max: Infinity, rate: 30 }, // Above 24L → 30%
      ],
    },
    standardDeduction: {
      OLD_REGIME: 50000,
      NEW_REGIME: 75000,
    },
    section87ARebate: {
      OLD_REGIME: {
        INCOME_LIMIT: 500000,
        MAX_REBATE: 12500,
      },
      NEW_REGIME: {
        INCOME_LIMIT: 1200000, // Updated to ₹12,00,000
        MAX_REBATE: 60000, // Updated to ₹60,000
      },
    },
    surcharge: {
      thresholds: [
        { min: 0, max: 5000000, rate: 0 },
        { min: 5000000, max: 10000000, rate: 10 },
        { min: 10000000, max: 20000000, rate: 15 },
        { min: 20000000, max: 50000000, rate: 25 },
        { min: 50000000, max: Infinity, rate: 37 },
      ],
      newRegimeCap: 25,
    },
    cessRate: 4,
    hraExemptionRate: 0.5,
  },
};

// Import types from employee service to maintain consistency
import type {
  SalarySetting,
  SalarySettingOption,
} from "@/lib/services/employeeService";

// Enhanced TDS calculation parameters with payroll support
export interface TdsCalculationParams {
  financialYear: FinancialYear;
  annualGrossSalary: number;
  basicSalary: number;
  regimeType: "old" | "new";
  salarySettings: SalarySetting[];
  salarySettingsOptions: SalarySettingOption[];
  taxAlreadyDeducted?: number; // For payroll calculations
  remainingMonths?: number; // For payroll calculations
}

// Helper function to get FY configuration
export const getFYConfig = (fy: FinancialYear): FYTaxConfig => {
  return FY_CONFIGS[fy];
};

/**
 * Calculate HRA exemption based on Indian tax rules (FY-aware)
 */
export const calculateHraExemption = (
  basicSalary: number,
  hraReceived: number,
  regimeType: "old" | "new",
  fyConfig: FYTaxConfig
): number => {
  if (regimeType === "new") {
    return 0; // No HRA exemption under new regime
  }

  if (hraReceived <= 0) {
    return 0;
  }

  // HRA exemption is minimum of:
  // 1. Actual HRA received
  // 2. 50% of basic salary (for metro cities) or 40% (for non-metro)
  // 3. Actual rent paid minus 10% of basic salary (not implemented here as we don't have rent data)

  const maxExemption = basicSalary * fyConfig.hraExemptionRate;
  return Math.min(hraReceived, maxExemption);
};

/**
 * Calculate surcharge based on taxable income and regime
 */
export const calculateSurcharge = (
  taxableIncome: number,
  incomeTax: number,
  regimeType: "old" | "new",
  fyConfig: FYTaxConfig
): number => {
  if (incomeTax <= 0) {
    return 0;
  }

  // Find applicable surcharge rate
  let surchargeRate = 0;
  for (const threshold of fyConfig.surcharge.thresholds) {
    if (taxableIncome > threshold.min && taxableIncome <= threshold.max) {
      surchargeRate = threshold.rate;
      break;
    }
  }

  if (surchargeRate === 0) {
    return 0;
  }

  // Calculate surcharge
  let surcharge = (incomeTax * surchargeRate) / 100;

  // Apply 25% cap for new regime
  if (regimeType === "new" && surchargeRate > fyConfig.surcharge.newRegimeCap) {
    surcharge = (incomeTax * fyConfig.surcharge.newRegimeCap) / 100;
  }

  return Math.round(surcharge);
};

/**
 * Calculate marginal relief for surcharge
 * Ensures that tax + surcharge doesn't exceed tax at threshold + excess income
 */
export const calculateMarginalRelief = (
  taxableIncome: number,
  incomeTax: number,
  surcharge: number,
  fyConfig: FYTaxConfig
): number => {
  // Find the surcharge threshold that applies
  let applicableThreshold = 0;
  for (const threshold of fyConfig.surcharge.thresholds) {
    if (taxableIncome > threshold.min && taxableIncome <= threshold.max) {
      applicableThreshold = threshold.min;
      break;
    }
  }

  if (applicableThreshold === 0) {
    return 0; // No marginal relief needed
  }

  // Calculate tax at threshold (without surcharge)
  const excessIncome = taxableIncome - applicableThreshold;
  const totalTaxWithSurcharge = incomeTax + surcharge;
  const maxAllowedTax = incomeTax + excessIncome;

  if (totalTaxWithSurcharge > maxAllowedTax) {
    return totalTaxWithSurcharge - maxAllowedTax;
  }

  return 0;
};

/**
 * Calculate taxable income based on Indian government tax rules
 * Taxable Income = Annual Gross Salary - Standard Deduction
 */
export const calculateTaxableIncome = (
  params: TdsCalculationParams
): number => {
  const { financialYear, annualGrossSalary, regimeType } = params;
  const fyConfig = getFYConfig(financialYear);

  // Apply FY-aware standard deduction
  const standardDeduction =
    regimeType === "old"
      ? fyConfig.standardDeduction.OLD_REGIME
      : fyConfig.standardDeduction.NEW_REGIME;

  // Taxable Income = Annual Gross Salary - Standard Deduction
  const taxableIncome = Math.max(0, annualGrossSalary - standardDeduction);

  return taxableIncome;
};

/**
 * Calculate salary breakdown for display purposes only
 * This does NOT affect taxable income calculation
 */
export const calculateSalaryBreakdownForDisplay = (
  params: TdsCalculationParams
): {
  basicSalary: number;
  earnings: Array<{ code: string; name: string; amount: number; taxable: boolean }>;
  deductions: Array<{ code: string; name: string; amount: number }>;
  hraExemption: number;
  totalEarnings: number;
  totalDeductions: number;
} => {
  const {
    financialYear,
    basicSalary,
    regimeType,
    salarySettings,
    salarySettingsOptions,
  } = params;

  const fyConfig = getFYConfig(financialYear);
  const annualBasicSalary = basicSalary * 12;
  
  const earnings: Array<{ code: string; name: string; amount: number; taxable: boolean }> = [];
  const deductions: Array<{ code: string; name: string; amount: number }> = [];
  let hraExemption = 0;

  // Add basic salary
  earnings.push({
    code: "BASIC",
    name: "Basic Salary",
    amount: annualBasicSalary,
    taxable: true
  });

  // Process salary settings for display
  salarySettings.forEach((setting) => {
    const settingOption = salarySettingsOptions.find(
      (option) => option.id === setting.salary_setting_id
    );

    if (!settingOption) return;

    // Calculate the actual monthly amount based on type
    let monthlyAmount = 0;
    if (settingOption.type_value === "percentage") {
      const percentage = parseFloat(setting.individual_value) || 0;
      monthlyAmount = (basicSalary * percentage) / 100;
    } else {
      monthlyAmount = parseFloat(setting.individual_value) || 0;
    }

    const annualAmount = monthlyAmount * 12;

    if (settingOption.type === "earning") {
      let isTaxable = settingOption.is_taxable === 1 || settingOption.is_taxable === undefined;
      
      // Calculate HRA exemption for display
      if (settingOption.code === "HRA") {
        hraExemption = calculateHraExemption(
          basicSalary,
          monthlyAmount,
          regimeType,
          fyConfig
        ) * 12;
      }

      earnings.push({
        code: settingOption.code,
        name: settingOption.name,
        amount: annualAmount,
        taxable: isTaxable
      });
    } else if (settingOption.type === "deduction") {
      deductions.push({
        code: settingOption.code,
        name: settingOption.name,
        amount: annualAmount
      });
    }
  });

  const totalEarnings = earnings.reduce((sum, item) => sum + item.amount, 0);
  const totalDeductions = deductions.reduce((sum, item) => sum + item.amount, 0);

  return {
    basicSalary: annualBasicSalary,
    earnings,
    deductions,
    hraExemption,
    totalEarnings,
    totalDeductions,
  };
};

/**
 * Calculate income tax based on progressive tax slabs (FY-aware)
 */
export const calculateIncomeTax = (
  taxableIncome: number,
  regimeType: "old" | "new",
  fyConfig: FYTaxConfig
): number => {
  const slabs =
    regimeType === "old" ? fyConfig.taxSlabs.OLD_REGIME : fyConfig.taxSlabs.NEW_REGIME;

  let tax = 0;

  for (const slab of slabs) {
    if (taxableIncome <= slab.min) {
      break;
    }

    const taxableInThisSlab = Math.min(taxableIncome, slab.max) - slab.min;
    tax += (taxableInThisSlab * slab.rate) / 100;
  }

  return Math.round(tax);
};

/**
 * Check if taxpayer is eligible for Section 87A rebate (FY-aware)
 */
export const isEligibleForSection87A = (
  taxableIncome: number,
  regimeType: "old" | "new",
  fyConfig: FYTaxConfig
): boolean => {
  const rebateConfig =
    regimeType === "old"
      ? fyConfig.section87ARebate.OLD_REGIME
      : fyConfig.section87ARebate.NEW_REGIME;

  return taxableIncome <= rebateConfig.INCOME_LIMIT;
};

/**
 * Calculate Section 87A rebate based on taxable income and regime (FY-aware)
 */
export const calculateSection87ARebate = (
  taxableIncome: number,
  incomeTax: number,
  regimeType: "old" | "new",
  fyConfig: FYTaxConfig
): number => {
  // Check eligibility first
  if (!isEligibleForSection87A(taxableIncome, regimeType, fyConfig)) {
    return 0; // No rebate if not eligible
  }

  const rebateConfig =
    regimeType === "old"
      ? fyConfig.section87ARebate.OLD_REGIME
      : fyConfig.section87ARebate.NEW_REGIME;

  // Apply rebate up to maximum limit for both regimes
  // Special case: If MAX_REBATE is Infinity, give full tax as rebate (for older FY configs)
  if (rebateConfig.MAX_REBATE === Infinity) {
    return incomeTax;
  } else {
    // Normal case: Rebate up to maximum limit
    return Math.min(incomeTax, rebateConfig.MAX_REBATE);
  }
};

/**
 * Calculate Health and Education Cess (FY-aware rate on tax + surcharge)
 */
export const calculateCess = (
  incomeTax: number,
  surcharge: number,
  fyConfig: FYTaxConfig
): number => {
  const taxPlusSurcharge = incomeTax + surcharge;
  return Math.round((taxPlusSurcharge * fyConfig.cessRate) / 100);
};

/**
 * Enhanced TDS calculation with surcharge, marginal relief, and cess
 */
export const calculateAnnualTax = (params: TdsCalculationParams): number => {
  try {
    const fyConfig = getFYConfig(params.financialYear);
    const taxableIncome = calculateTaxableIncome(params);

    if (taxableIncome <= 0) {
      return 0;
    }

    // Step 1: Calculate income tax based on progressive slabs
    const grossIncomeTax = calculateIncomeTax(
      taxableIncome,
      params.regimeType,
      fyConfig
    );

    // Step 2: Apply Section 87A rebate
    const section87ARebate = calculateSection87ARebate(
      taxableIncome,
      grossIncomeTax,
      params.regimeType,
      fyConfig
    );

    // Step 3: Income tax after rebate
    const incomeTaxAfterRebate = Math.max(0, grossIncomeTax - section87ARebate);

    // Step 4: Calculate surcharge
    const surcharge = calculateSurcharge(
      taxableIncome,
      incomeTaxAfterRebate,
      params.regimeType,
      fyConfig
    );

    // Step 5: Apply marginal relief
    const marginalRelief = calculateMarginalRelief(
      taxableIncome,
      incomeTaxAfterRebate,
      surcharge,
      fyConfig
    );

    const surchargeAfterRelief = Math.max(0, surcharge - marginalRelief);

    // Step 6: Calculate cess on (tax + surcharge)
    const cess = calculateCess(incomeTaxAfterRebate, surchargeAfterRelief, fyConfig);

    // Step 7: Total tax liability
    const totalTax = incomeTaxAfterRebate + surchargeAfterRelief + cess;

    return Math.round(totalTax);
  } catch (error) {
    return 0;
  }
};

/**
 * Payroll-grade monthly TDS calculation
 * Considers tax already deducted and remaining months
 */
export const calculateMonthlyTdsPayroll = (
  params: TdsCalculationParams
): number => {
  const annualTax = calculateAnnualTax(params);
  const taxAlreadyDeducted = params.taxAlreadyDeducted || 0;
  const remainingMonths = params.remainingMonths || 12;

  if (remainingMonths <= 0) {
    return 0;
  }

  const remainingTax = Math.max(0, annualTax - taxAlreadyDeducted);
  return Math.round(remainingTax / remainingMonths);
};

/**
 * Calculate monthly TDS from annual TDS (legacy function)
 */
export const calculateMonthlyTds = (annualTds: number): number => {
  return Math.round(annualTds / 12);
};

/**
 * Legacy function for backward compatibility
 */
export const calculateTdsAmountFE = (params: TdsCalculationParams): number => {
  return calculateAnnualTax(params);
};

/**
 * Enhanced detailed tax calculation breakdown
 */
export interface TaxCalculationBreakdown {
  financialYear: FinancialYear;
  regimeType: "old" | "new";
  annualGrossSalary: number;
  standardDeduction: number;
  taxableIncome: number;
  grossIncomeTax: number;
  section87AEligible: boolean;
  section87ARebate: number;
  incomeTaxAfterRebate: number;
  surcharge: number;
  marginalRelief: number;
  surchargeAfterRelief: number;
  cess: number;
  totalTax: number;
  taxAlreadyDeducted: number;
  remainingMonths: number;
  monthlyTds: number;
  salaryBreakdown?: ReturnType<typeof calculateSalaryBreakdownForDisplay>;
}

/**
 * Calculate detailed TDS breakdown with all components (enhanced)
 */
export const calculateTdsBreakdown = (
  params: TdsCalculationParams
): TaxCalculationBreakdown => {
  const fyConfig = getFYConfig(params.financialYear);
  const standardDeduction = params.regimeType === "old" 
    ? fyConfig.standardDeduction.OLD_REGIME 
    : fyConfig.standardDeduction.NEW_REGIME;
  
  const taxableIncome = calculateTaxableIncome(params);
  const grossIncomeTax = calculateIncomeTax(taxableIncome, params.regimeType, fyConfig);
  const section87AEligible = isEligibleForSection87A(
    taxableIncome,
    params.regimeType,
    fyConfig
  );
  const section87ARebate = calculateSection87ARebate(
    taxableIncome,
    grossIncomeTax,
    params.regimeType,
    fyConfig
  );
  const incomeTaxAfterRebate = Math.max(0, grossIncomeTax - section87ARebate);
  const surcharge = calculateSurcharge(
    taxableIncome,
    incomeTaxAfterRebate,
    params.regimeType,
    fyConfig
  );
  const marginalRelief = calculateMarginalRelief(
    taxableIncome,
    incomeTaxAfterRebate,
    surcharge,
    fyConfig
  );
  const surchargeAfterRelief = Math.max(0, surcharge - marginalRelief);
  const cess = calculateCess(incomeTaxAfterRebate, surchargeAfterRelief, fyConfig);
  const totalTax = incomeTaxAfterRebate + surchargeAfterRelief + cess;
  const taxAlreadyDeducted = params.taxAlreadyDeducted || 0;
  const remainingMonths = params.remainingMonths || 12;
  const monthlyTds = calculateMonthlyTdsPayroll(params);
  const salaryBreakdown = calculateSalaryBreakdownForDisplay(params);

  return {
    financialYear: params.financialYear,
    regimeType: params.regimeType,
    annualGrossSalary: params.annualGrossSalary,
    standardDeduction,
    taxableIncome,
    grossIncomeTax,
    section87AEligible,
    section87ARebate,
    incomeTaxAfterRebate,
    surcharge,
    marginalRelief,
    surchargeAfterRelief,
    cess,
    totalTax,
    taxAlreadyDeducted,
    remainingMonths,
    monthlyTds,
    salaryBreakdown,
  };
};

/**
 * Main exported function for payroll-grade monthly TDS calculation
 * This is the primary function to be used by the application
 */
export const computeMonthlyTds = (
  fy: FinancialYear,
  regime: "old" | "new",
  input: {
    annualGrossSalary: number;
    basicSalary: number;
    salarySettings: SalarySetting[];
    salarySettingsOptions: SalarySettingOption[];
    taxAlreadyDeducted?: number;
    remainingMonths?: number;
  }
): {
  monthlyTds: number;
  annualTax: number;
  breakdown: TaxCalculationBreakdown;
} => {
  const params: TdsCalculationParams = {
    financialYear: fy,
    annualGrossSalary: input.annualGrossSalary,
    basicSalary: input.basicSalary,
    regimeType: regime,
    salarySettings: input.salarySettings,
    salarySettingsOptions: input.salarySettingsOptions,
    taxAlreadyDeducted: input.taxAlreadyDeducted,
    remainingMonths: input.remainingMonths,
  };

  console.log("params", params);

  const monthlyTds = calculateMonthlyTdsPayroll(params);
  const annualTax = calculateAnnualTax(params);
  const breakdown = calculateTdsBreakdown(params);

  return {
    monthlyTds,
    annualTax,
    breakdown,
  };
};

/**
 * Utility function to get available financial years
 */
export const getAvailableFinancialYears = (): FinancialYear[] => {
  return Object.keys(FY_CONFIGS) as FinancialYear[];
};

/**
 * Utility function to get current financial year based on date
 */
export const getCurrentFinancialYear = (date: Date = new Date()): FinancialYear => {
  const year = date.getFullYear();
  const month = date.getMonth() + 1; // JavaScript months are 0-indexed

  // Indian FY runs from April 1 to March 31
  if (month >= 4) {
    // April to December - current FY
    const fyYear = year + 1;
    return `FY_${year}_${fyYear.toString().slice(-2)}` as FinancialYear;
  } else {
    // January to March - previous FY
    const fyYear = year;
    const prevYear = year - 1;
    return `FY_${prevYear}_${fyYear.toString().slice(-2)}` as FinancialYear;
  }
};

/**
 * Format currency for display
 */
export const formatCurrency = (
  amount: number,
  currency: string = "₹"
): string => {
  return `${currency}${amount.toLocaleString("en-IN")}`;
};
