<?php

/**
 * Notification manager.
 *
 * @package CartNinjaRecovery
 */
if ( !defined( 'ABSPATH' ) ) {
    exit;
}
class CARTNINJA_Notification_Manager {
    private $sms_sender;

    private $email_sender;

    private $scheduler;

    public function __construct( CARTNINJA_SMS_Sender $sms_sender, CARTNINJA_Email_Sender $email_sender, CARTNINJA_Scheduler $scheduler ) {
        $this->sms_sender = $sms_sender;
        $this->email_sender = $email_sender;
        $this->scheduler = $scheduler;
    }

    public function schedule_notification( $cart_id, $channel = 'sms' ) {
        $this->scheduler->schedule_notification( absint( $cart_id ), sanitize_key( $channel ) );
    }

    public function process_scheduled_notification( $cart_id, $channel = 'sms' ) {
        $cart_id = absint( $cart_id );
        $channel = sanitize_key( $channel );
        $settings = get_option( 'cartninja_settings', array() );
        $general = ( isset( $settings['general'] ) ? $settings['general'] : array() );
        if ( 'sms' === $channel && 'yes' !== (( isset( $general['enable_sms'] ) ? $general['enable_sms'] : 'yes' )) ) {
            return;
        }
        if ( 'email' === $channel && 'yes' !== (( isset( $general['enable_email'] ) ? $general['enable_email'] : 'yes' )) ) {
            return;
        }
        $cart = $this->get_cart( $cart_id );
        if ( empty( $cart ) || 'abandoned' !== $cart['status'] ) {
            return;
        }
        if ( 'email' === $channel ) {
            if ( empty( $cart['email'] ) || $this->has_notification( $cart_id, 'email' ) ) {
                return;
            }
            $result = $this->email_sender->send_cart_email( $cart );
            $this->log_attempt(
                $cart_id,
                'email',
                $cart['email'],
                $result['message'],
                $result
            );
            return;
        }
        if ( empty( $cart['phone'] ) || $this->has_notification( $cart_id, 'sms' ) ) {
            return;
        }
        $result = $this->sms_sender->send_cart_sms( $cart );
        $this->log_attempt(
            $cart_id,
            'sms',
            $cart['phone'],
            $result['message'],
            $result
        );
    }

    public function send_test_sms( $phone ) {
        return $this->sms_sender->send_cart_sms( array(
            'phone'          => sanitize_text_field( $phone ),
            'cart_total'     => '1999.00',
            'recovery_token' => wp_generate_password( 32, false, false ),
        ), array(
            'customer_name' => __( 'Test Customer', 'cartninja-recovery-for-woocommerce' ),
            'cart_url'      => home_url( '/cart/?cartninja_token=test-token' ),
            'site_name'     => wp_specialchars_decode( get_bloginfo( 'name' ), ENT_QUOTES ),
        ) );
    }

    public function send_test_email( $email, $context = array() ) {
        $cart = array(
            'email'          => sanitize_email( $email ),
            'cart_total'     => '1999.00',
            'currency'       => ( function_exists( 'get_woocommerce_currency' ) ? get_woocommerce_currency() : '' ),
            'recovery_token' => 'test-token',
            'coupon_code'    => 'WELCOME10',
            'cart_contents'  => wp_json_encode( array(array(
                'product_name' => __( 'CartNinja Sample Product', 'cartninja-recovery-for-woocommerce' ),
                'quantity'     => 1,
                'line_total'   => 1299.0,
            ), array(
                'product_name' => __( 'Recovery Demo Add-on', 'cartninja-recovery-for-woocommerce' ),
                'quantity'     => 2,
                'line_total'   => 700.0,
            )) ),
        );
        $context = wp_parse_args( $context, array(
            'customer_name' => __( 'Test Customer', 'cartninja-recovery-for-woocommerce' ),
            'cart_url'      => home_url( '/cart/?cartninja_token=test-token' ),
            'site_name'     => wp_specialchars_decode( get_bloginfo( 'name' ), ENT_QUOTES ),
            'coupon_code'   => 'WELCOME10',
        ) );
        return $this->email_sender->send_cart_email( $cart, $context );
    }

    public function retry_failed_notification( $cart_id, $channel ) {
        $cart_id = absint( $cart_id );
        $channel = sanitize_key( $channel );
        $valid_channels = array('sms', 'email');
        if ( !$cart_id || !in_array( $channel, $valid_channels, true ) ) {
            return false;
        }
        $cart = $this->get_cart( $cart_id );
        if ( !$cart || in_array( $cart['status'], array('recovered'), true ) ) {
            return false;
        }
        if ( !$this->can_retry_failed_notification( $cart_id, $channel ) ) {
            return false;
        }
        $this->process_scheduled_notification( $cart_id, $channel );
        return $this->has_successful_notification( $cart_id, $channel );
    }

    private function log_attempt(
        $cart_id,
        $channel,
        $recipient,
        $message,
        $result
    ) {
        global $wpdb;
        $status = ( isset( $result['status'] ) ? sanitize_key( $result['status'] ) : 'failed' );
        $wpdb->insert( $wpdb->prefix . 'cartninja_notifications', array(
            'cart_id'            => absint( $cart_id ),
            'channel'            => sanitize_key( $channel ),
            'recipient'          => sanitize_text_field( $recipient ),
            'message_sent'       => sanitize_textarea_field( $message ),
            'status'             => $status,
            'gateway_message_id' => ( isset( $result['gateway_message_id'] ) ? sanitize_text_field( $result['gateway_message_id'] ) : '' ),
            'error_message'      => ( isset( $result['error_message'] ) ? sanitize_textarea_field( $result['error_message'] ) : '' ),
            'scheduled_at'       => current_time( 'mysql' ),
            'sent_at'            => ( in_array( $status, array('sent', 'clicked'), true ) ? current_time( 'mysql' ) : null ),
            'clicked_at'         => ( 'clicked' === $status ? current_time( 'mysql' ) : null ),
        ), array(
            '%d',
            '%s',
            '%s',
            '%s',
            '%s',
            '%s',
            '%s',
            '%s',
            '%s',
            '%s'
        ) );
    }

    private function has_notification( $cart_id, $channel ) {
        global $wpdb;
        $count = (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM {$wpdb->prefix}cartninja_notifications WHERE cart_id = %d AND channel = %s AND status IN ('pending','sent','clicked')", $cart_id, $channel ) );
        return $count > 0;
    }

    private function has_successful_notification( $cart_id, $channel ) {
        global $wpdb;
        $count = (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM {$wpdb->prefix}cartninja_notifications WHERE cart_id = %d AND channel = %s AND status IN ('sent','clicked')", $cart_id, $channel ) );
        return $count > 0;
    }

    private function can_retry_failed_notification( $cart_id, $channel ) {
        global $wpdb;
        if ( $this->has_successful_notification( $cart_id, $channel ) ) {
            return false;
        }
        $latest_status = $wpdb->get_var( $wpdb->prepare( "SELECT status FROM {$wpdb->prefix}cartninja_notifications WHERE cart_id = %d AND channel = %s ORDER BY id DESC LIMIT 1", $cart_id, $channel ) );
        return 'failed' === $latest_status;
    }

    private function get_cart( $cart_id ) {
        global $wpdb;
        return $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}cartninja_carts WHERE id = %d", $cart_id ), ARRAY_A );
    }

}
