<?php
/**
 * HVAC Community Events - Communication Scheduler
 *
 * Main controller for automated communication scheduling system.
 * Handles creation, management, and execution of scheduled communications.
 *
 * @package HVAC_Community_Events
 * @subpackage Communication
 * @version 1.0.0
 */

// Exit if accessed directly
if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

/**
 * Class HVAC_Communication_Scheduler
 *
 * Core scheduling system for automated email communications.
 */
class HVAC_Communication_Scheduler {

    /**
     * Singleton instance
     */
    private static $instance = null;

    /**
     * Schedule manager instance
     */
    private $schedule_manager;

    /**
     * Trigger engine instance
     */
    private $trigger_engine;

    /**
     * Communication logger instance
     */
    private $logger;

    /**
     * Get singleton instance
     */
    public static function instance() {
        if ( null === self::$instance ) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    /**
     * Constructor
     */
    private function __construct() {
        $this->init_dependencies();
        $this->register_hooks();
        
        // Debug logging
        if ( class_exists( 'HVAC_Logger' ) ) {
            HVAC_Logger::info( 'HVAC_Communication_Scheduler initialized', 'Scheduler' );
        }
    }

    /**
     * Initialize dependencies
     */
    private function init_dependencies() {
        require_once HVAC_PLUGIN_DIR . 'includes/communication/class-communication-schedule-manager.php';
        require_once HVAC_PLUGIN_DIR . 'includes/communication/class-communication-trigger-engine.php';
        require_once HVAC_PLUGIN_DIR . 'includes/communication/class-communication-logger.php';

        $this->schedule_manager = new HVAC_Communication_Schedule_Manager();
        $this->trigger_engine = new HVAC_Communication_Trigger_Engine();
        $this->logger = new HVAC_Communication_Logger();
    }

    /**
     * Register WordPress hooks
     */
    private function register_hooks() {
        // Cron hooks
        add_action( 'hvac_process_communication_schedules', array( $this, 'process_scheduled_communications' ) );
        
        // Event-based triggers
        add_action( 'tribe_events_event_save_after', array( $this, 'on_event_saved' ) );
        add_action( 'event_tickets_after_add_attendee', array( $this, 'on_attendee_registered' ) );
        add_action( 'wp', array( $this, 'check_event_date_changes' ) );
        
        // AJAX handlers
        add_action( 'wp_ajax_hvac_create_schedule', array( $this, 'ajax_create_schedule' ) );
        add_action( 'wp_ajax_hvac_update_schedule', array( $this, 'ajax_update_schedule' ) );
        add_action( 'wp_ajax_hvac_delete_schedule', array( $this, 'ajax_delete_schedule' ) );
        add_action( 'wp_ajax_hvac_get_schedules', array( $this, 'ajax_get_schedules' ) );
        add_action( 'wp_ajax_hvac_toggle_schedule', array( $this, 'ajax_toggle_schedule' ) );
        add_action( 'wp_ajax_hvac_preview_recipients', array( $this, 'ajax_preview_recipients' ) );
        
        // Custom cron schedules
        add_filter( 'cron_schedules', array( $this, 'add_custom_cron_schedules' ) );
        
        // Initialize cron if not scheduled
        add_action( 'wp_loaded', array( $this, 'setup_cron_schedules' ) );
    }

    /**
     * Add custom cron schedules
     */
    public function add_custom_cron_schedules( $schedules ) {
        $schedules['hvac_every_5_minutes'] = array(
            'interval' => 300,
            'display' => __( 'Every 5 minutes', 'hvac-community-events' )
        );
        
        $schedules['hvac_every_15_minutes'] = array(
            'interval' => 900,
            'display' => __( 'Every 15 minutes', 'hvac-community-events' )
        );
        
        return $schedules;
    }

    /**
     * Setup cron schedules
     */
    public function setup_cron_schedules() {
        if ( ! wp_next_scheduled( 'hvac_process_communication_schedules' ) ) {
            wp_schedule_event( time(), 'hvac_every_15_minutes', 'hvac_process_communication_schedules' );
            
            if ( class_exists( 'HVAC_Logger' ) ) {
                HVAC_Logger::info( 'Communication scheduler cron job set up', 'Scheduler' );
            }
        }
    }

    /**
     * Create a new communication schedule
     *
     * @param array $schedule_data Schedule configuration
     * @return int|WP_Error Schedule ID on success, WP_Error on failure
     */
    public function create_schedule( $schedule_data ) {
        // Validate schedule data
        $validation_result = $this->schedule_manager->validate_schedule_data( $schedule_data );
        if ( is_wp_error( $validation_result ) ) {
            return $validation_result;
        }

        // Check for conflicts
        $conflict_check = $this->schedule_manager->check_schedule_conflicts( $schedule_data );
        if ( is_wp_error( $conflict_check ) ) {
            return $conflict_check;
        }

        // Calculate next run time
        $next_run = $this->calculate_next_run_time( $schedule_data );
        $schedule_data['next_run'] = $next_run;

        // Save schedule
        $schedule_id = $this->schedule_manager->save_schedule( $schedule_data );
        
        if ( $schedule_id && class_exists( 'HVAC_Logger' ) ) {
            HVAC_Logger::info( "Communication schedule created: ID $schedule_id", 'Scheduler' );
        }

        return $schedule_id;
    }

    /**
     * Update an existing communication schedule
     *
     * @param int $schedule_id Schedule ID
     * @param array $schedule_data Updated schedule configuration
     * @return bool|WP_Error Success status
     */
    public function update_schedule( $schedule_id, $schedule_data ) {
        // Verify ownership
        if ( ! $this->schedule_manager->user_can_edit_schedule( $schedule_id ) ) {
            return new WP_Error( 'permission_denied', __( 'You do not have permission to edit this schedule.', 'hvac-community-events' ) );
        }

        // Validate data
        $validation_result = $this->schedule_manager->validate_schedule_data( $schedule_data );
        if ( is_wp_error( $validation_result ) ) {
            return $validation_result;
        }

        // Recalculate next run time if trigger settings changed
        $existing_schedule = $this->schedule_manager->get_schedule( $schedule_id );
        $trigger_changed = ( 
            $existing_schedule['trigger_type'] !== $schedule_data['trigger_type'] ||
            $existing_schedule['trigger_value'] !== $schedule_data['trigger_value'] ||
            $existing_schedule['trigger_unit'] !== $schedule_data['trigger_unit']
        );

        if ( $trigger_changed ) {
            $schedule_data['next_run'] = $this->calculate_next_run_time( $schedule_data );
        }

        return $this->schedule_manager->update_schedule( $schedule_id, $schedule_data );
    }

    /**
     * Delete a communication schedule
     *
     * @param int $schedule_id Schedule ID
     * @return bool|WP_Error Success status
     */
    public function delete_schedule( $schedule_id ) {
        // Verify ownership
        if ( ! $this->schedule_manager->user_can_edit_schedule( $schedule_id ) ) {
            return new WP_Error( 'permission_denied', __( 'You do not have permission to delete this schedule.', 'hvac-community-events' ) );
        }

        $result = $this->schedule_manager->delete_schedule( $schedule_id );
        
        if ( $result && class_exists( 'HVAC_Logger' ) ) {
            HVAC_Logger::info( "Communication schedule deleted: ID $schedule_id", 'Scheduler' );
        }

        return $result;
    }

    /**
     * Get schedules for a trainer
     *
     * @param int $trainer_id Trainer user ID
     * @param int $event_id Optional specific event ID
     * @return array Array of schedules
     */
    public function get_trainer_schedules( $trainer_id, $event_id = null ) {
        return $this->schedule_manager->get_schedules_by_trainer( $trainer_id, $event_id );
    }

    /**
     * Process all due scheduled communications
     */
    public function process_scheduled_communications() {
        $due_schedules = $this->schedule_manager->get_due_schedules();
        
        if ( class_exists( 'HVAC_Logger' ) ) {
            HVAC_Logger::info( 'Processing ' . count( $due_schedules ) . ' due communication schedules', 'Scheduler' );
        }

        foreach ( $due_schedules as $schedule ) {
            $this->execute_schedule( $schedule['schedule_id'] );
        }
    }

    /**
     * Calculate next run time for a schedule
     *
     * @param array $schedule Schedule configuration
     * @return string MySQL datetime string
     */
    public function calculate_next_run_time( $schedule ) {
        if ( ! empty( $schedule['event_id'] ) ) {
            // Event-based scheduling
            $event_date = get_post_meta( $schedule['event_id'], '_EventStartDate', true );
            if ( ! $event_date ) {
                return null;
            }

            return $this->trigger_engine->calculate_trigger_time( $event_date, $schedule );
        } else {
            // Immediate or custom date scheduling
            if ( $schedule['trigger_type'] === 'custom_date' && ! empty( $schedule['custom_date'] ) ) {
                return $schedule['custom_date'];
            } elseif ( $schedule['trigger_type'] === 'on_registration' ) {
                // This will be triggered immediately on registration
                return null;
            }
        }

        return null;
    }

    /**
     * Execute a specific schedule
     *
     * @param int $schedule_id Schedule ID
     * @return bool Success status
     */
    public function execute_schedule( $schedule_id ) {
        $schedule = $this->schedule_manager->get_schedule( $schedule_id );
        if ( ! $schedule ) {
            return false;
        }

        try {
            // Get recipients
            $recipients = $this->trigger_engine->get_schedule_recipients( $schedule );
            
            if ( empty( $recipients ) ) {
                $this->logger->log_schedule_execution( $schedule_id, 'skipped', array(
                    'reason' => 'No recipients found'
                ) );
                return true;
            }

            // Execute communication
            $result = $this->trigger_engine->execute_communication( $schedule, $recipients );

            // Update schedule run tracking
            $this->schedule_manager->update_schedule_run_tracking( $schedule_id );

            // Log execution
            $this->logger->log_schedule_execution( $schedule_id, 'sent', array(
                'recipient_count' => count( $recipients ),
                'success' => $result
            ) );

            return $result;

        } catch ( Exception $e ) {
            $this->logger->log_schedule_execution( $schedule_id, 'failed', array(
                'error' => $e->getMessage()
            ) );
            
            if ( class_exists( 'HVAC_Logger' ) ) {
                HVAC_Logger::error( "Schedule execution failed: " . $e->getMessage(), 'Scheduler' );
            }

            return false;
        }
    }

    /**
     * Handle event saved/updated
     *
     * @param int $event_id Event ID
     */
    public function on_event_saved( $event_id ) {
        $schedules = $this->schedule_manager->get_schedules_by_event( $event_id );
        
        foreach ( $schedules as $schedule ) {
            // Recalculate next run time if event date changed
            $new_next_run = $this->calculate_next_run_time( $schedule );
            
            if ( $new_next_run !== $schedule['next_run'] ) {
                $this->schedule_manager->update_schedule( $schedule['schedule_id'], array(
                    'next_run' => $new_next_run
                ) );
            }
        }
    }

    /**
     * Handle attendee registration
     *
     * @param int $attendee_id Attendee ID
     * @param int $event_id Event ID
     */
    public function on_attendee_registered( $attendee_id, $event_id ) {
        // Process immediate registration triggers
        $this->trigger_engine->process_registration_triggers( $attendee_id, $event_id );
    }

    /**
     * Check for event date changes
     */
    public function check_event_date_changes() {
        // This will be called on wp hook to check for any event date changes
        // and update corresponding schedules
        if ( ! is_admin() || ! current_user_can( 'edit_posts' ) ) {
            return;
        }

        // Process any date change updates
        $this->trigger_engine->process_event_date_changes();
    }

    /**
     * AJAX: Create schedule
     */
    public function ajax_create_schedule() {
        check_ajax_referer( 'hvac_scheduler_nonce', 'nonce' );

        if ( ! is_user_logged_in() ) {
            wp_send_json_error( array( 'message' => __( 'You must be logged in to create schedules.', 'hvac-community-events' ) ) );
        }

        $schedule_data = $this->sanitize_schedule_data( $_POST );
        $schedule_data['trainer_id'] = get_current_user_id();

        $result = $this->create_schedule( $schedule_data );

        if ( is_wp_error( $result ) ) {
            wp_send_json_error( array( 'message' => $result->get_error_message() ) );
        }

        wp_send_json_success( array(
            'schedule_id' => $result,
            'message' => __( 'Schedule created successfully.', 'hvac-community-events' )
        ) );
    }

    /**
     * AJAX: Update schedule
     */
    public function ajax_update_schedule() {
        check_ajax_referer( 'hvac_scheduler_nonce', 'nonce' );

        if ( ! is_user_logged_in() ) {
            wp_send_json_error( array( 'message' => __( 'You must be logged in to update schedules.', 'hvac-community-events' ) ) );
        }

        $schedule_id = intval( $_POST['schedule_id'] );
        $schedule_data = $this->sanitize_schedule_data( $_POST );

        $result = $this->update_schedule( $schedule_id, $schedule_data );

        if ( is_wp_error( $result ) ) {
            wp_send_json_error( array( 'message' => $result->get_error_message() ) );
        }

        wp_send_json_success( array( 'message' => __( 'Schedule updated successfully.', 'hvac-community-events' ) ) );
    }

    /**
     * AJAX: Delete schedule
     */
    public function ajax_delete_schedule() {
        check_ajax_referer( 'hvac_scheduler_nonce', 'nonce' );

        if ( ! is_user_logged_in() ) {
            wp_send_json_error( array( 'message' => __( 'You must be logged in to delete schedules.', 'hvac-community-events' ) ) );
        }

        $schedule_id = intval( $_POST['schedule_id'] );
        $result = $this->delete_schedule( $schedule_id );

        if ( is_wp_error( $result ) ) {
            wp_send_json_error( array( 'message' => $result->get_error_message() ) );
        }

        wp_send_json_success( array( 'message' => __( 'Schedule deleted successfully.', 'hvac-community-events' ) ) );
    }

    /**
     * AJAX: Get schedules
     */
    public function ajax_get_schedules() {
        check_ajax_referer( 'hvac_scheduler_nonce', 'nonce' );

        if ( ! is_user_logged_in() ) {
            wp_send_json_error( array( 'message' => __( 'You must be logged in to view schedules.', 'hvac-community-events' ) ) );
        }

        $trainer_id = get_current_user_id();
        $event_id = isset( $_POST['event_id'] ) ? intval( $_POST['event_id'] ) : null;
        $status_filter = isset( $_POST['status'] ) ? sanitize_text_field( $_POST['status'] ) : null;

        $schedules = $this->get_trainer_schedules( $trainer_id, $event_id );

        if ( $status_filter && $status_filter !== 'all' ) {
            $schedules = array_filter( $schedules, function( $schedule ) use ( $status_filter ) {
                return $schedule['status'] === $status_filter;
            } );
        }

        wp_send_json_success( array( 'schedules' => array_values( $schedules ) ) );
    }

    /**
     * AJAX: Toggle schedule status
     */
    public function ajax_toggle_schedule() {
        check_ajax_referer( 'hvac_scheduler_nonce', 'nonce' );

        if ( ! is_user_logged_in() ) {
            wp_send_json_error( array( 'message' => __( 'You must be logged in to toggle schedules.', 'hvac-community-events' ) ) );
        }

        $schedule_id = intval( $_POST['schedule_id'] );
        $schedule = $this->schedule_manager->get_schedule( $schedule_id );

        if ( ! $schedule ) {
            wp_send_json_error( array( 'message' => __( 'Schedule not found.', 'hvac-community-events' ) ) );
        }

        $new_status = ( $schedule['status'] === 'active' ) ? 'paused' : 'active';
        
        $result = $this->update_schedule( $schedule_id, array( 'status' => $new_status ) );

        if ( is_wp_error( $result ) ) {
            wp_send_json_error( array( 'message' => $result->get_error_message() ) );
        }

        wp_send_json_success( array(
            'status' => $new_status,
            'message' => sprintf( __( 'Schedule %s.', 'hvac-community-events' ), $new_status )
        ) );
    }

    /**
     * AJAX: Preview recipients
     */
    public function ajax_preview_recipients() {
        check_ajax_referer( 'hvac_scheduler_nonce', 'nonce' );

        if ( ! is_user_logged_in() ) {
            wp_send_json_error( array( 'message' => __( 'You must be logged in to preview recipients.', 'hvac-community-events' ) ) );
        }

        $schedule_data = $this->sanitize_schedule_data( $_POST );
        $schedule_data['trainer_id'] = get_current_user_id();

        $recipients = $this->trigger_engine->get_schedule_recipients( $schedule_data );

        wp_send_json_success( array(
            'recipients' => $recipients,
            'count' => count( $recipients )
        ) );
    }

    /**
     * Sanitize schedule data from form input
     *
     * @param array $raw_data Raw POST data
     * @return array Sanitized schedule data
     */
    private function sanitize_schedule_data( $raw_data ) {
        return array(
            'schedule_name' => isset( $raw_data['schedule_name'] ) ? sanitize_text_field( $raw_data['schedule_name'] ) : '',
            'event_id' => isset( $raw_data['event_id'] ) ? intval( $raw_data['event_id'] ) : null,
            'template_id' => isset( $raw_data['template_id'] ) ? intval( $raw_data['template_id'] ) : 0,
            'trigger_type' => isset( $raw_data['trigger_type'] ) ? sanitize_text_field( $raw_data['trigger_type'] ) : '',
            'trigger_value' => isset( $raw_data['trigger_value'] ) ? intval( $raw_data['trigger_value'] ) : 0,
            'trigger_unit' => isset( $raw_data['trigger_unit'] ) ? sanitize_text_field( $raw_data['trigger_unit'] ) : 'days',
            'target_audience' => isset( $raw_data['target_audience'] ) ? sanitize_text_field( $raw_data['target_audience'] ) : 'all_attendees',
            'custom_recipient_list' => isset( $raw_data['custom_recipient_list'] ) ? sanitize_textarea_field( $raw_data['custom_recipient_list'] ) : '',
            'is_recurring' => isset( $raw_data['is_recurring'] ) ? (bool) $raw_data['is_recurring'] : false,
            'recurring_interval' => isset( $raw_data['recurring_interval'] ) ? intval( $raw_data['recurring_interval'] ) : null,
            'recurring_unit' => isset( $raw_data['recurring_unit'] ) ? sanitize_text_field( $raw_data['recurring_unit'] ) : null,
            'max_runs' => isset( $raw_data['max_runs'] ) ? intval( $raw_data['max_runs'] ) : null,
            'status' => isset( $raw_data['status'] ) ? sanitize_text_field( $raw_data['status'] ) : 'active'
        );
    }

    /**
     * Get default schedule templates
     *
     * @return array Default schedule configurations
     */
    public function get_default_schedule_templates() {
        return array(
            'event_reminder_24h' => array(
                'name' => __( '24-Hour Event Reminder', 'hvac-community-events' ),
                'trigger_type' => 'before_event',
                'trigger_value' => 1,
                'trigger_unit' => 'days',
                'template_category' => 'event_reminder',
                'target_audience' => 'confirmed_attendees',
                'description' => __( 'Send reminder 24 hours before event starts', 'hvac-community-events' )
            ),
            'welcome_on_registration' => array(
                'name' => __( 'Welcome Email on Registration', 'hvac-community-events' ),
                'trigger_type' => 'on_registration',
                'trigger_value' => 0,
                'trigger_unit' => 'minutes',
                'template_category' => 'pre_event',
                'target_audience' => 'all_attendees',
                'description' => __( 'Send welcome email immediately when someone registers', 'hvac-community-events' )
            ),
            'post_event_followup' => array(
                'name' => __( 'Post-Event Follow-up', 'hvac-community-events' ),
                'trigger_type' => 'after_event',
                'trigger_value' => 2,
                'trigger_unit' => 'days',
                'template_category' => 'post_event',
                'target_audience' => 'all_attendees',
                'description' => __( 'Send follow-up email 2 days after event', 'hvac-community-events' )
            ),
            'certificate_notification' => array(
                'name' => __( 'Certificate Ready Notification', 'hvac-community-events' ),
                'trigger_type' => 'after_event',
                'trigger_value' => 3,
                'trigger_unit' => 'days',
                'template_category' => 'certificate',
                'target_audience' => 'confirmed_attendees',
                'description' => __( 'Notify attendees when certificates are ready', 'hvac-community-events' )
            )
        );
    }
}

// Initialize the scheduler
function hvac_communication_scheduler() {
    return HVAC_Communication_Scheduler::instance();
}

// Initialize after plugins loaded
add_action( 'plugins_loaded', 'hvac_communication_scheduler' );