<?php

defined( 'ABSPATH' ) or exit;

class PWLPAR_Reward {

    /* Properties */
    protected $id;
    protected $pimwick_rewards_offer_id;
    protected $user_id;
    protected $status;
    protected $create_date_gmt;
    protected $create_user_id;
    protected $update_date_gmt;
    protected $update_user_id;

    /* Cache the Offer properties (to prevent multiple sql queries) */
    protected $offer;
    protected $offer_title;
    protected $offer_points;
    protected $offer_description;
    protected $offer_image_url;

    function __construct( $args = array() ) {
        $default_args = apply_filters( 'pwlpar_reward_default_args', array(
            'pimwick_rewards_reward_id'     => 0,
            'pimwick_rewards_offer_id'      => null,
            'user_id'                       => null,
            'status'                        => 'pending',
            'create_date_gmt'               => current_time( 'mysql', true ),
            'create_user_id'                => get_current_user_id(),
            'update_date_gmt'               => null,
            'update_user_id'                => null,

            'offer'                         => false,
            'offer_title'                   => '',
            'offer_points'                  => 0,
            'offer_description'             => '',
            'offer_image_url'               => '',
        ) );

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

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

        $this->id                           = $args['pimwick_rewards_reward_id'];
        $this->pimwick_rewards_offer_id     = $args['pimwick_rewards_offer_id'];
        $this->user_id                      = $args['user_id'];
        $this->status                       = $args['status'];
        $this->create_date_gmt              = $args['create_date_gmt'];
        $this->create_user_id               = $args['create_user_id'];
        $this->update_date_gmt              = $args['update_date_gmt'];
        $this->update_user_id               = $args['update_user_id'];

        $this->offer                        = $args['offer'];
        $this->offer_title                  = $args['offer_title'];
        $this->offer_points                 = $args['offer_points'];
        $this->offer_description            = $args['offer_description'];
        $this->offer_image_url              = $args['offer_image_url'];

    }

    /* Getters */
    public function get_id( $context = 'view' ) {
        return $this->id;
    }

    public function get_pimwick_rewards_offer_id( $context = 'view' ) {
        return $this->pimwick_rewards_offer_id;
    }

    public function get_offer_id( $context = 'view' ) {
        return $this->get_pimwick_rewards_offer_id( $context );
    }

    public function get_user_id( $context = 'view' ) {
        return $this->user_id;
    }

    public function get_status( $context = 'view' ) {
        if ( $context == 'edit' ) {
            return $this->status;
        }

        $statuses = pwlpar_get_reward_statuses();
        if ( isset( $statuses[ $this->status ] ) ) {
            return $statuses[ $this->status ];
        } else {
            return $this->status;
        }
    }

    public function get_create_date( $context = 'view' ) {
        if ( $context == 'edit' ) {
            return $this->create_date_gmt;
        }

        return pwlpar_format_datetime( $this->create_date_gmt );
    }

    public function get_create_user_id( $context = 'view' ) {
        return $this->create_user_id;
    }

    public function get_update_date( $context = 'view' ) {
        if ( $context == 'edit' ) {
            return $this->update_date_gmt;
        }

        return pwlpar_format_datetime( $this->update_date_gmt );
    }

    public function get_update_user_id( $context = 'view' ) {
        return $this->update_user_id;
    }



    /* Setters */
    public function set_id( $id ) {
        $this->id = absint( $id );
    }

    public function set_pimwick_rewards_offer_id( $pimwick_rewards_offer_id ) {
        $this->pimwick_rewards_offer_id = absint( $pimwick_rewards_offer_id );
    }

    public function set_offer_id( $offer_id ) {
        $this->set_pimwick_rewards_offer_id( $offer_id );
    }

    public function set_user_id( $user_id ) {
        $this->user_id = absint( $user_id );
    }

    public function set_status( $status ) {
        $this->status = $status;
    }

    public function set_create_date_gmt( $create_date_gmt ) {
        $this->create_date_gmt = pwlpar_get_gmt_from_date( $create_date_gmt );
    }

    public function set_create_user_id( $create_user_id ) {
        $this->create_user_id = absint( $create_user_id );
    }

    public function set_update_date_gmt( $update_date_gmt ) {
        $this->update_date_gmt = pwlpar_get_gmt_from_date( $update_date_gmt );
    }

    public function set_update_user_id( $update_user_id ) {
        $this->update_user_id = absint( $update_user_id );
    }



    /* Offer methods */
    public function get_offer_title( $context = 'view' ) {
        if ( $context == 'edit' ) {
            return $this->offer_title;
        }

        return pwlpar_format_string( $this->offer_title );
    }

    public function get_offer_description( $context = 'view' ) {
        if ( $context == 'edit' ) {
            return $this->offer_description;
        }

        return pwlpar_format_string( $this->offer_description );
    }

    public function get_offer_points( $context = 'view' ) {
        if ( $context == 'edit' ) {
            return $this->offer_points;
        }

        return pwlpar_format_points( $this->offer_points );
    }

    public function get_offer_image_url( $context = 'view' ) {
        return $this->offer_image_url;
    }



    /* Public methods */
    public function is_redeemable() {
        $redeemable = ( $this->status == 'pending' );
        return apply_filters( 'pwlpar_reward_is_redeemable', $redeemable, $this );
    }

    public function shop_coupon_data() {
        $data = false;

        if ( $this->is_redeemable() ) {
            $offer = pwlpar_get_offer( $this->get_pimwick_rewards_offer_id() );
            if ( is_a( $offer, 'PWLPAR_Offer' ) ) {

                $discount_type = $offer->get_coupon_type( 'edit' );
                $amount = $offer->get_coupon_amount( 'edit' );

                $data = array(
                    'discount_type'                 => $discount_type,
                    'amount'                        => $amount,
                    'individual_use'                => $offer->get_individual_use(),
                    'product_ids'                   => $offer->get_product_ids( 'edit' ),
                    'excluded_product_ids'          => $offer->get_excluded_product_ids( 'edit' ),
                    'usage_limit'                   => '1',
                    'usage_limit_per_user'          => '0', // This is superceded by the 'usage_limit' field. Do not set to anything but zero else Blocks checkout throws an exception.
                    'usage_count'                   => '',
                    'free_shipping'                 => $offer->get_free_shipping( 'edit' ),
                    'product_categories'            => $offer->get_product_categories( 'edit' ),
                    'excluded_product_categories'   => $offer->get_excluded_product_categories( 'edit' ),
                    'exclude_sale_items'            => $offer->get_exclude_sale_items( 'edit' ),
                    'minimum_amount'                => '',
                    'maximum_amount'                => '',
                    'customer_email'                => array( wp_get_current_user()->user_email ),
                );
            }
        }

        return apply_filters( 'pwlpar_reward_shop_coupon_data', $data, $this );
    }

    public function save() {
        global $wpdb, $pwlpardb;

        do_action( 'pwlpar_reward_save', $this );

        $data = array(
            'pimwick_rewards_offer_id' => $this->pimwick_rewards_offer_id,
            'user_id' => $this->user_id,
            'status' => $this->status,
        );

        if ( empty( $this->id ) ) {
            $data['create_date_gmt'] = current_time( 'mysql', true );
            $data['create_user_id'] = get_current_user_id();

            // Using a custom table, not a WordPress table, so this warning can be ignored.
            // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
            $wpdb->insert( $pwlpardb->reward, $data );
            if ( $wpdb->last_error ) {
                return false;
            }
            $this->set_id( $wpdb->insert_id );

        } else {
            $data['update_date_gmt'] = current_time( 'mysql', true );
            $data['update_user_id'] = get_current_user_id();

            // Using a custom table, not a WordPress table, so this warning can be ignored.
            // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
            $wpdb->update( $pwlpardb->reward, $data, array( 'pimwick_rewards_reward_id' => $this->id ) );
            if ( $wpdb->last_error ) {
                return false;
            }
        }

        do_action( 'pwlpar_reward_saved', $this );

        return $this->id;
    }

    public function delete( $permanent = false ) {
        global $wpdb, $pwlpardb;

        do_action( 'pwlpar_reward_delete', $this, $permanent );

        if ( empty( $this->id ) ) {
            return false;
        }

        if ( $permanent ) {
            // Using a custom table, not a WordPress table, so this warning can be ignored.
            // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
            $result = $wpdb->delete( $pwlpardb->reward, array( 'pimwick_rewards_reward_id' => $this->id ) );
        } else {
            $this->set_status( 'trash' );
            $this->save();
            $result = true;
        }

        do_action( 'pwlpar_reward_deleted', $this, $permanent );

        return $result;
    }

    public function get_offer() {
        if ( $this->offer === false ) {
            $this->offer = pwlpar_get_offer( $this->pimwick_rewards_offer_id );
        }

        return $this->offer;
    }

    public function get_coupon_code() {
        $coupon_code = pwlpar_coupon_prefix() . $this->id;

        return apply_filters( 'pwlpar_reward_get_coupon_code', $coupon_code, $this );
    }

    public function get_apply_url() {
        $url = add_query_arg( array(
            'pwlpar_action' => 'apply_reward',
            'reward_id' => $this->id,
        ), pwlpar_get_home_url() );

        return apply_filters( 'pwlpar_reward_get_apply_url', $url, $this );
    }

    public function get_remove_url() {
        $url = add_query_arg( array(
            'pwlpar_action' => 'remove_reward',
            'reward_id' => $this->id,
        ), pwlpar_get_home_url() );

        return apply_filters( 'pwlpar_reward_get_remove_url', $url, $this );
    }
}
