/**
     * Trigger a notification
     * 
     * @access public
     * @param object $subscription
     * @param array $args
     * @param bool $send_to_admin
     * @return void
     */
    public function trigger($subscription, $args = array(), $send_to_admin = false)
    {
        if (!$subscription) {
            return;
        }

        $this->object = $subscription;

        if ($send_to_admin) {
            $this->recipient = get_option('admin_email');
        }
        else {
            $this->recipient = get_user_meta($subscription->user_id, 'billing_email', true);
        }

        // Check if this email type is enabled, recipient is set and we are not on a development website
        if (!$this->is_enabled() || !$this->get_recipient() || !Subscriptio::is_main_site()) {
            return;
        }

        $this->template_variables = array(
            'subscription' => $this->object,
            'email_heading' => $this->get_heading(),
            'sent_to_admin' => false,
        );

        $this->send($this->get_recipient(), $this->get_subject(), $this->get_content(), $this->get_headers(), $this->get_attachments());
    }
    /**
     * Trigger a notification
     * 
     * @access public
     * @param object $subscription
     * @param array $args
     * @param bool $send_to_admin
     * @return void
     */
    public function trigger($subscription, $args = array(), $send_to_admin = false)
    {
        if (!$subscription || !isset($subscription->last_order_id)) {
            return;
        }

        $order = new WC_Order($subscription->last_order_id);

        if (!$order) {
            return;
        }

        $this->object = $order;

        if ($send_to_admin) {
            $this->recipient = get_option('admin_email');
        }
        else {
            $this->recipient = $this->object->billing_email;
        }

        // Replace macros
        $this->find[] = '{order_number}';
        $this->replace[] = $this->object->get_order_number();

        // Check if this email type is enabled, recipient is set and we are not on a development website
        if (!$this->is_enabled() || !$this->get_recipient() || !Subscriptio::is_main_site()) {
            return;
        }

        // Get next action and next action date
        $next_action_datetime = Subscriptio_Scheduler::get_scheduled_event_datetime('subscriptio_scheduled_payment', $subscription->id);
        $next_action_is_overdue = false;

        if ($subscription->calculate_overdue_time()) {
            $next_action = __('marked overdue', 'subscriptio');
            $next_action_is_overdue = true;
            $subsequent_action = $subscription->calculate_suspension_time() > 0 ? __('suspension', 'subscriptio') : __('cancellation', 'subscriptio');
        }
        else if ($subscription->calculate_suspension_time() > 0) {
            $next_action = __('suspended', 'subscriptio');
        }
        else {
            $next_action = __('cancelled', 'subscriptio');
        }

        $this->template_variables = array(
            'subscription'              => $subscription,
            'order'                     => $this->object,
            'email_heading'             => $this->get_heading(),
            'sent_to_admin'             => false,
            'next_action'               => $next_action,
            'next_action_datetime'      => $next_action_datetime,
            'next_action_is_overdue'    => $next_action_is_overdue,
            'subsequent_action'         => isset($subsequent_action) ? $subsequent_action : '',
        );

        $this->send($this->get_recipient(), $this->get_subject(), $this->get_content(), $this->get_headers(), $this->get_attachments());
    }
    /**
     * Trigger a notification
     * 
     * @access public
     * @param object $order
     * @param array $args
     * @param bool $send_to_admin
     * @return void
     */
    public function trigger($order, $args = array(), $send_to_admin = false)
    {
        if (!$order) {
            return;
        }

        $this->object = $order;

        if ($send_to_admin) {
            $this->recipient = get_option('admin_email');
        }
        else {
            $this->recipient = $this->object->billing_email;
        }

        // Replace macros
        $this->find[] = '{order_date}';
        $this->replace[] = date_i18n(wc_date_format(), strtotime($this->object->order_date));

        // Check if this email type is enabled, recipient is set and we are not on a development website
        if (!$this->is_enabled() || !$this->get_recipient() || !Subscriptio::is_main_site()) {
            return;
        }

        // Get subscription
        $subscription = Subscriptio_Order_Handler::get_subscriptions_from_order_id($order->id);
        $subscription = reset($subscription);

        if (!$subscription) {
            return;
        }

        $this->template_variables = array(
            'subscription'  => $subscription,
            'order'         => $this->object,
            'email_heading' => $this->get_heading(),
            'sent_to_admin' => false,
        );

        $this->send($this->get_recipient(), $this->get_subject(), $this->get_content(), $this->get_headers(), $this->get_attachments());
    }
    /**
     * Trigger a notification
     * 
     * @access public
     * @param object $subscription
     * @param array $args
     * @param bool $send_to_admin
     * @return void
     */
    public function trigger($subscription, $args = array(), $send_to_admin = false)
    {
        if (!$subscription || !isset($subscription->last_order_id)) {
            return;
        }

        $order = new WC_Order($subscription->last_order_id);

        if (!$order) {
            return;
        }

        $this->object = $subscription;

        if ($send_to_admin) {
            $this->recipient = get_option('admin_email');
        }
        else {
            $this->recipient = get_user_meta($subscription->user_id, 'billing_email', true);
        }

        // Check if this email type is enabled, recipient is set and we are not on a development website
        if (!$this->is_enabled() || !$this->get_recipient() || !Subscriptio::is_main_site()) {
            return;
        }

        // Get next action date and time
        $next_action_datetime = Subscriptio_Scheduler::get_scheduled_event_datetime('subscriptio_scheduled_cancellation', $subscription->id);

        $this->template_variables = array(
            'subscription'          => $this->object,
            'order'                 => $order,
            'email_heading'         => $this->get_heading(),
            'sent_to_admin'         => false,
            'next_action_datetime'  => $next_action_datetime,
        );

        $this->send($this->get_recipient(), $this->get_subject(), $this->get_content(), $this->get_headers(), $this->get_attachments());
    }
    /**
     * Scheduled next payment event handler
     * 
     * @access public
     * @param int $subscription_id
     * @return void
     */
    public static function scheduled_payment($subscription_id)
    {
        // Start transaction
        $transaction = new Subscriptio_Transaction(null, 'payment_due');

        // Load subscription if it's still valid
        $subscription = Subscriptio_Subscription::get_valid_subscription($subscription_id, $transaction);

        // Got a valid subscription object?
        if (!isset($subscription->status)) {
            return;
        }

        // Load related order
        $order = new WC_Order($subscription->last_order_id);

        if (!$order) {
            $transaction->update_result('error');
            $transaction->update_note(__('Renewal order not found.', 'subscriptio'), true);
            return;
        }

        // Check if payment has been received manually - last order must be marked as processing or completed and payment_due date must be in the future
        if (time() <= $subscription->payment_due || in_array($order->status, array('processing', 'completed'))) {
            $transaction->update_result('error');
            $transaction->update_note(__('Payment seems to be already received.', 'subscriptio'), true);
            return;
        }

        // Attempt to process automatic payment if this is main website
        if (apply_filters('subscriptio_process_automatic_payment', Subscriptio::is_main_site(), $order, $subscription)) {
            if (apply_filters('subscriptio_automatic_payment', false, $order, $subscription)) {
                return;
            }
        }

        // Now either set to overdue or suspend or cancel, depending on settings
        try {
            $overdue_end_time = $subscription->calculate_overdue_time();
            $suspension_end_time = $subscription->calculate_suspension_time();  // This will be "fake" time for now in case $overdue_end_time is set

            // Overdue
            if ($overdue_end_time > 0) {

                // Set subscription to overdue
                $subscription->overdue();

                // Update transaction
                $transaction->update_result('success');
                $transaction->update_note(__('Payment not received. Subscription marked as overdue.', 'subscriptio'), true);

                // Schedule suspension and/or cancellation
                if ($suspension_end_time > 0) {
                    self::schedule_suspension($subscription->id, $overdue_end_time);
                    self::schedule_cancellation($subscription->id, $subscription->calculate_suspension_time($overdue_end_time));
                    $transaction->update_note(__('Suspension and cancellation scheduled.', 'subscriptio'), true);
                }
                else {
                    self::schedule_cancellation($subscription->id, $overdue_end_time);
                    $transaction->update_note(__('Cancellation scheduled.', 'subscriptio'), true);
                }
            }

            // Suspend
            else if ($suspension_end_time > 0) {

                // Not yet suspended? (can be suspended manually)
                if ($subscription->status != 'suspended') {

                    // Suspend suscription
                    $subscription->suspend();

                    // Update transaction
                    $transaction->update_result('success');
                    $transaction->update_note(__('Payment not received. Subscription suspended.', 'subscriptio'), true);
                }
                else {
                    $transaction->update_result('error');
                    $transaction->update_note(__('Payment not received but subscription is already suspended.', 'subscriptio'), true);
                }

                // Schedule cancellation
                self::schedule_cancellation($subscription->id, $suspension_end_time);
                $transaction->update_note(__('Cancellation scheduled.', 'subscriptio'), true);
            }

            // Cancel instantly (no overdue or suspension periods configured)
            else {

                // Cancel subscription
                $subscription->cancel();

                // Update transaction
                $transaction->update_result('success');
                $transaction->update_note(__('Payment not received. Subscription cancelled.', 'subscriptio'), true);
            }
        } catch (Exception $e) {
            $transaction->update_result('error');
            $transaction->update_note($e->getMessage(), true);
        }
    }
    /**
     * Send selected email
     * 
     * @access public
     * @param string $alias
     * @param object $object
     * @param array $args
     * @param array $customer_email
     * @return void
     */
    public function send_email($alias, $object, $args = array(), $customer_email = false)
    {
        // Cancel sending emails if this is a duplicate website
        if (!apply_filters('subscriptio_send_email', Subscriptio::is_main_site(), $alias, $object, $args)) {
            return;
        }

        // Cancel sending email if we don't have such email
        if (!isset(self::$aliases[$alias])) {
            return;
        }

        global $woocommerce;

        $woocommerce_mailer = $woocommerce->mailer();
        $emails = $woocommerce_mailer->get_emails();
        $emails[self::$aliases[$alias]]->trigger($object, $args);

        // Check if we need to send a copy of customer email to admin
        if ($customer_email && $emails[self::$aliases[$alias]]->send_to_admin) {
            $emails[self::$aliases[$alias]]->trigger($object, $args, true);
        }
    }