<?php
/**
 * Email Notifications — customer + merchant on wpnest_rfw_request_submitted.
 * Plaintext in Free; bodies pass through filters so Pro can swap to HTML templates.
 *
 * @package WPNest_Returns_For_WooCommerce
 */

if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

class WPNest_RFW_Email_Notifications {

    private static $instance = null;

    public static function get_instance() {
        if ( null === self::$instance ) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    /**
     * Per-request opt-out flag. Set via {@see self::skip_next_status_change()}
     * before triggering an update_status() that should NOT trigger an email
     * (e.g. admin un-checked "Notify customer" in the detail-page form).
     *
     * @var bool
     */
    private static $skip_next = false;

    private function __construct() {
        add_action( 'wpnest_rfw_request_submitted', array( $this, 'send_emails' ), 20, 2 );

        // Free's contract: every status transition emails the customer by default.
        // The global toggle `wpnest_rfw_notify_customer_on_status` and the per-change
        // `self::$skip_next` flag let admins suppress when needed; Pro can replace the
        // body via the `wpnest_rfw_status_change_email_body` filter.
        add_action( 'wpnest_rfw_status_changed', array( $this, 'maybe_send_status_change' ), 20, 3 );

        // Backward compat: anything calling the old action still fires the same email.
        add_action( 'wpnest_rfw_admin_status_changed_notify', array( $this, 'send_status_change_email' ), 20, 3 );
    }

    /**
     * Caller sets this flag BEFORE update_status() to suppress the email for
     * exactly one transition.
     */
    public static function skip_next_status_change() {
        self::$skip_next = true;
    }

    /**
     * Auto-handler that decides whether to send the status-change email
     * (global toggle, skip flag, per-status filter), then delegates to
     * send_status_change_email() for the actual mail rendering.
     *
     * @param int    $request_id
     * @param string $old_status
     * @param string $new_status
     */
    public function maybe_send_status_change( $request_id, $old_status, $new_status ) {
        // Per-change opt-out takes priority over the global toggle.
        if ( self::$skip_next ) {
            self::$skip_next = false;
            return;
        }

        if ( ! get_option( 'wpnest_rfw_notify_customer_on_status', 1 ) ) {
            return;
        }

        // No-op if nothing actually changed (update_status() does log same-status updates).
        if ( (string) $old_status === (string) $new_status ) {
            return;
        }

        $request = WPNest_RFW_Request_Model::get( (int) $request_id );
        if ( ! $request ) {
            return;
        }
        $order = wc_get_order( (int) $request->order_id );
        if ( ! $order instanceof WC_Order ) {
            return;
        }

        // Pro can suppress per-status (e.g. send only on accepted/refunded).
        $should_send = apply_filters( 'wpnest_rfw_send_status_change_email', true, (int) $request_id, $new_status, $order );
        if ( ! $should_send ) {
            return;
        }

        $this->send_status_change_email( (int) $request_id, $new_status, $order );
    }

    /**
     * Renders + sends the email for one status transition. Safe to call directly;
     * does no permission or duplicate-detection work — those are the caller's job.
     *
     * @param int      $request_id
     * @param string   $new_status
     * @param WC_Order $order
     */
    public function send_status_change_email( $request_id, $new_status, $order ) {
        if ( ! $order instanceof WC_Order ) {
            return;
        }
        $to = $order->get_billing_email();
        if ( ! $to ) {
            return;
        }

        $statuses     = WPNest_RFW_Request_Model::get_statuses();
        $status_label = isset( $statuses[ $new_status ] ) ? $statuses[ $new_status ] : ucfirst( (string) $new_status );

        $subject = sprintf(
            /* translators: 1: order number, 2: new status label */
            __( 'Update on your return request for order #%1$s — %2$s', 'wpnest-returns-for-woocommerce' ),
            $order->get_order_number(),
            $status_label
        );

        /* translators: %s: customer first name */
        $body  = sprintf( __( 'Hello %s,', 'wpnest-returns-for-woocommerce' ), $order->get_billing_first_name() ) . "\n\n";
        $body .= sprintf(
            /* translators: 1: order number, 2: new status label */
            __( 'Your return request for order #%1$s has been updated to: %2$s.', 'wpnest-returns-for-woocommerce' ),
            $order->get_order_number(),
            $status_label
        ) . "\n\n";

        switch ( $new_status ) {
            case WPNest_RFW_Request_Model::STATUS_ACCEPTED:
                $body .= __( 'Next steps: please send the items back to us using the address from your order confirmation. We will inspect them and issue a refund.', 'wpnest-returns-for-woocommerce' ) . "\n\n";
                break;
            case WPNest_RFW_Request_Model::STATUS_REJECTED:
                $body .= __( 'Unfortunately we could not accept this return. If you have questions, reply to this email and we will get back to you.', 'wpnest-returns-for-woocommerce' ) . "\n\n";
                break;
            case WPNest_RFW_Request_Model::STATUS_REFUNDED:
                $body .= __( 'A refund has been issued. Depending on your bank, it may take a few business days for the funds to appear on your statement.', 'wpnest-returns-for-woocommerce' ) . "\n\n";
                break;
        }

        $body .= __( 'Thank you,', 'wpnest-returns-for-woocommerce' ) . "\n";
        $body .= sprintf(
            /* translators: %s: store name */
            __( '%s team', 'wpnest-returns-for-woocommerce' ),
            get_bloginfo( 'name' )
        );

        $body = apply_filters( 'wpnest_rfw_status_change_email_body', $body, (int) $request_id, $new_status, $order );

        wp_mail( $to, $subject, $body );
    }

    public function send_emails( $request_id, $order ) {
        if ( ! $order instanceof WC_Order ) {
            return;
        }
        $request = WPNest_RFW_Request_Model::get( (int) $request_id );
        if ( ! $request ) {
            return;
        }

        $attachments = array();
        if ( $request->pdf_path && file_exists( $request->pdf_path ) ) {
            $attachments[] = (string) $request->pdf_path;
        }

        $this->send_customer_email( $request, $order, $attachments );
        $this->send_merchant_email( $request, $order );
    }

    private function send_customer_email( $request, WC_Order $order, array $attachments ) {
        $to = $order->get_billing_email();
        if ( ! $to ) {
            return;
        }
        $subject = sprintf(
            /* translators: %s: order number */
            __( 'Your return request for order #%s has been received', 'wpnest-returns-for-woocommerce' ),
            $order->get_order_number()
        );

        /* translators: %s: customer first name */
        $body  = sprintf( __( 'Hello %s,', 'wpnest-returns-for-woocommerce' ), $order->get_billing_first_name() ) . "\n\n";
        $body .= sprintf(
            /* translators: %s: order number */
            __( 'We have received your return request for order #%s.', 'wpnest-returns-for-woocommerce' ),
            $order->get_order_number()
        ) . "\n\n";
        $body .= __( 'Items being returned:', 'wpnest-returns-for-woocommerce' ) . "\n";
        $body .= self::format_items_block( $order, $request );
        $body .= "\n";
        $body .= sprintf(
            /* translators: %s: ISO-8601 date */
            __( 'Submitted on: %s UTC', 'wpnest-returns-for-woocommerce' ),
            (string) $request->created_at
        ) . "\n\n";
        $body .= __( 'Next steps: our team will review your request and contact you with refund instructions. If you have not yet sent the item back, please follow the instructions you receive in the next email.', 'wpnest-returns-for-woocommerce' ) . "\n\n";
        $body .= __( 'A confirmation PDF is attached to this email for your records.', 'wpnest-returns-for-woocommerce' ) . "\n\n";
        $body .= __( 'Thank you,', 'wpnest-returns-for-woocommerce' ) . "\n";
        $body .= sprintf(
            /* translators: %s: store name */
            __( '%s team', 'wpnest-returns-for-woocommerce' ),
            get_bloginfo( 'name' )
        );

        $body = apply_filters( 'wpnest_rfw_customer_email_body', $body, (int) $request->id, $order );

        wp_mail( $to, $subject, $body, array(), $attachments );
    }

    private function send_merchant_email( $request, WC_Order $order ) {
        $to = (string) get_option( 'wpnest_rfw_merchant_email', '' );
        if ( ! $to ) {
            $to = (string) get_option( 'admin_email', '' );
        }
        if ( ! $to ) {
            return;
        }
        $subject = sprintf(
            /* translators: %s: order number */
            __( 'New return request for order #%s', 'wpnest-returns-for-woocommerce' ),
            $order->get_order_number()
        );

        $customer_name = trim( $order->get_billing_first_name() . ' ' . $order->get_billing_last_name() );

        $body  = __( 'A new return request has been submitted.', 'wpnest-returns-for-woocommerce' ) . "\n\n";
        $body .= sprintf( /* translators: %s: order number */ __( 'Order: #%s', 'wpnest-returns-for-woocommerce' ), $order->get_order_number() ) . "\n";
        if ( $customer_name ) {
            $body .= sprintf( /* translators: %s: customer name */ __( 'Customer: %s', 'wpnest-returns-for-woocommerce' ), $customer_name ) . "\n";
        }
        $body .= sprintf( /* translators: %s: customer email */ __( 'Email: %s', 'wpnest-returns-for-woocommerce' ), $order->get_billing_email() ) . "\n";

        $body .= "\n" . __( 'Items being returned:', 'wpnest-returns-for-woocommerce' ) . "\n";
        $body .= self::format_items_block( $order, $request );

        $body .= "\n" . sprintf(
            /* translators: %s: admin URL */
            __( 'Manage in admin: %s', 'wpnest-returns-for-woocommerce' ),
            admin_url( 'admin.php?page=wpnest-rfw-requests' )
        ) . "\n";

        $body = apply_filters( 'wpnest_rfw_merchant_email_body', $body, (int) $request->id, $order );

        wp_mail( $to, $subject, $body );
    }

    /**
     * Build a plaintext list of returned items + reasons for both emails.
     */
    private static function format_items_block( WC_Order $order, $request ) {
        $rows = WPNest_RFW_Request_Item_Model::get_for_request( (int) $request->id );
        if ( empty( $rows ) ) {
            return "  - " . __( '(See linked order for details.)', 'wpnest-returns-for-woocommerce' ) . "\n";
        }
        $out = '';
        foreach ( $rows as $ir ) {
            $name = '';
            $oi   = $order->get_item( (int) $ir->order_item_id );
            if ( $oi ) {
                $name = $oi->get_name();
            }
            if ( '' === $name && $ir->product_id ) {
                $p = wc_get_product( (int) $ir->product_id );
                $name = $p ? $p->get_name() : ( '#' . (int) $ir->product_id );
            }
            $reason = WPNest_RFW_Reason_Codes::get_label( (string) $ir->reason_code );
            $out   .= '  - ' . (int) $ir->qty . ' x ' . $name . ' — ' . $reason . "\n";
            if ( $ir->reason_text ) {
                $out .= '      "' . trim( (string) $ir->reason_text ) . '"' . "\n";
            }
        }
        return $out;
    }
}
