<?php
/**
 * HVAC Community Events - Communication Trigger Engine
 *
 * Handles automation logic, recipient management, and email execution.
 * Processes trigger conditions and manages communication delivery.
 *
 * @package HVAC_Community_Events
 * @subpackage Communication
 * @version 1.0.0
 */

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

/**
 * Class HVAC_Communication_Trigger_Engine
 *
 * Manages trigger processing and communication execution.
 */
class HVAC_Communication_Trigger_Engine {

    /**
     * Constructor
     */
    public function __construct() {
        // Initialize any required hooks or filters
    }

    /**
     * Calculate trigger time based on event date and schedule configuration
     *
     * @param string $event_date Event start date (MySQL format)
     * @param array $schedule Schedule configuration
     * @return string|null MySQL datetime string for trigger time
     */
    public function calculate_trigger_time( $event_date, $schedule ) {
        if ( empty( $event_date ) || empty( $schedule['trigger_type'] ) ) {
            return null;
        }

        $event_timestamp = strtotime( $event_date );
        if ( ! $event_timestamp ) {
            return null;
        }

        $trigger_value = intval( $schedule['trigger_value'] );
        $trigger_unit = $schedule['trigger_unit'];

        // Convert trigger unit to seconds
        $seconds_multiplier = $this->get_unit_multiplier( $trigger_unit );
        if ( ! $seconds_multiplier ) {
            return null;
        }

        $offset_seconds = $trigger_value * $seconds_multiplier;

        switch ( $schedule['trigger_type'] ) {
            case 'before_event':
                $trigger_timestamp = $event_timestamp - $offset_seconds;
                break;
            case 'after_event':
                // Use event end date if available, otherwise start date
                $event_end_date = get_post_meta( $schedule['event_id'], '_EventEndDate', true );
                $end_timestamp = $event_end_date ? strtotime( $event_end_date ) : $event_timestamp;
                $trigger_timestamp = $end_timestamp + $offset_seconds;
                break;
            case 'on_registration':
                // Immediate trigger - return current time
                return current_time( 'mysql' );
            case 'custom_date':
                // Custom date should be provided in schedule data
                return isset( $schedule['custom_date'] ) ? $schedule['custom_date'] : null;
            default:
                return null;
        }

        // Ensure trigger time is in the future
        if ( $trigger_timestamp <= time() ) {
            return null;
        }

        return date( 'Y-m-d H:i:s', $trigger_timestamp );
    }

    /**
     * Get unit multiplier for converting to seconds
     *
     * @param string $unit Time unit
     * @return int|false Multiplier or false if invalid
     */
    private function get_unit_multiplier( $unit ) {
        $multipliers = array(
            'minutes' => MINUTE_IN_SECONDS,
            'hours'   => HOUR_IN_SECONDS,
            'days'    => DAY_IN_SECONDS,
            'weeks'   => WEEK_IN_SECONDS
        );

        return isset( $multipliers[$unit] ) ? $multipliers[$unit] : false;
    }

    /**
     * Get recipients for a schedule based on target audience settings
     *
     * @param array $schedule Schedule configuration
     * @return array Array of recipient data
     */
    public function get_schedule_recipients( $schedule ) {
        $recipients = array();

        switch ( $schedule['target_audience'] ) {
            case 'all_attendees':
                $recipients = $this->get_all_event_attendees( $schedule['event_id'] );
                break;
            case 'confirmed_attendees':
                $recipients = $this->get_confirmed_attendees( $schedule['event_id'] );
                break;
            case 'pending_attendees':
                $recipients = $this->get_pending_attendees( $schedule['event_id'] );
                break;
            case 'custom_list':
                $recipients = $this->parse_custom_recipient_list( $schedule['custom_recipient_list'] );
                break;
        }

        // Apply additional conditions if specified
        if ( ! empty( $schedule['conditions'] ) ) {
            $recipients = $this->apply_recipient_conditions( $recipients, $schedule['conditions'] );
        }

        return $recipients;
    }

    /**
     * Get all attendees for an event
     *
     * @param int $event_id Event ID
     * @return array Array of attendee data
     */
    private function get_all_event_attendees( $event_id ) {
        if ( empty( $event_id ) ) {
            return array();
        }

        // Use the Email Attendees Data class for consistent attendee retrieval
        $email_data = new HVAC_Email_Attendees_Data( $event_id );
        $attendees = $email_data->get_attendees();

        $recipients = array();
        foreach ( $attendees as $attendee ) {
            $recipients[] = array(
                'email' => $attendee['email'],
                'name' => $attendee['name'],
                'attendee_id' => $attendee['attendee_id'],
                'ticket_name' => $attendee['ticket_name'],
                'status' => 'confirmed' // Default status
            );
        }

        return $recipients;
    }

    /**
     * Get confirmed attendees only
     *
     * @param int $event_id Event ID
     * @return array Array of confirmed attendee data
     */
    private function get_confirmed_attendees( $event_id ) {
        $all_attendees = $this->get_all_event_attendees( $event_id );

        // For now, treat all attendees as confirmed
        // This can be enhanced later based on ticket status if needed
        return array_filter( $all_attendees, function( $attendee ) {
            return $attendee['status'] === 'confirmed';
        });
    }

    /**
     * Get pending attendees only
     *
     * @param int $event_id Event ID
     * @return array Array of pending attendee data
     */
    private function get_pending_attendees( $event_id ) {
        $all_attendees = $this->get_all_event_attendees( $event_id );

        return array_filter( $all_attendees, function( $attendee ) {
            return $attendee['status'] === 'pending';
        });
    }

    /**
     * Parse custom recipient list from text input
     *
     * @param string $recipient_list Comma or line-separated email list
     * @return array Array of recipient data
     */
    private function parse_custom_recipient_list( $recipient_list ) {
        if ( empty( $recipient_list ) ) {
            return array();
        }

        $recipients = array();
        $lines = preg_split( '/[\r\n,]+/', $recipient_list );

        foreach ( $lines as $line ) {
            $line = trim( $line );
            
            if ( empty( $line ) ) {
                continue;
            }

            // Check if line contains both name and email
            if ( preg_match( '/(.+?)\s*<(.+?)>/', $line, $matches ) ) {
                $name = trim( $matches[1] );
                $email = trim( $matches[2] );
            } else {
                // Just email address
                $email = $line;
                $name = '';
            }

            if ( is_email( $email ) ) {
                $recipients[] = array(
                    'email' => $email,
                    'name' => $name,
                    'attendee_id' => 0,
                    'ticket_name' => '',
                    'status' => 'custom'
                );
            }
        }

        return $recipients;
    }

    /**
     * Apply additional conditions to filter recipients
     *
     * @param array $recipients Current recipient list
     * @param array $conditions Filter conditions
     * @return array Filtered recipients
     */
    private function apply_recipient_conditions( $recipients, $conditions ) {
        if ( empty( $conditions ) ) {
            return $recipients;
        }

        foreach ( $conditions as $condition ) {
            switch ( $condition['type'] ) {
                case 'ticket_type':
                    $recipients = array_filter( $recipients, function( $recipient ) use ( $condition ) {
                        return $recipient['ticket_name'] === $condition['value'];
                    });
                    break;
                case 'exclude_emails':
                    $exclude_list = array_map( 'trim', explode( ',', $condition['value'] ) );
                    $recipients = array_filter( $recipients, function( $recipient ) use ( $exclude_list ) {
                        return ! in_array( $recipient['email'], $exclude_list );
                    });
                    break;
            }
        }

        return $recipients;
    }

    /**
     * Execute communication for a schedule
     *
     * @param array $schedule Schedule configuration
     * @param array $recipients Recipients to send to
     * @return bool Success status
     */
    public function execute_communication( $schedule, $recipients ) {
        if ( empty( $recipients ) || empty( $schedule['template_id'] ) ) {
            return false;
        }

        // Get the email template
        $template = get_post( $schedule['template_id'] );
        if ( ! $template || $template->post_type !== 'hvac_email_template' ) {
            return false;
        }

        $subject = $template->post_title;
        $message = $template->post_content;

        // Get event details for placeholder replacement
        $event_details = null;
        if ( ! empty( $schedule['event_id'] ) ) {
            $email_data = new HVAC_Email_Attendees_Data( $schedule['event_id'] );
            $event_details = $email_data->get_event_details();
        }

        $success_count = 0;
        $total_count = count( $recipients );

        foreach ( $recipients as $recipient ) {
            // Replace placeholders in subject and message
            $personalized_subject = $this->replace_placeholders( $subject, $recipient, $event_details );
            $personalized_message = $this->replace_placeholders( $message, $recipient, $event_details );

            // Send email
            $headers = array(
                'Content-Type: text/html; charset=UTF-8'
            );

            // Add sender information
            $trainer = get_user_by( 'id', $schedule['trainer_id'] );
            if ( $trainer ) {
                $from_name = $trainer->display_name;
                $from_email = $trainer->user_email;
                
                // Check for trainer business name
                $business_name = get_user_meta( $trainer->ID, 'business_name', true );
                if ( ! empty( $business_name ) ) {
                    $from_name = $business_name;
                }
                
                $headers[] = 'From: ' . $from_name . ' <' . $from_email . '>';
            }

            $mail_sent = wp_mail( $recipient['email'], $personalized_subject, wpautop( $personalized_message ), $headers );
            
            if ( $mail_sent ) {
                $success_count++;
            }

            // Log individual send attempt if logger is available
            if ( class_exists( 'HVAC_Logger' ) ) {
                $status = $mail_sent ? 'sent' : 'failed';
                HVAC_Logger::info( "Email {$status} to {$recipient['email']} for schedule {$schedule['schedule_id']}", 'Communication Engine' );
            }
        }

        return $success_count === $total_count;
    }

    /**
     * Replace placeholders in email content
     *
     * @param string $content Email subject or content
     * @param array $recipient Recipient data
     * @param array|null $event_details Event details for placeholders
     * @return string Content with placeholders replaced
     */
    private function replace_placeholders( $content, $recipient, $event_details = null ) {
        $placeholders = array(
            '{attendee_name}' => $recipient['name'],
            '{attendee_email}' => $recipient['email'],
            '{ticket_type}' => $recipient['ticket_name']
        );

        if ( $event_details ) {
            $placeholders['{event_title}'] = $event_details['title'];
            $placeholders['{event_date}'] = $event_details['start_date'];
            $placeholders['{event_time}'] = $event_details['start_time'];
            $placeholders['{event_start_date}'] = $event_details['start_date'];
            $placeholders['{event_start_time}'] = $event_details['start_time'];
            $placeholders['{event_end_date}'] = $event_details['end_date'];
            $placeholders['{event_end_time}'] = $event_details['end_time'];
        }

        // Add current date/time placeholders
        $placeholders['{current_date}'] = date( 'F j, Y' );
        $placeholders['{current_time}'] = date( 'g:i a' );
        $placeholders['{current_year}'] = date( 'Y' );

        return str_replace( array_keys( $placeholders ), array_values( $placeholders ), $content );
    }

    /**
     * Process registration-triggered communications
     *
     * @param int $attendee_id Attendee ID
     * @param int $event_id Event ID
     */
    public function process_registration_triggers( $attendee_id, $event_id ) {
        global $wpdb;

        // Get all active schedules with registration triggers for this event
        $schedules_table = $wpdb->prefix . 'hvac_communication_schedules';
        
        $schedules = $wpdb->get_results( $wpdb->prepare(
            "SELECT * FROM {$schedules_table} 
             WHERE event_id = %d 
             AND trigger_type = 'on_registration' 
             AND status = 'active'",
            $event_id
        ), ARRAY_A );

        foreach ( $schedules as $schedule ) {
            // Get attendee details
            $attendee_post = get_post( $attendee_id );
            if ( ! $attendee_post ) {
                continue;
            }

            $attendee_email = get_post_meta( $attendee_id, '_tribe_tickets_email', true );
            if ( empty( $attendee_email ) ) {
                $attendee_email = get_post_meta( $attendee_id, '_tribe_tpp_email', true );
            }

            $attendee_name = get_post_meta( $attendee_id, '_tribe_tickets_full_name', true );
            if ( empty( $attendee_name ) ) {
                $attendee_name = get_post_meta( $attendee_id, '_tribe_tpp_full_name', true );
            }

            if ( empty( $attendee_email ) || ! is_email( $attendee_email ) ) {
                continue;
            }

            // Create recipient array
            $recipients = array(
                array(
                    'email' => $attendee_email,
                    'name' => $attendee_name,
                    'attendee_id' => $attendee_id,
                    'ticket_name' => '',
                    'status' => 'confirmed'
                )
            );

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

            // Update schedule run tracking
            $schedule_manager = new HVAC_Communication_Schedule_Manager();
            $schedule_manager->update_schedule_run_tracking( $schedule['schedule_id'] );
        }
    }

    /**
     * Process event date changes and update affected schedules
     */
    public function process_event_date_changes() {
        global $wpdb;

        // This would be called when event dates are updated
        // For now, it's a placeholder for future implementation
        
        if ( class_exists( 'HVAC_Logger' ) ) {
            HVAC_Logger::info( 'Processing event date changes', 'Communication Engine' );
        }
    }

    /**
     * Validate recipients against event attendees
     *
     * @param array $recipients Recipients to validate
     * @param int $event_id Event ID
     * @return array Valid recipients only
     */
    public function validate_recipients( $recipients, $event_id = null ) {
        if ( empty( $recipients ) ) {
            return array();
        }

        $valid_recipients = array();

        foreach ( $recipients as $recipient ) {
            // Basic email validation
            if ( empty( $recipient['email'] ) || ! is_email( $recipient['email'] ) ) {
                continue;
            }

            // If event ID provided, verify recipient is actually an attendee
            if ( $event_id ) {
                $all_attendees = $this->get_all_event_attendees( $event_id );
                $is_attendee = false;
                
                foreach ( $all_attendees as $attendee ) {
                    if ( $attendee['email'] === $recipient['email'] ) {
                        $is_attendee = true;
                        break;
                    }
                }

                if ( ! $is_attendee && $recipient['status'] !== 'custom' ) {
                    continue;
                }
            }

            $valid_recipients[] = $recipient;
        }

        return $valid_recipients;
    }

    /**
     * Get communication statistics for a schedule
     *
     * @param int $schedule_id Schedule ID
     * @return array Statistics array
     */
    public function get_schedule_statistics( $schedule_id ) {
        global $wpdb;
        
        $logs_table = $wpdb->prefix . 'hvac_communication_logs';
        
        $stats = $wpdb->get_row( $wpdb->prepare(
            "SELECT 
                COUNT(*) as total_sends,
                COUNT(CASE WHEN status = 'sent' THEN 1 END) as successful_sends,
                COUNT(CASE WHEN status = 'failed' THEN 1 END) as failed_sends,
                MAX(sent_date) as last_sent
             FROM {$logs_table} 
             WHERE schedule_id = %d",
            $schedule_id
        ), ARRAY_A );

        return $stats;
    }
}