<?php
if ( !defined( 'ABSPATH' ) ) {
    exit;
}

$changed_objects = array();

if ( !function_exists( 'datebook_get_prop' ) ) {

    function datebook_get_prop( $object, $key, $single = true, $context = 'view' ) {

        $prop_map   = datebook_return_new_attribute_map();
        $is_wc_data = $object instanceof WC_Data;

        if ( $is_wc_data ) {
            $key = ( array_key_exists( $key, $prop_map ) ) ? $prop_map[ $key ] : $key;

            if ( ( $getter = "get{$key}" ) && method_exists( $object, $getter ) ) {
                return $object->$getter( $context );
            } elseif ( ( $getter = "get_{$key}" ) && method_exists( $object, $getter ) ) {
                return $object->$getter( $context );
            } else {
                return $object->get_meta( $key, $single );
            }
        } else {
            $key = ( in_array( $key, $prop_map ) ) ? array_search( $key, $prop_map ) : $key;

            if ( isset( $object->$key ) ) {
                return $object->$key;
            } elseif ( datebook_wc_check_post_columns( $key ) ) {
                return $object->post->$key;
            } else {
                $getter = 'get_user_meta';
                !$object instanceof WC_Customer && $getter = 'get_post_meta';

                $object_id = is_callable( array( $object, 'get_id' ) ) ? $object->get_id() : (isset($object->id) ? $object->id : '');

                return $getter( $object_id, $key, true );
            }
        }
    }
}

if ( !function_exists( 'datebook_set_prop' ) ) {

    function datebook_set_prop( $object, $arg1, $arg2 = false ) {

        if ( !is_array( $arg1 ) ) {
            $arg1 = array(
                $arg1 => $arg2
            );
        }

        $prop_map   = datebook_return_new_attribute_map();
        $is_wc_data = $object instanceof WC_Data;

        foreach ( $arg1 as $key => $value ) {
            if ( $is_wc_data ) {
                $key = ( array_key_exists( $key, $prop_map ) ) ? $prop_map[ $key ] : $key;

                if ( ( $setter = "set{$key}" ) && method_exists( $object, $setter ) ) {
                    $object->$setter( $value );
                } elseif ( ( $setter = "set_{$key}" ) && method_exists( $object, $setter ) ) {
                    $object->$setter( $value );
                } else {
                    $object->update_meta_data( $key, $value );
                }
            } else {
                $key = ( in_array( $key, $prop_map ) ) ? array_search( $key, $prop_map ) : $key;
                ( strpos( $key, '_' ) === 0 ) && $key = substr( $key, 1 );

                if ( datebook_wc_check_post_columns( $key ) ) {
                    $object->post->$key = $value;
                } else {
                    $object->$key = $value;
                }
            }
        }
    }
}

if ( !function_exists( 'datebook_save_prop' ) ) {

    function datebook_save_prop( $object, $arg1, $arg2 = false, $force_update = false ) {
        if ( !is_array( $arg1 ) ) {
            $arg1 = array(
                $arg1 => $arg2
            );
        }

        $is_wc_data = $object instanceof WC_Data;

        foreach ( $arg1 as $key => $value ) {
            datebook_set_prop( $object, $key, $value );

            if ( !$is_wc_data ) {

                if ( datebook_wc_check_post_columns( $key ) ) {
                    datebook_store_changes( $object->post, $key, $value );
                } else {
                    $object_id = is_callable( array( $object, 'get_id' ) ) ? $object->get_id() : $object->id;

                    update_post_meta( $object_id, $key, $value );
                }
            }
        }

        if ( $is_wc_data ) {
            $object->save();
        }
    }
}

if ( !function_exists( 'datebook_return_new_attribute_map' ) ) {
    function datebook_return_new_attribute_map() {
        return array(
            'post_parent'                => 'parent_id',
            'post_title'                 => 'name',
            'post_status'                => 'status',
            'post_content'               => 'description',
            'post_excerpt'               => 'short_description',
            /* Orders */
            'paid_date'                  => 'date_paid',
            '_paid_date'                 => '_date_paid',
            'completed_date'             => 'date_completed',
            '_completed_date'            => '_date_completed',
            '_order_date'                => '_date_created',
            'order_date'                 => 'date_created',
            'order_total'                => 'total',
            'customer_user'              => 'customer_id',
            '_customer_user'             => 'customer_id',
            /* Products */
            'visibility'                 => 'catalog_visibility',
            '_visibility'                => '_catalog_visibility',
            'sale_price_dates_from'      => 'date_on_sale_from',
            '_sale_price_dates_from'     => '_date_on_sale_from',
            'sale_price_dates_to'        => 'date_on_sale_to',
            '_sale_price_dates_to'       => '_date_on_sale_to',
            'product_attributes'         => 'attributes',
            '_product_attributes'        => '_attributes',
            /*Coupons*/
            'coupon_amount'              => 'amount',
            'exclude_product_ids'        => 'excluded_product_ids',
            'exclude_product_categories' => 'excluded_product_categories',
            'customer_email'             => 'email_restrictions',
            'expiry_date'                => 'date_expires',
        );
    }
}

if ( !function_exists( 'datebook_store_changes' ) ) {
    function datebook_store_changes( $object, $key, $value = false ) {
        global $changed_objects;

        $is_wc_data = $object instanceof WC_Data;

        if ( $is_wc_data ) {

            $object_reference = $object->get_id();

            $changed_objects[ $object_reference ][ 'object' ]          = $object;
            $changed_objects[ $object_reference ][ 'changes' ][ $key ] = $value;



        } else {
            $changed_objects[ $object->ID ][ $key ] = $value;
        }
    }
}

if ( !function_exists( 'datebook_send_changes_to_db' ) ) {
    function datebook_send_changes_to_db() {
        global $changed_objects;

        if ( !empty( $changed_objects ) ) {
            foreach ( $changed_objects as $id => $data ) {

				$object = is_a( $data[ 'object' ], 'WC_Product' ) ? wc_get_product( $id ) : wc_get_order( $id );

				datebook_set_prop( $object, $data[ 'changes' ] );
				$object->save();

            }
        }
    }
}

if ( !function_exists( 'datebook_wc_check_post_columns' ) ) {
    function datebook_wc_check_post_columns( $key ) {
        $columns = array(
            'post_author',
            'post_date',
            'post_date_gmt',
            'post_content',
            'post_title',
            'post_excerpt',
            'post_status',
            'comment_status',
            'ping_status',
            'post_password',
            'post_name',
            'to_ping',
            'pinged',
            'post_modified',
            'post_modified_gmt',
            'post_content_filtered',
            'post_parent',
            'guid',
            'menu_order',
            'post_type',
            'post_mime_type',
            'comment_count',
        );

        return in_array( $key, $columns );
    }
}


/*  Shortcuts for common functions   */

if ( !function_exists( 'datebook_get_order_id' ) ) {
    /**
     * Retrieve the order id
     *
     */
    function datebook_get_order_id( $order ) {
        return datebook_get_prop( $order, 'id' );
    }
}


add_action( 'shutdown', 'datebook_send_changes_to_db' );