// ============================================================================
// GLOBAL DEBUGGING UTILITY
// ============================================================================

/**
 * Global debugging utility function for pretty-printing values
 *
 * This function is attached to the global scope and provides enhanced
 * console output for debugging purposes. It automatically formats
 * different data types appropriately.
 *
 * Features:
 * - Arrays: Display as console.table() for readability
 * - Objects: Display as formatted JSON with 2-space indentation
 * - Primitives: Display as regular console.log()
 * - Optional process exit for fatal debugging scenarios
 *
 * @param param - Value to print (any type)
 * @param isExit - Optional flag to exit process after printing (default: 0)
 *
 * @example
 * // Print array as table
 * pr([{id: 1, name: 'John'}, {id: 2, name: 'Jane'}]);
 *
 * @example
 * // Print object as formatted JSON
 * pr({user: {id: 1, name: 'John', roles: ['admin', 'user']}});
 *
 * @example
 * // Print primitive value
 * pr('Hello, World!');
 *
 * @example
 * // Print and exit (for fatal errors)
 * pr('Critical error occurred', 1);
 */
(global as any).pr = (param: any, isExit: number = 0): void => {
  // Format output based on data type
  if (Array.isArray(param)) {
    // Arrays: Use console.table for tabular data
    console.table(param);
  } else if (typeof param === 'object' && param !== null) {
    // Objects: Pretty-print JSON with indentation
    console.log(JSON.stringify(param, null, 2));
  } else {
    // Primitives: Standard console output
    console.log(param);
  }

  // Optional process exit (for debugging fatal scenarios)
  if (isExit === 1) {
    process.exit(1);
  }
};

// Ensure TypeScript knows about the global function
export {};

declare global {
  /**
   * Global debugging function for pretty-printing values
   *
   * @param param - Value to print (any type)
   * @param isExit - Optional flag to exit process after printing (default: 0)
   */
  function pr(param: any, isExit?: number): void;
}

// ============================================================================
// DATE FORMATTING UTILITY
// ============================================================================

/**
 * Formats a date string or object into a specified format
 *
 * Supports multiple input formats and intelligently detects the
 * date format to parse it correctly. Handles both slash (/) and
 * dash (-) separators.
 *
 * Supported input formats:
 * - DD-MM-YYYY or DD/MM/YYYY (day first)
 * - YYYY-MM-DD or YYYY/MM/DD (year first)
 *
 * Supported output placeholders:
 * - DD: Zero-padded day (01-31)
 * - MM: Zero-padded month (01-12)
 * - YYYY: Full year (2024)
 *
 * @param dateInput - Date to format (string, Date object, or timestamp)
 * @param format - Output format pattern (default: 'DD-MM-YYYY')
 * @returns Formatted date string, or empty string if input is falsy
 *
 * @example
 * // Format from various inputs
 * formatDate('2024-12-25'); // '25-12-2024'
 * formatDate('25/12/2024'); // '25-12-2024'
 * formatDate(new Date(2024, 11, 25), 'YYYY/MM/DD'); // '2024/12/25'
 * formatDate(1735084800000, 'MM-DD-YYYY'); // '12-25-2024' (timestamp)
 */
export const formatDate = (
  dateInput: any,
  format: string = 'DD-MM-YYYY',
): string => {
  // Handle null/undefined/empty input
  if (!dateInput) return '';

  // Convert everything to string for consistent parsing
  const dateStr = String(dateInput).trim();

  // Detect separator (support both / and -)
  const separator = dateStr.includes('/') ? '/' : '-';
  const parts = dateStr.split(separator).map(Number);

  // Validate we have exactly 3 parts (day, month, year)
  if (parts.length !== 3 || parts.some(isNaN)) {
    // Try parsing as ISO string or timestamp
    try {
      const date = new Date(dateInput);
      if (isNaN(date.getTime())) return '';

      const day = date.getDate();
      const month = date.getMonth() + 1; // Months are 0-indexed
      const year = date.getFullYear();

      return format
        .replace(/DD/, String(day).padStart(2, '0'))
        .replace(/MM/, String(month).padStart(2, '0'))
        .replace(/YYYY/, String(year));
    } catch {
      return ''; // Invalid date
    }
  }

  let day: number, month: number, year: number;

  // Intelligent format detection
  // If first part > 31, assume YYYY-MM-DD format
  if (parts[0] > 31) {
    year = parts[0];
    month = parts[1];
    day = parts[2];
  } else {
    // Otherwise assume DD-MM-YYYY format
    day = parts[0];
    month = parts[1];
    year = parts[2];
  }

  // Validate date components
  if (
    day < 1 ||
    day > 31 ||
    month < 1 ||
    month > 12 ||
    year < 1000 ||
    year > 9999
  ) {
    return '';
  }

  // Helper function for zero-padding
  const pad = (n: number) => String(n).padStart(2, '0');

  const DD = pad(day);
  const MM = pad(month);
  const YYYY = String(year);

  // Apply format replacements
  return format.replace(/DD/, DD).replace(/MM/, MM).replace(/YYYY/, YYYY);
};

// ============================================================================
// FINANCIAL YEAR UTILITY
// ============================================================================

/**
 * Gets the current financial year in YY-YY format
 *
 * Calculates the financial year based on the current date.
 * Assumes financial year runs from April 1 to March 31.
 *
 * Financial Year Logic:
 * - April 2024 to March 2025 → FY 2024-25 → returns '24-25'
 * - January 2024 to March 2024 → FY 2023-24 → returns '23-24'
 *
 * @returns Financial year string in 'YY-YY' format
 *
 * @example
 * // If current date is January 15, 2024
 * getFinancialYear(); // Returns '23-24'
 *
 * @example
 * // If current date is April 15, 2024
 * getFinancialYear(); // Returns '24-25'
 */
export function getFinancialYear(): string {
  const today = new Date();
  const currentYear = today.getFullYear();
  const currentMonth = today.getMonth() + 1; // 1 = January, 12 = December

  // Financial year starts from April (month 4)
  let fyStartYear = currentYear;

  // If current month is January-March, financial year started previous year
  if (currentMonth < 4) {
    fyStartYear = currentYear - 1;
  }

  const fyEndYear = fyStartYear + 1;

  // Convert to 2-digit year format
  const startYY = fyStartYear.toString().slice(-2);
  const endYY = fyEndYear.toString().slice(-2);

  return `${startYY}-${endYY}`;
}
