<?php

namespace WeDevs\Wpuf\Pro;

/**
 * Pricing Field Payment Handler
 *
 * Handles payment integration for pricing fields
 *
 * @since 4.2.2
 */
class Pricing_Field_Payment {

    /**
     * Constructor
     *
     * @since 4.2.2
     */
    public function __construct() {
        add_filter( 'wpuf_payment_amount', [ $this, 'add_pricing_fields_cost' ], 10, 2 );
        add_filter( 'wpuf_get_post_cost', [ $this, 'calculate_post_cost_with_pricing' ], 10, 2 );
        add_filter( 'wpuf_add_post_redirect', [ $this, 'redirect_to_payment' ], 20, 4 );
        add_action( 'wp_footer', [ $this, 'fix_payment_page_display' ] );
    }

    /**
     * Calculate pricing fields cost from form submission
     *
     * @since 4.2.2
     *
     * @param int   $post_id Post ID.
     * @param array $form_data Form data (submitted POST data).
     *
     * @return float Pricing fields total cost.
     */
    public function calculate_pricing_cost( $post_id, $form_data ) {
        $total = 0;

        if ( empty( $form_data ) || ! is_array( $form_data ) ) {
            return $total;
        }

        // Get form ID from form_data
        $form_id = null;
        if ( isset( $form_data['form_id'] ) ) {
            $form_id = intval( $form_data['form_id'] );
        } elseif ( isset( $form_data['wpuf_form_id'] ) ) {
            $form_id = intval( $form_data['wpuf_form_id'] );
        }

        if ( ! $form_id ) {
            return $total;
        }

        // Fetch form fields once to avoid multiple database calls
        $form_fields = wpuf_get_form_fields( $form_id );

        if ( empty( $form_fields ) ) {
            return $total;
        }

        foreach ( $form_data as $field_name => $field_value ) {
            // Get field settings from form fields
            $field = $this->get_field_by_name( $field_name, null, $form_fields );

            if ( ! $field ) {
                continue;
            }

            if ( empty( $field['input_type'] ) ) {
                continue;
            }

            $input_type = $field['input_type'];

            // Check if it's a pricing field or regular price field
            $is_pricing_field = in_array( $input_type, [ 'pricing_checkbox', 'pricing_radio', 'pricing_dropdown', 'pricing_multiselect' ], true );
            $is_price_field = 'price_field' === $input_type;

            if ( ! $is_pricing_field && ! $is_price_field ) {
                continue;
            }

            // Calculate cost based on field type
            if ( $is_price_field ) {
                // For regular price field, just use the value directly
                $field_cost = is_numeric( $field_value ) ? floatval( $field_value ) : 0;
            } else {
                // For pricing fields, calculate based on selected options
                $field_cost = $this->calculate_field_cost( $field, $field_value, $field_name );
            }

            $total += $field_cost;
        }

        return $total;
    }

    /**
     * Calculate cost for a single pricing field
     *
     * @since 4.2.2
     *
     * @param array  $field Field settings.
     * @param mixed  $field_value Field value.
     * @param string $field_name Field name.
     *
     * @return float Field cost.
     */
    private function calculate_field_cost( $field, $field_value, $field_name ) {
        $cost = 0;

        if ( empty( $field['prices'] ) || ! is_array( $field['prices'] ) ) {
            return $cost;
        }

        $input_type = $field['input_type'];

        // Handle different field types
        switch ( $input_type ) {
            case 'pricing_checkbox':
            case 'pricing_multiselect':
                // Multiple selections - handle both array and pipe-separated string
                $values = $field_value;

                // Convert pipe-separated string to array if needed
                if ( ! is_array( $values ) && is_string( $values ) ) {
                    $values = array_map( 'trim', explode( '|', $values ) );
                }

                if ( is_array( $values ) ) {
                    foreach ( $values as $value ) {
                        if ( isset( $field['prices'][$value] ) ) {
                            $price = floatval( $field['prices'][$value] );
                            $qty = $this->get_quantity( $field_name, $value );
                            $cost += $price * $qty;
                        }
                    }
                }
                break;

            case 'pricing_radio':
            case 'pricing_dropdown':
                // Single selection
                if ( ! empty( $field_value ) && isset( $field['prices'][$field_value] ) ) {
                    $price = floatval( $field['prices'][$field_value] );
                    $qty = $this->get_quantity( $field_name );
                    $cost += $price * $qty;
                }
                break;
        }

        return $cost;
    }

    /**
     * Get quantity for pricing field
     *
     * @since 4.2.2
     *
     * @param string $field_name Field name.
     * @param string $value Option value (for multiselect).
     *
     * @return int Quantity.
     */
    private function get_quantity( $field_name, $value = null ) {
        $qty = 1;

        if ( null !== $value ) {
            // For multiselect with individual quantities
            $qty_field = $field_name . '_qty';
            if ( isset( $_POST[$qty_field][$value] ) ) {
                $qty = max( 1, intval( $_POST[$qty_field][$value] ) );
            }
        } else {
            // For single selection
            $qty_field = $field_name . '_qty';
            if ( isset( $_POST[$qty_field] ) ) {
                $qty = max( 1, intval( $_POST[$qty_field] ) );
            }
        }

        return $qty;
    }

    /**
     * Get field settings by field name
     *
     * @since 4.2.2
     *
     * @param string     $field_name Field name.
     * @param array|null $form_data Form data (submitted POST data) - for backward compatibility.
     * @param array|null $form_fields Form field definitions (to avoid database calls).
     *
     * @return array|null Field settings or null.
     */
    private function get_field_by_name( $field_name, $form_data = null, $form_fields = null ) {
        // If form_fields are provided, use them directly (optimized path)
        if ( ! empty( $form_fields ) && is_array( $form_fields ) ) {
            foreach ( $form_fields as $field ) {
                if ( isset( $field['name'] ) && $field_name === $field['name'] ) {
                    return $field;
                }
            }
            return null;
        }

        // Fallback to database call (legacy path for backward compatibility)
        // Try to get form_id from form_data first, then fallback to $_POST
        $form_id = null;
        if ( $form_data && isset( $form_data['form_id'] ) ) {
            $form_id = intval( $form_data['form_id'] );
        } elseif ( isset( $_POST['wpuf_form_id'] ) ) {
            $form_id = intval( $_POST['wpuf_form_id'] );
        } elseif ( isset( $_POST['form_id'] ) ) {
            $form_id = intval( $_POST['form_id'] );
        }

        if ( ! $form_id ) {
            return null;
        }

        $form_settings = wpuf_get_form_fields( $form_id );

        if ( empty( $form_settings ) ) {
            return null;
        }

        foreach ( $form_settings as $field ) {
            if ( isset( $field['name'] ) && $field_name === $field['name'] ) {
                return $field;
            }
        }

        return null;
    }

    /**
     * Add pricing fields cost to payment amount
     *
     * @since 4.2.2
     *
     * @param float $amount Current amount.
     * @param int   $post_id Post ID (optional).
     *
     * @return float Modified amount.
     */
    public function add_pricing_fields_cost( $amount, $post_id = 0 ) {
        if ( ! $post_id ) {
            return $amount;
        }

        // Get form ID from post meta
        $form_id = get_post_meta( $post_id, '_wpuf_form_id', true );
        if ( ! $form_id ) {
            return $amount;
        }

        // Check if pricing payment is enabled for this form
        $form_settings = wpuf_get_form_settings( $form_id );
        if ( ! $this->is_pricing_payment_enabled( $form_settings ) ) {
            return $amount;
        }

        $pricing_cost = get_post_meta( $post_id, '_wpuf_pricing_field_cost', true );

        if ( $pricing_cost && is_numeric( $pricing_cost ) ) {
            // Replace the amount with pricing field cost (independent payment option)
            return floatval( $pricing_cost );
        }

        return $amount;
    }

    /**
     * Calculate post cost including pricing fields
     *
     * @since 4.2.2
     *
     * @param float $cost Current cost.
     * @param int   $post_id Post ID.
     *
     * @return float Modified cost.
     */
    public function calculate_post_cost_with_pricing( $cost, $post_id ) {
        $pricing_cost = get_post_meta( $post_id, '_wpuf_pricing_field_cost', true );

        if ( $pricing_cost && is_numeric( $pricing_cost ) ) {
            $cost += floatval( $pricing_cost );
        }

        return $cost;
    }

    /**
     * Check if pricing field payment is enabled for a form
     *
     * @since 4.2.2
     *
     * @param array $form_settings Form settings array.
     *
     * @return bool True if enabled, false otherwise.
     */
    private function is_pricing_payment_enabled( $form_settings ) {
        return isset( $form_settings['enable_pricing_payment'] ) && wpuf_is_checkbox_or_toggle_on( $form_settings['enable_pricing_payment'] );
    }

    /**
     * Redirect to payment page if pricing payment is enabled
     *
     * @since 4.2.2
     *
     * @param array  $response Response array with redirect_to and show_message.
     * @param int    $post_id Post ID.
     * @param int    $form_id Form ID.
     * @param array  $form_settings Form settings.
     *
     * @return array Modified response array.
     */
    public function redirect_to_payment( $response, $post_id, $form_id, $form_settings ) {
        // Check if this is an update
        $is_update = isset( $_POST['post_id'] ) && ! empty( $_POST['post_id'] );

        // Only redirect for new posts with pricing payment enabled
        if ( $is_update ) {
            return $response;
        }

        // Check if pricing payment is enabled
        if ( ! $this->is_pricing_payment_enabled( $form_settings ) ) {
            return $response;
        }

        // Calculate and save pricing cost
        $pricing_cost = $this->calculate_pricing_cost( $post_id, $_POST );

        if ( $pricing_cost > 0 ) {
            update_post_meta( $post_id, '_wpuf_pricing_field_cost', $pricing_cost );
        }

        // Check if there's a pricing cost
        if ( ! $pricing_cost || floatval( $pricing_cost ) <= 0 ) {
            return $response;
        }

        // Redirect to payment page (independent payment option)
        $response['show_message'] = false;
        $response['redirect_to']  = add_query_arg(
            [
                'action'  => 'wpuf_pay',
                'type'    => 'post',
                'post_id' => $post_id,
            ],
            get_permalink( wpuf_get_option( 'payment_page', 'wpuf_payment' ) )
        );

        return $response;
    }

    /**
     * Fix payment page display to show pricing field cost
     *
     * @since 4.2.2
     */
    public function fix_payment_page_display() {
        // Only run on payment page with post type
        if ( ! isset( $_GET['action'] ) || 'wpuf_pay' !== $_GET['action'] ) {
            return;
        }
        if ( ! isset( $_GET['type'] ) || 'post' !== $_GET['type'] ) {
            return;
        }
        if ( ! isset( $_GET['post_id'] ) ) {
            return;
        }

        $post_id = intval( $_GET['post_id'] );
        $form_id = get_post_meta( $post_id, '_wpuf_form_id', true );

        if ( ! $form_id ) {
            return;
        }

        // Check if pricing payment is enabled
        $form_settings = wpuf_get_form_settings( $form_id );
        if ( ! $this->is_pricing_payment_enabled( $form_settings ) ) {
            return;
        }

        // Get the pricing cost
        $pricing_cost = get_post_meta( $post_id, '_wpuf_pricing_field_cost', true );
        if ( ! $pricing_cost || ! is_numeric( $pricing_cost ) ) {
            return;
        }

        // Format price
        $formatted_cost = number_format( $pricing_cost, 2 );
        ?>
        <script type="text/javascript">
        jQuery(document).ready(function($) {
            $('#wpuf_pay_page_cost').html('<?php echo esc_js( $formatted_cost ); ?>');
            $('#wpuf_pay_page_total').html('<?php echo esc_js( $formatted_cost ); ?>');
        });
        </script>
        <?php
    }
}
