/**
 * Composable function for time field logic
 */
export function useTimeField() {
  function parseTimeString(str: string) {
    if (!str) return { hours: '', minutes: '', amPm: '' }
    const fullMatch = str.match(/^(\d{2}):?(\d{2})?(?:\s*(AM|PM))?$/)
    const minutesAmPmMatch = str.match(/^:(\d{2})\s*(AM|PM)$/)
    const hoursMatch = str.match(/^\d{2}$/)
    const minutesMatch = str.match(/^:(\d{2})$/)
    const ampmMatch = str.match(/^(AM|PM)$/)
    if (fullMatch) {
      return {
        hours: fullMatch[1] || '',
        minutes: fullMatch[2] || '',
        amPm: fullMatch[3] || '',
      }
    }
    if (minutesAmPmMatch) {
      return {
        hours: '',
        minutes: minutesAmPmMatch[1],
        amPm: minutesAmPmMatch[2],
      }
    }
    if (hoursMatch) {
      return {
        hours: str,
        minutes: '',
        amPm: '',
      }
    }
    if (minutesMatch) {
      return {
        hours: '',
        minutes: minutesMatch[1],
        amPm: '',
      }
    }
    if (ampmMatch) {
      return {
        hours: '',
        minutes: '',
        amPm: ampmMatch[1],
      }
    }
    return { hours: '', minutes: '', amPm: '' }
  }

  /**
   * Parse time string to total minutes since midnight
   * Handles both 24h and 12h (AM/PM) formats
   * Returns null if time string is malformed
   *
   * @param timeStr - Time string in format "HH:MM" or "HH:MM AM/PM"
   * @returns Total minutes since midnight, or null if parsing fails
   */
  function parseTimeToMinutes(timeStr: string): number | null {
    if (!timeStr || typeof timeStr !== 'string') {
      return null
    }

    let hours = 0
    let minutes = 0

    // Handle AM/PM format
    const ampmMatch = timeStr.trim().match(/^(\d{1,2}):(\d{2})\s?(AM|PM|am|pm)$/i)
    if (ampmMatch) {
      hours = parseInt(ampmMatch[1], 10)
      minutes = parseInt(ampmMatch[2], 10)
      const meridiem = ampmMatch[3].toUpperCase()

      // Validate hour range for 12h format
      if (hours < 1 || hours > 12) {
        return null
      }

      // Convert to 24h format
      if (meridiem === 'PM' && hours !== 12) {
        hours += 12
      } else if (meridiem === 'AM' && hours === 12) {
        hours = 0
      }
    } else {
      // Handle 24h format
      const match24h = timeStr.trim().match(/^(\d{1,2}):(\d{2})$/)
      if (match24h) {
        hours = parseInt(match24h[1], 10)
        minutes = parseInt(match24h[2], 10)
      } else {
        return null // Malformed time string
      }
    }

    // Validate hour and minute ranges
    if (hours < 0 || hours > 23 || minutes < 0 || minutes > 59) {
      return null
    }

    return hours * 60 + minutes
  }

  /**
   * Validate time format based on time format and field type
   * Returns true if time matches the expected format
   */
  function isValidTimeFormat(timeStr: string, timeFormat: string, timeFieldType?: string): boolean {
    if (!timeStr || typeof timeStr !== 'string') {
      return false
    }

    const trimmed = timeStr.trim()

    // Dropdown mode already ensures format, so only validate non-dropdown
    if (timeFieldType === 'dropdown') {
      if (timeFormat === 'ampm') {
        return /^(0?[1-9]|1[0-2]):[0-5]\d ?([AP]M|[ap]m)$/.test(trimmed)
      } else {
        return /^(?:[01]?\d|2[0-3]):[0-5]\d$/.test(trimmed)
      }
    }

    // Time-picker mode
    if (timeFieldType === 'time-picker') {
      return /^(?:[01]\d|2[0-3]):[0-5]\d(?:\s?(?:AM|PM|am|pm))?$/.test(trimmed)
    }

    // Input mode
    if (timeFormat === 'ampm') {
      return /^(0?[1-9]|1[0-2]):[0-5]\d (AM|PM|am|pm)$/.test(trimmed)
    } else {
      return /^(?:[01]\d|2[0-3]):[0-5]\d$/.test(trimmed)
    }
  }
  function isTimeInValidRange(
    timeStr: string,
    minTimeValue?: string | null,
    maxTimeValue?: string | null,
  ): { isInRange: boolean; error?: string } {
    // Empty or partial values are allowed
    if (!timeStr || timeStr === '__PARTIAL__') {
      return { isInRange: true }
    }

    const currentTimeMinutes = parseTimeToMinutes(timeStr)
    if (currentTimeMinutes === null) {
      return { isInRange: false, error: 'Invalid time format' }
    }

    const hasMin = minTimeValue !== null && minTimeValue !== undefined && minTimeValue !== ''
    const hasMax = maxTimeValue !== null && maxTimeValue !== undefined && maxTimeValue !== ''

    if (!hasMin && !hasMax) {
      return { isInRange: true }
    }

    // Parse min time
    let minTimeMinutes: number | null = null
    if (hasMin) {
      minTimeMinutes = parseTimeToMinutes(minTimeValue!)
      if (minTimeMinutes === null) {
        return { isInRange: false, error: `Malformed minimum time value: ${minTimeValue}` }
      }
    }

    // Parse max time
    let maxTimeMinutes: number | null = null
    if (hasMax) {
      maxTimeMinutes = parseTimeToMinutes(maxTimeValue!)
      if (maxTimeMinutes === null) {
        return { isInRange: false, error: `Malformed maximum time value: ${maxTimeValue}` }
      }
    }

    // Check range
    if (minTimeMinutes !== null && currentTimeMinutes < minTimeMinutes) {
      return { isInRange: false, error: `Time must be at or after ${minTimeValue}` }
    }

    if (maxTimeMinutes !== null && currentTimeMinutes > maxTimeMinutes) {
      return { isInRange: false, error: `Time must be at or before ${maxTimeValue}` }
    }

    return { isInRange: true }
  }

  function formatTimeString(hours: string, minutes: string, amPm: string) {
    if (!hours && !minutes && amPm) return amPm
    if (!hours && minutes && amPm) return `:${minutes} ${amPm}`
    if (hours && minutes) return amPm ? `${hours}:${minutes} ${amPm}` : `${hours}:${minutes}`
    if (hours) return hours
    if (minutes) return `:${minutes}`
    return ''
  }

  function getAmPmFromHours(hours: string): 'AM' | 'PM' {
    const h = parseInt(hours, 10)
    return h >= 12 ? 'PM' : 'AM'
  }

  function to24hFormat(time: string): string {
    if (!time) return ''
    const match = time.match(/^(\d{1,2}):(\d{2})\s*(AM|PM)?$/i)
    if (!match) return time
    let hours = parseInt(match[1], 10)
    const minutes = match[2]
    const ampm = match[3]?.toUpperCase()
    if (ampm === 'PM' && hours < 12) hours += 12
    if (ampm === 'AM' && hours === 12) hours = 0
    return `${hours.toString().padStart(2, '0')}:${minutes}`
  }

  return {
    parseTimeString,
    parseTimeToMinutes,
    isValidTimeFormat,
    isTimeInValidRange,
    formatTimeString,
    getAmPmFromHours,
    to24hFormat,
  }
}
