<?php

defined( 'ABSPATH' ) or exit;

function pwlpar_get_transaction_statuses() {
    $statuses = array(
        'active' => __( 'Active', 'pw-loyalty-points-and-rewards-for-woocommerce' ),
        'trash' => __( 'Deleted', 'pw-loyalty-points-and-rewards-for-woocommerce' ),
    );

    return apply_filters( 'pwlpar_get_transaction_statuses', $statuses );
}

function pwlpar_get_transaction( $id ) {
    $transaction = false;

    $id = absint( $id );
    if ( !empty( $id ) ) {
        $transactions = pwlpar_get_transactions( array( 'id' => $id ) );
        if ( count( $transactions ) == 1 ) {
            $transaction = $transactions[0];
        }
    }

    return apply_filters( 'pwlpar_get_transaction', $transaction, $id );
}

function pwlpar_get_transactions( $args = array() ) {
    global $wpdb, $pwlpardb;

    $default_args = array(
        'pimwick_rewards_transaction_id' => 'any',
        'user_id' => 'any',
        'earned_order_id' => 'any',
        'redeemed_reward_id' => 'any',
        'create_user_id' => 'any',
        'update_user_id' => 'any',
        'status' => 'any',
        'status__in' => array(),
        'status__not_in' => array(),
    );

    $args = wp_parse_args( $args, $default_args );

    if ( isset( $args['id'] ) && $args['pimwick_rewards_transaction_id'] == 'any' ) {
        $args['pimwick_rewards_transaction_id'] = $args['id'];
    }

    $transactions = array();

    $where = '1 = 1';
    $where .= pwlpar_get_sql_where( 't.pimwick_rewards_transaction_id', $args['pimwick_rewards_transaction_id'] );
    $where .= pwlpar_get_sql_where( 't.user_id', $args['user_id'] );
    $where .= pwlpar_get_sql_where( 't.earned_order_id', $args['earned_order_id'] );
    $where .= pwlpar_get_sql_where( 't.redeemed_reward_id', $args['redeemed_reward_id'] );
    $where .= pwlpar_get_sql_where( 't.create_user_id', $args['create_user_id'] );
    $where .= pwlpar_get_sql_where( 't.update_user_id', $args['update_user_id'] );
    $where .= pwlpar_get_sql_where( 't.status', $args['status'] );
    $where .= pwlpar_get_sql_where( 't.status', $args['status__in'] );
    $where .= pwlpar_get_sql_where( 't.status', $args['status__not_in'], true );

    //
    // $where value is escaped inside the pwlpar_get_sql_where() function preventing SQL injection.
    //
    // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
    $results = $wpdb->get_results( $wpdb->prepare( "
        SELECT
            t.*
        FROM
            %i AS t
        WHERE
            $where
        ORDER BY
            t.create_date_gmt DESC,
            t.pimwick_rewards_transaction_id DESC
        ",
        $pwlpardb->transaction
    ), ARRAY_A );
    // phpcs:enable

    foreach ( $results as $row ) {
        $transaction = new PWLPAR_Transaction( $row );

        $transactions[] = $transaction;
    }

    return apply_filters( 'pwlpar_get_transactions', $transactions, $args );
}

function pwlpar_add_transaction( $args = array() ) {
    global $wpdb, $pwlpardb;

    $args = wp_parse_args( $args, array(
        'user_id' => false,
        'points' => 0,
        'note' => '',
        'earned_order_id' => null,
        'redeemed_reward_id' => null,
        'create_date_gmt' => current_time( 'mysql', true ),
        'create_user_id' => get_current_user_id(),
        'status' => 'active',
    ) );

    if ( empty( $args['user_id'] ) || !is_numeric( $args['points'] ) ) {
        return __( 'Invalid user id or points.', 'pw-loyalty-points-and-rewards-for-woocommerce' );
    }

    if ( ! pwlpar_user_is_rewards_member( $args['user_id'] ) ) {
        return __( 'User is not a rewards member.', 'pw-loyalty-points-and-rewards-for-woocommerce' );
    }

    $balance = pwlpar_get_member_point_balance( $args['user_id'] );
    $new_balance = $balance + $args['points'];

    // Make sure their balance won't go negative.
    if ( $new_balance < 0 ) {
        $args['points'] = $balance * -1;
    }

    $transaction_id = 0;

    // Using a custom table, not a WordPress table, so this warning can be ignored.
    // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
    $result = $wpdb->insert( $pwlpardb->transaction, $args ); //db call ok

    if ( false !== $result ) {
        $transaction_id = $wpdb->insert_id;
    } else {
        pwlpar_log( 'pwlpar_add_transaction() failed. [$args: ' . implode( ', ', $args ) . '], [$wpdb->last_error: ' . $wpdb->last_error . ']' );
        return $wpdb->last_error;
    }

    do_action( 'pwlpar_transaction_added', $args );

    return $transaction_id;
}
