<?php

defined( 'ABSPATH' ) or exit;

function pwlpar_get_reward_statuses() {
    $statuses = array(
        'pending' => __( 'Pending', 'pw-loyalty-points-and-rewards-for-woocommerce' ),
        'claimed' => __( 'Claimed', 'pw-loyalty-points-and-rewards-for-woocommerce' ),
        'redeemed' => __( 'Redeemed', 'pw-loyalty-points-and-rewards-for-woocommerce' ),
        'trash' => __( 'Deleted', 'pw-loyalty-points-and-rewards-for-woocommerce' ),
    );

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

function pwlpar_get_reward( $id ) {
    $reward = false;

    $id = absint( $id );
    if ( !empty( $id ) ) {
        $rewards = pwlpar_get_rewards( array( 'id' => $id ) );
        if ( count( $rewards ) == 1 ) {
            $reward = $rewards[0];
        }
    }

    return apply_filters( 'pwlpar_get_reward', $reward, $id );
}

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

    $default_args = array(
        'pimwick_rewards_reward_id' => 'any',
        'pimwick_rewards_offer_id' => 'any',
        'user_id' => 'any',
        'status' => 'any',
        'status__in' => array(),
        'status__not_in' => array(),
        'limit' => -1,
    );

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

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

    if ( isset( $args['offer_id'] ) && $args['pimwick_rewards_offer_id'] == 'any' ) {
        $args['pimwick_rewards_offer_id'] = $args['offer_id'];
    }

    $rewards = array();

    $where = '1 = 1';
    $where .= pwlpar_get_sql_where( 'r.pimwick_rewards_reward_id', $args['pimwick_rewards_reward_id'] );
    $where .= pwlpar_get_sql_where( 'r.pimwick_rewards_offer_id', $args['pimwick_rewards_offer_id'] );
    $where .= pwlpar_get_sql_where( 'r.user_id', $args['user_id'] );
    $where .= pwlpar_get_sql_where( 'r.status', $args['status'] );
    $where .= pwlpar_get_sql_where( 'r.status', $args['status__in'] );
    $where .= pwlpar_get_sql_where( 'r.status', $args['status__not_in'], true );

    $limit_sql = '';
    if ( $args['limit'] > 0 ) {
        $limit_sql = 'LIMIT ' . absint( $args['limit'] );
    }

    //
    // $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
                r.*,
                o.title         AS offer_title,
                o.description   AS offer_description,
                o.points        AS offer_points
            FROM
                %i AS r
            JOIN
                %i AS o ON (o.pimwick_rewards_offer_id = r.pimwick_rewards_offer_id)
            WHERE
                $where
            ORDER BY
                r.create_date_gmt DESC
            $limit_sql
        ",
            $pwlpardb->reward,
            $pwlpardb->offer
        ),
        ARRAY_A
    );
    // phpcs:enable

    $offer_logo = pwlpar_offer_logo_url_default();

    foreach ( $results as $row ) {
        $row['offer_image_url'] = $offer_logo;

        $reward = new PWLPAR_Reward( $row );

        $rewards[] = $reward;
    }

    return apply_filters( 'pwlpar_get_rewards', $rewards, $args );
}

function pwlpar_get_reward_by_coupon_code( $coupon_code ) {
    global $wpdb;

    if ( stripos( $coupon_code, pwlpar_coupon_prefix() ) === false ) {
        return false;
    }

    $reward_id = absint( str_replace( pwlpar_coupon_prefix(), '', $coupon_code ) );
    if ( empty( $reward_id ) ) {
        return false;
    }

    $reward = pwlpar_get_reward( $reward_id );

    return apply_filters( 'pwlpar_get_reward_by_coupon_code', $reward, $coupon_code );
}

function pwlpar_apply_reward( $reward ) {
    if ( is_a( $reward, 'PWLPAR_Reward' ) ) {
        return WC()->cart->apply_coupon( $reward->get_coupon_code() );
    } else {
        return false;
    }
}

function pwlpar_remove_reward( $reward ) {
    if ( is_a( $reward, 'PWLPAR_Reward' ) && WC()->cart->has_discount( $reward->get_coupon_code() ) ) {
        return WC()->cart->remove_coupon( $reward->get_coupon_code() );
    } else {
        return false;
    }
}

function pwlpar_is_reward_in_cart( $reward ) {
    if ( !is_a( $reward, 'PWLPAR_Reward' ) || !is_a( WC()->cart, 'WC_Cart' ) ) {
        return false;
    }

    $in_cart = WC()->cart->has_discount( $reward->get_coupon_code() );

    return apply_filters( 'pwlpar_is_reward_in_cart', $in_cart, $reward );
}

function pwlpar_get_order_rewards( $order ) {
    $rewards = array();

    // Get all coupons on the Order
    if ( is_a( $order, 'WC_Order' ) ) {
        $coupons = $order->get_coupon_codes();

        foreach ( $coupons as $coupon_code ) {
            $reward = pwlpar_get_reward_by_coupon_code( $coupon_code );
            if ( $reward ) {
                $rewards[] = $reward;
            }
        }
    }

    return apply_filters( 'pwlpar_get_order_rewards', $rewards, $order );
}

function pwlpar_mark_order_rewards_redeemed( $order ) {
    global $wpdb;

    $rewards = pwlpar_get_order_rewards( $order );

    do_action( 'pwlpar_before_mark_order_rewards_redeemed', $order->get_id(), $rewards );

    foreach ( $rewards as $reward ) {
        if ( $reward->get_status( 'edit' ) != 'redeemed' ) {
            $reward->set_status( 'redeemed' );
            $reward->save();
        }
    }

    do_action( 'pwlpar_after_mark_order_rewards_redeemed', $order->get_id(), $rewards );

    return true;
}

function pwlpar_mark_order_rewards_pending( $order ) {
    global $wpdb;

    $rewards = pwlpar_get_order_rewards( $order );

    do_action( 'pwlpar_before_mark_order_rewards_pending', $order->get_id(), $rewards );

    foreach ( $rewards as $reward ) {
        if ( $reward->get_status( 'edit' ) != 'pending' ) {
            $reward->set_status( 'pending' );
            $reward->save();
        }
    }

    do_action( 'pwlpar_after_mark_order_rewards_pending', $order->get_id(), $rewards );

    return true;
}
