<?php

defined( 'ABSPATH' ) or exit;

function pwlpar_add_signup_bonus_points( $member ) {
    if ( !pwlpar_is_active_or_admin() ) {
        return;
    }

    if ( pwlpar_signup_bonus_points() <= 0 ) {
        return;
    }

    return pwlpar_add_transaction( array(
        'user_id' => $member->get_id(),
        'points' => pwlpar_signup_bonus_points(),
        'note' => pwlpar_signup_bonus_transaction_note(),
    ) );
}

function pwlpar_calculate_max_potential_product_points( $product_id ) {
    $product = wc_get_product( $product_id );
    if ( !is_a( $product, 'WC_Product' ) ) {
        return 0;
    }

    $points = 0;
    if ( !pwlpar_earning_excludes_on_sale() || !$product->is_on_sale() ) {
        $price = 0;
        if ( is_a( $product, 'WC_Product_Variable' ) ) {
            $price = $product->get_variation_price( 'max', false );
        } else {
            $price = $product->get_price();
        }
        $points = max( $points, pwlpar_dollars_to_points( $price ) );
    }

    return apply_filters( 'pwlpar_calculate_max_potential_product_points', $points, $product_id );
}

function pwlpar_calculate_cart_product_points( $cart_item ) {
    $product = $cart_item['data'];
    if ( !is_a( $product, 'WC_Product' ) ) {
        pwlpar_log( 'pwlpar_calculate_cart_product_points: Invalid product [$cart_item: ' . implode( ', ', $cart_item ) . ']', 'error' );
        return 0;
    }

    if ( pwlpar_earning_excludes_on_sale() && $product->is_on_sale() ) {
        return apply_filters( 'pwlpar_calculate_cart_product_points', 0, $cart_item, $product );
    }

    if ( pwlpar_earning_excludes_coupons() ) {
        $price = $cart_item['line_total'];
        if ( pwlpar_earning_includes_tax() ) {
            $price += $cart_item['line_total_tax'];
        }
    } else {
        $price = $cart_item['line_subtotal'];
        if ( pwlpar_earning_includes_tax() ) {
            $price += $cart_item['line_subtotal_tax'];
        }
    }

    $product_points = pwlpar_dollars_to_points( $price ) / $cart_item['quantity'];

    return apply_filters( 'pwlpar_calculate_cart_product_points', $product_points, $cart_item, $product );
}

function pwlpar_calculate_earned_cart_points() {
    $cart = WC()->cart;
    if ( !is_a( $cart, 'WC_Cart' ) ) {
        return 0;
    }

    $cart_points = 0;

    // Loop over all cart items and add product points to the cart points total.
    $cart_items = pwlpar_flatten_and_sort_cart_items( $cart->get_cart() );
    foreach ( $cart_items as $cart_item ) {
        $product_points = pwlpar_calculate_cart_product_points( $cart_item );
        $product = $cart_item['data'];

        $cart_points += $product_points;
    }

    if ( pwlpar_earning_includes_shipping() ) {
        $shipping = $cart->get_shipping_total( 'edit' );
        if ( pwlpar_earning_includes_tax() ) {
            $shipping += $cart->get_shipping_tax( 'edit' );
        }

        $cart_points += pwlpar_dollars_to_points( $shipping );
    }

    return apply_filters( 'pwlpar_calculate_earned_cart_points', $cart_points, $cart );
}

function pwlpar_add_earned_order_points( $order, $points, $note = false ) {
    if ( !is_a( $order, 'WC_Order' ) && !empty( absint( $order ) ) ) {
        $order = wc_get_order( $order );
    }

    if ( !is_a( $order, 'WC_Order' ) ) {
        pwlpar_log( 'pwlpar_add_earned_order_points: Invalid Order [$order: ' . implode( ', ', $order ) . ']' );
        return false;
    }

    $user_id = $order->get_user_id( 'edit' );
    if ( empty( $user_id ) ) {
        pwlpar_log( 'pwlpar_add_earned_order_points: Invalid User ID [$user_id: ' . implode( ', ', $user_id ) . ']' );
        return false;
    }

    if ( ! pwlpar_user_is_rewards_member( $user_id ) ) {
        pwlpar_log( 'pwlpar_add_earned_order_points: User is not a Rewards Member [$user_id: ' . implode( ', ', $user_id ) . ']' );
        return false;
    }

    if ( $note === false ) {
        /* translators: %s is the order number */
        $note = sprintf( __( 'Points earned from Order #%s', 'pw-loyalty-points-and-rewards-for-woocommerce' ), $order->get_order_number() );
    }

    $transaction_id = pwlpar_add_transaction( array(
        'user_id' => $user_id,
        'points' => $points,
        'note' => $note,
        'earned_order_id' => $order->get_id(),
        'status' => 'pending',
    ) );
    if ( !is_numeric( $transaction_id ) ) {
        return $transaction_id;
    }

    if ( !empty( $note ) ) {
        $order->add_order_note( $note );
    }

    return $transaction_id;
}

function pwlpar_update_earned_order_points_status( $order, $status ) {
    $transactions = pwlpar_get_transactions( array(
        'earned_order_id' => $order->get_id(),
    ) );

    foreach ( $transactions as $transaction ) {
        $transaction->set_status( $status );
        $transaction->save();
    }
}
