<?php

namespace PloverCRM\Core\Helpers;

/**
 * DateTime Helper
 * 
 * Centralized date/datetime parsing and normalization for all CRM providers.
 * Supports 20+ common date formats from various form plugins.
 */
class DateTimeHelper
{
  /**
   * Common date formats used by form plugins
   */
  private const DATE_FORMATS = [
    'd/m/Y',        // 06/02/2026
    'd-m-Y',        // 06-02-2026
    'd.m.Y',        // 06.02.2026
    'M/d/Y',        // Feb/06/2026
    'M-d-Y',        // Feb-06-2026
    'M.d.Y',        // Feb.06.2026
    'F/d/Y',        // February/06/2026
    'F-d-Y',        // February-06-2026
    'F.d.Y',        // February.06.2026
    'd/M/Y',        // 06/Feb/2026
    'd-M-Y',        // 06-Feb-2026
    'd.M.Y',        // 06.Feb.2026
    'd/F/Y',        // 06/February/2026
    'd-F-Y',        // 06-February-2026
    'd.F.Y',        // 06.February.2026
    'Y/m/d',        // 2026/02/06
    'Y.m.d',        // 2026.02.06
    'd M Y',        // 06 Feb 2026
    'd F Y',        // 06 February 2026
    'M d, Y',       // Feb 06, 2026
    'F d, Y',       // February 06, 2026
  ];

  /**
   * Common datetime formats used by form plugins
   */
  private const DATETIME_FORMATS = [
    'd/m/Y h:i A',      // 06/02/2026 12:00 PM
    'd/m/Y H:i',        // 06/02/2026 12:00
    'd-m-Y h:i A',      // 06-02-2026 12:00 PM
    'd-m-Y H:i',        // 06-02-2026 12:00
    'd.m.Y h:i A',      // 06.02.2026 12:00 PM
    'd.m.Y H:i',        // 06.02.2026 12:00
    'm/d/Y h:i A',      // 02/06/2026 12:00 PM
    'm/d/Y H:i',        // 02/06/2026 12:00
    'm-d-Y h:i A',      // 02-06-2026 12:00 PM
    'm-d-Y H:i',        // 02-06-2026 12:00
    'Y/m/d H:i',        // 2026/02/06 12:00
    'Y-m-d H:i',        // 2026-02-06 12:00
    'Y.m.d H:i',        // 2026.02.06 12:00
    'd M Y h:i A',      // 06 Feb 2026 12:00 PM
    'd M Y H:i',        // 06 Feb 2026 12:00
    'd F Y h:i A',      // 06 February 2026 12:00 PM
    'd F Y H:i',        // 06 February 2026 12:00
    'M d, Y h:i A',     // Feb 06, 2026 12:00 PM
    'M d, Y H:i',       // Feb 06, 2026 12:00
    'F d, Y h:i A',     // February 06, 2026 12:00 PM
    'F d, Y H:i',       // February 06, 2026 12:00
  ];

  /**
   * Validate if a value is a valid date
   * 
   * @param string $value Date string to validate
   * @return bool True if valid date
   */
  public static function isValidDate(string $value): bool
  {
    if (empty($value)) {
      return false;
    }

    // Try strtotime first (handles many formats)
    $timestamp = strtotime($value);
    if ($timestamp !== false) {
      return true;
    }

    // Try specific formats
    foreach (self::DATE_FORMATS as $format) {
      $parsed = \DateTime::createFromFormat($format, $value);
      if ($parsed !== false && $parsed->format($format) === $value) {
        return true;
      }
    }

    return false;
  }

  /**
   * Validate if a value is a valid datetime
   * 
   * @param string $value DateTime string to validate
   * @return bool True if valid datetime
   */
  public static function isValidDateTime(string $value): bool
  {
    if (empty($value)) {
      return false;
    }

    // Try strtotime first (handles many formats)
    $timestamp = strtotime($value);
    if ($timestamp !== false) {
      return true;
    }

    // Try specific formats
    foreach (self::DATETIME_FORMATS as $format) {
      $parsed = \DateTime::createFromFormat($format, $value);
      if ($parsed !== false && $parsed->format($format) === $value) {
        return true;
      }
    }

    return false;
  }

  /**
   * Normalize date value to specified format
   * 
   * @param string $value Date string to normalize
   * @param string $outputFormat Output format (default: Y-m-d)
   * @return string Normalized date or original value if parsing fails
   */
  public static function normalizeDate(string $value, string $outputFormat = 'Y-m-d'): string
  {
    if (empty($value)) {
      return $value;
    }

    // Try strtotime first (handles many formats)
    $timestamp = strtotime($value);
    if ($timestamp !== false) {
      return date($outputFormat, $timestamp);
    }

    // Try specific formats
    foreach (self::DATE_FORMATS as $format) {
      $parsed = \DateTime::createFromFormat($format, $value);
      if ($parsed !== false && $parsed->format($format) === $value) {
        return $parsed->format($outputFormat);
      }
    }

    // Return original value if parsing fails
    return $value;
  }

  /**
   * Normalize datetime value to specified format
   * 
   * @param string $value DateTime string to normalize
   * @param string $outputFormat Output format (default: Y-m-d H:i:s)
   * @return string Normalized datetime or original value if parsing fails
   */
  public static function normalizeDateTime(string $value, string $outputFormat = 'Y-m-d H:i:s'): string
  {
    if (empty($value)) {
      return $value;
    }

    // Try strtotime first (handles many formats)
    $timestamp = strtotime($value);
    if ($timestamp !== false) {
      return date($outputFormat, $timestamp);
    }

    // Try specific formats
    foreach (self::DATETIME_FORMATS as $format) {
      $parsed = \DateTime::createFromFormat($format, $value);
      if ($parsed !== false && $parsed->format($format) === $value) {
        return $parsed->format($outputFormat);
      }
    }

    // Return original value if parsing fails
    return $value;
  }

  /**
   * Get all supported date formats
   * 
   * @return array Array of date format strings
   */
  public static function getSupportedDateFormats(): array
  {
    return self::DATE_FORMATS;
  }

  /**
   * Get all supported datetime formats
   * 
   * @return array Array of datetime format strings
   */
  public static function getSupportedDateTimeFormats(): array
  {
    return self::DATETIME_FORMATS;
  }
}
