<?php
/**
 * Event Validator
 *
 * Centralized validation logic for event data
 *
 * @package NemtlyBooking
 * @since   PBOOKING_SINCE
 */

namespace NemtlyBooking\Services;

use WP_Error;

/**
 * Event Validator class
 *
 * Provides validation methods for event data that can be used
 * across Event_Creator and API controllers
 *
 * @since PBOOKING_SINCE
 */
class Event_Validator {

    /**
     * Supported recurrence patterns
     *
     * @var array
     */
    const RECURRENCE_PATTERNS = [
        'none'         => 'None (Single Event)',
        'availability' => 'Availability (Slot-based)',
        'daily'        => 'Daily',
        'weekly'       => 'Weekly',
        'monthly'      => 'Monthly',
        'yearly'       => 'Yearly',
    ];

    /**
     * Validate complete event data
     *
     * @since PBOOKING_SINCE
     *
     * @param array $event_data Event data to validate.
     *
     * @return true|WP_Error True on success, WP_Error with validation errors on failure.
     */
    public static function validate_event_data( $event_data ) {
        $errors = [];

        // Required fields validation
        if ( empty( $event_data['title'] ) ) {
            $errors['title'] = __( 'Event title is required.', 'nemtly-booking' );
        }

        if ( empty( $event_data['event_date'] ) ) {
            $errors['event_date'] = __( 'Event date is required.', 'nemtly-booking' );
        }

        if ( empty( $event_data['event_time'] ) ) {
            $errors['event_time'] = __( 'Event time is required.', 'nemtly-booking' );
        }

        // Date format validation
        if ( ! empty( $event_data['event_date'] ) && ! self::is_valid_date( $event_data['event_date'] ) ) {
            $errors['event_date'] = __( 'Invalid date format. Use Y-m-d format.', 'nemtly-booking' );
        }

        // Time format validation
        if ( ! empty( $event_data['event_time'] ) && ! self::is_valid_time( $event_data['event_time'] ) ) {
            $errors['event_time'] = __( 'Invalid time format. Use H:i format.', 'nemtly-booking' );
        }

        // Event duration validation
        if ( isset( $event_data['event_duration'] ) ) {
            $duration = absint( $event_data['event_duration'] );
            if ( $duration < 15 ) {
                $errors['event_duration'] = __( 'Event duration must be at least 15 minutes.', 'nemtly-booking' );
            }
        }

        // Max attendees validation
        if ( isset( $event_data['max_attendees'] ) ) {
            $max_attendees = absint( $event_data['max_attendees'] );
            if ( $max_attendees < 0 ) {
                $errors['max_attendees'] = __( 'Max attendees cannot be negative.', 'nemtly-booking' );
            }
        }

        // Booking cutoff validation
        if ( isset( $event_data['booking_cutoff'] ) ) {
            $cutoff = absint( $event_data['booking_cutoff'] );
            if ( $cutoff < 0 ) {
                $errors['booking_cutoff'] = __( 'Booking cutoff cannot be negative.', 'nemtly-booking' );
            }
        }

        // Timezone validation
        if ( ! empty( $event_data['timezone'] ) && ! self::is_valid_timezone( $event_data['timezone'] ) ) {
            $errors['timezone'] = __( 'Invalid timezone. Use a valid IANA timezone identifier.', 'nemtly-booking' );
        }

        // Recurrence pattern validation
        if ( ! empty( $event_data['recurrence_pattern'] ) ) {
            if ( ! array_key_exists( $event_data['recurrence_pattern'], self::RECURRENCE_PATTERNS ) ) {
                $errors['recurrence_pattern'] = __( 'Invalid recurrence pattern.', 'nemtly-booking' );
            }
        }

        // Recurrence count validation (0 = no limit).
        if ( isset( $event_data['recurrence_count'] ) ) {
            $count = absint( $event_data['recurrence_count'] );
            if ( $count > 365 ) {
                $errors['recurrence_count'] = __( 'Recurrence count must be between 0 and 365.', 'nemtly-booking' );
            }
        }

        // Recurrence end date validation
        if ( ! empty( $event_data['recurrence_end'] ) && ! self::is_valid_date( $event_data['recurrence_end'] ) ) {
            $errors['recurrence_end'] = __( 'Invalid recurrence end date format. Use Y-m-d format.', 'nemtly-booking' );
        }

        // Return errors if any
        if ( ! empty( $errors ) ) {
            return new WP_Error(
                'validation_failed',
                __( 'Event validation failed.', 'nemtly-booking' ),
                [
                    'status' => 400,
                    'errors' => $errors,
                ]
            );
        }

        return true;
    }

    /**
     * Validate date format (Y-m-d)
     *
     * @since PBOOKING_SINCE
     *
     * @param string $date Date string to validate.
     *
     * @return bool True if valid, false otherwise.
     */
    public static function is_valid_date( $date ) {
        $parsed = date_parse( $date );
        return $parsed && ! $parsed['error_count'] && ! $parsed['warning_count'] && checkdate( $parsed['month'], $parsed['day'], $parsed['year'] );
    }

    /**
     * Validate time format (H:i)
     *
     * @since PBOOKING_SINCE
     *
     * @param string $time Time string to validate.
     *
     * @return bool True if valid, false otherwise.
     */
    public static function is_valid_time( $time ) {
        return (bool) preg_match( '/^([01]?[0-9]|2[0-3]):[0-5][0-9]$/', $time );
    }

    /**
     * Get supported recurrence patterns
     *
     * @since PBOOKING_SINCE
     *
     * @return array Recurrence patterns.
     */
    public static function get_recurrence_patterns() {
        return self::RECURRENCE_PATTERNS;
    }

    /**
     * Validate IANA timezone identifier
     *
     * @since PBOOKING_SINCE
     *
     * @param string $timezone Timezone string to validate.
     *
     * @return bool True if valid, false otherwise.
     */
    public static function is_valid_timezone( $timezone ) {
        try {
            new \DateTimeZone( $timezone );
            return true;
        } catch ( \Exception $e ) {
            return false;
        }
    }

    /**
     * Validate WordPress post status for events
     *
     * @since PBOOKING_SINCE
     *
     * @param string $status Post status to validate.
     *
     * @return bool True if valid, false otherwise.
     */
    public static function is_valid_post_status( $status ) {
        $allowed_statuses = [ 'draft', 'publish', 'future', 'trash' ];
        return in_array( $status, $allowed_statuses, true );
    }
}
