<?php
/**
 * Form Handler — server-side processing of a return request (per-item wizard payload).
 * Called by the REST controller after auth/nonce checks.
 *
 * @package WPNest_Returns_For_WooCommerce
 */

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

class WPNest_RFW_Form_Handler {

    /**
     * Process a submission and return the new request row or WP_Error.
     *
     * @param array $payload {
     *     order_id (int), items (array of {order_item_id, qty, reason_code, reason_text}),
     *     guest_token (string|null), ip (string)
     * }
     * @return array|WP_Error  ['request_id'=>int, 'order_id'=>int, 'message'=>string]
     */
    public static function submit( array $payload ) {
        $order_id = isset( $payload['order_id'] ) ? (int) $payload['order_id'] : 0;
        if ( $order_id <= 0 ) {
            return new WP_Error( 'invalid_order', __( 'Invalid order.', 'wpnest-returns-for-woocommerce' ) );
        }

        $order = wc_get_order( $order_id );
        if ( ! $order instanceof WC_Order ) {
            return new WP_Error( 'invalid_order', __( 'Order not found.', 'wpnest-returns-for-woocommerce' ) );
        }

        $eligibility = WPNest_RFW_Eligibility::evaluate( $order_id );
        if ( empty( $eligibility['eligible'] ) ) {
            return new WP_Error( 'not_eligible', $eligibility['reason'] );
        }

        $items_in = isset( $payload['items'] ) && is_array( $payload['items'] ) ? $payload['items'] : array();
        $validated = self::validate_items( $order, $items_in );
        if ( is_wp_error( $validated ) ) {
            return $validated;
        }

        $ip_raw  = isset( $payload['ip'] ) ? (string) $payload['ip'] : '';
        $ip_hash = $ip_raw ? hash_hmac( 'sha256', $ip_raw, wp_salt( 'auth' ) ) : '';

        $reason_summary = self::build_reason_summary( $validated );

        $request_id = WPNest_RFW_Request_Model::create(
            array(
                'order_id'     => $order_id,
                'customer_id'  => $order->get_customer_id() ? (int) $order->get_customer_id() : null,
                'order_key'    => (string) $order->get_order_key(),
                'reason'       => $reason_summary,
                'has_returned' => 0,
                'is_digital'   => WPNest_RFW_Eligibility::is_digital_order( $order ) ? 1 : 0,
                'ip_hash'      => $ip_hash,
            )
        );

        if ( ! $request_id ) {
            return new WP_Error( 'create_failed', __( 'Could not store the return request. Please try again later.', 'wpnest-returns-for-woocommerce' ) );
        }

        WPNest_RFW_Request_Item_Model::create_many( $request_id, $validated );

        $order->update_status(
            'rfw-pending',
            __( 'Return requested by customer.', 'wpnest-returns-for-woocommerce' )
        );

        $pdf_path = WPNest_RFW_PDF_Generator::generate_confirmation( $request_id );
        if ( $pdf_path ) {
            WPNest_RFW_Request_Model::update_column( $request_id, 'pdf_path', $pdf_path, '%s' );
        }

        if ( ! empty( $payload['guest_token'] ) ) {
            WPNest_RFW_Guest_Handler::consume_token( (string) $payload['guest_token'] );
        }

        do_action( 'wpnest_rfw_request_submitted', $request_id, $order );

        return array(
            'request_id' => $request_id,
            'order_id'   => $order_id,
            'message'    => __( 'Your return request has been received. Check your email for confirmation.', 'wpnest-returns-for-woocommerce' ),
        );
    }

    /**
     * Validates and normalizes the wizard's items payload against the order's actual items.
     *
     * @param WC_Order $order
     * @param array    $items_in
     * @return array|WP_Error  Normalized items ready for create_many().
     */
    private static function validate_items( WC_Order $order, array $items_in ) {
        if ( empty( $items_in ) ) {
            return new WP_Error( 'no_items', __( 'Please select at least one item to return.', 'wpnest-returns-for-woocommerce' ) );
        }

        $order_items = $order->get_items();
        $by_id       = array();
        foreach ( $order_items as $oi_id => $oi ) {
            if ( $oi instanceof WC_Order_Item_Product ) {
                $by_id[ (int) $oi_id ] = $oi;
            }
        }

        $out = array();
        foreach ( $items_in as $raw ) {
            if ( ! is_array( $raw ) ) {
                continue;
            }
            $oi_id = isset( $raw['order_item_id'] ) ? (int) $raw['order_item_id'] : 0;
            if ( ! isset( $by_id[ $oi_id ] ) ) {
                return new WP_Error( 'invalid_item', __( 'One of the selected items does not belong to this order.', 'wpnest-returns-for-woocommerce' ) );
            }

            $order_item = $by_id[ $oi_id ];
            $max_qty    = max( 1, (int) $order_item->get_quantity() );
            $qty        = isset( $raw['qty'] ) ? (int) $raw['qty'] : 0;
            if ( $qty < 1 || $qty > $max_qty ) {
                return new WP_Error(
                    'invalid_qty',
                    sprintf(
                        /* translators: 1: product name, 2: maximum allowed quantity */
                        __( 'Quantity for "%1$s" must be between 1 and %2$d.', 'wpnest-returns-for-woocommerce' ),
                        $order_item->get_name(),
                        $max_qty
                    )
                );
            }

            $reason_code = isset( $raw['reason_code'] ) ? sanitize_key( (string) $raw['reason_code'] ) : '';
            if ( ! WPNest_RFW_Reason_Codes::is_valid( $reason_code ) ) {
                return new WP_Error( 'invalid_reason', __( 'Please choose a return reason for every selected item.', 'wpnest-returns-for-woocommerce' ) );
            }

            $reason_text = isset( $raw['reason_text'] ) ? wp_strip_all_tags( (string) $raw['reason_text'] ) : '';
            $reason_text = mb_substr( trim( $reason_text ), 0, 1000 );

            if ( WPNest_RFW_Reason_Codes::requires_text( $reason_code ) && '' === $reason_text ) {
                return new WP_Error(
                    'reason_text_required',
                    sprintf(
                        /* translators: %s: product name */
                        __( 'Please describe the reason for "%s".', 'wpnest-returns-for-woocommerce' ),
                        $order_item->get_name()
                    )
                );
            }

            $product      = $order_item->get_product();
            $product_id   = $product ? (int) $product->get_id() : 0;
            $variation_id = 0;
            if ( $product instanceof WC_Product_Variation ) {
                $variation_id = $product_id;
                $product_id   = (int) $product->get_parent_id();
            }

            $out[] = array(
                'order_item_id' => $oi_id,
                'product_id'    => $product_id,
                'variation_id'  => $variation_id,
                'qty'           => $qty,
                'reason_code'   => $reason_code,
                'reason_text'   => $reason_text,
            );
        }

        if ( empty( $out ) ) {
            return new WP_Error( 'no_items', __( 'Please select at least one item to return.', 'wpnest-returns-for-woocommerce' ) );
        }

        return $out;
    }

    /**
     * Builds a short human-readable summary string saved into `wpnest_rfw_requests.reason`,
     * so existing admin lists and CSV exports keep a quick-scan column.
     *
     * @param array $items_validated
     * @return string
     */
    private static function build_reason_summary( array $items_validated ) {
        $counts = array();
        foreach ( $items_validated as $item ) {
            $code = (string) $item['reason_code'];
            $counts[ $code ] = isset( $counts[ $code ] ) ? $counts[ $code ] + 1 : 1;
        }
        $parts = array();
        foreach ( $counts as $code => $n ) {
            $parts[] = $n > 1
                ? sprintf( '%s (×%d)', WPNest_RFW_Reason_Codes::get_label( $code ), $n )
                : WPNest_RFW_Reason_Codes::get_label( $code );
        }
        return implode( '; ', $parts );
    }
}
