<?php
namespace Bright_Deposits_For_WooCommerce\Emails;

use Bright_Deposits_For_WooCommerce\Helpers\Helper;

/**
 * @package Bright_Deposits_For_WooCommerce\Emails
 * @since 1.0.0
 * @author Bright Plugins
 * Description: This class is responsible for managing the reminder emails for deposit orders.
 */
class ReminderManager {

    public function __construct() {
        // Hook into our custom action that fires after deposit orders are created.
        add_action( 'bdfwbp_deposit_orders_generated', [ $this, 'schedule_reminders_for_order' ], 10, 1 );

        // Hook into Action Scheduler actions
        add_action( 'bdfwbp_send_upcoming_reminder', [ $this, 'send_upcoming_reminder_email' ], 10, 2 );
    }

    /**
     * Schedules reminder actions for a given order.
     * @since 1.0.0
     * @param int $order_id The order ID.
     * @return void
     */
    public function schedule_reminders_for_order( int $order_id ): void {
        
        $order = wc_get_order( $order_id );

        if ( ! $order instanceof \WC_Order ) {
            return;
        }

        /**
         * Check if the order is a deposit order.
         */
        if ( !Helper::isDepositOrder( $order_id ) ) {
            return;
        }

        $days_to_pay_installment = Helper::getOptionValue( 'days_to_pay_installment' );

        /**
         * Fetch all deposit orders related to the main order.
         * This assumes that deposit orders are stored as a custom post type 'shop_deposit'
         * and are children of the main order.
         */
        $deposit_orders = wc_get_orders( array(
            'type'        => 'shop_deposit',
            'parent'      => $order_id,
            'status'      => 'wc-pending', // Only get pending orders
            'orderby'     => 'ID',
            'order'       => 'ASC',
            'limit'       => -1,
        ) );

        if ( ! $deposit_orders ) {
            return;
        }

        $order_created_timestamp = $order->get_date_created()->getTimestamp();

        foreach ( $deposit_orders as $shop_deposit_order ) {

            if ( ! $shop_deposit_order ) {
                continue;
            }

            $due_date_timestamp = null;

            // Try to get due date from the _deposit_due_date meta of the shop_deposit order
            $explicit_due_date = $shop_deposit_order->get_meta( '_deposit_due_date', true );
            if ( ! empty( $explicit_due_date ) ) {
                $due_date_timestamp = strtotime( $explicit_due_date );
            } 
            else {
                // If no explicit due date, calculate it based on order creation date and days_to_pay_installment
                $due_date_timestamp = strtotime( "+{$days_to_pay_installment} days", $order_created_timestamp );
            }

            // If after all checks, due_date_timestamp is still null, then we cannot schedule reminders for this installment
            if ( ! $due_date_timestamp ) {
                continue; // Skip this installment as no valid due date can be determined
            }

            // Determine if the installment is paid based on its status
            $is_paid = in_array( $shop_deposit_order->get_status(), array( 'completed', 'processing' ) ); // Adjust statuses as per your plugin's logic

            // If installment is already paid, no need to schedule reminders
            if ( $is_paid ) {
                continue;
            }

            // Unschedule any existing actions for this installment to prevent duplicates
            as_unschedule_action( 'bdfwbp_send_upcoming_reminder', [ $order_id, $shop_deposit_order->get_id() ] );

            // Schedule upcoming reminder
            $days_before_due = Helper::getOptionValue( 'days_before_due' );
            $upcoming_reminder_timestamp = strtotime( "-{$days_before_due} days", $due_date_timestamp );

            if ( $upcoming_reminder_timestamp > time() ) { // Only schedule if in the future
                as_schedule_single_action( $upcoming_reminder_timestamp, 'bdfwbp_send_upcoming_reminder', [ $order_id, $shop_deposit_order->get_id() ], 'bright-deposits' );
            }
            
        }

        /**
         * BDFWBP_CUSTOM_ACTION_HOOK: Allows developers to add custom function after the reminders are scheduled.
         * @since 1.0.0
         * @param int $order_id The order ID.
         * @return void
         */
		do_action( 'bdfwbp_after_schedule_reminders_for_order', $order_id );
    }

    /**
     * Sends an upcoming deposit reminder email.
     * @since 1.0.0
     * @param int $order_id The parent order ID.
     * @param int $deposit_order_id The shop_deposit order ID (installment ID).
     * @return void
     */
    public function send_upcoming_reminder_email( int $order_id, int $deposit_order_id ): void {
        $parent_order = wc_get_order( $order_id );
        $shop_deposit_order = wc_get_order( $deposit_order_id );

        if ( ! $parent_order instanceof \WC_Order || ! $shop_deposit_order instanceof \WC_Order ) {
            return;
        }

        // Check if reminder already sent for this installment
        if ( $parent_order->get_meta( "_bright_deposits_upcoming_reminder_sent_{$deposit_order_id}", true ) ) {
            return;
        }

        // Check if installment is still due (not completed or processing)
        if ( in_array( $shop_deposit_order->get_status(), array( 'completed', 'processing' ) ) ) {
            return;
        }

        // Send the email using the DepositReminder email class
        $mailer = WC()->mailer();
        $email = $mailer->emails['WC_Customer_Payment_Deposit_Reminder'];
        $admin_email = $mailer->emails['WC_Admin_Payment_Deposit_Reminder'];
        if ( $email ) {
            // Pass the parent order ID to the email trigger, as the email templates expect the main order object
            $email->trigger( $order_id ); 
            $parent_order->update_meta_data( "_bright_deposits_upcoming_reminder_sent_{$deposit_order_id}", true );
            $parent_order->save();
            wc_get_logger()->info( "Upcoming deposit reminder sent for Parent Order #{$order_id}, Deposit Order #{$deposit_order_id}", [ 'source' => 'bright-deposits' ] );
        }

        if ( $admin_email ) {
            // Pass the parent order ID to the email trigger, as the email templates expect the main order object
            $admin_email->trigger( $order_id ); 
        }
    }
    
}