<?php

if (!defined('ABSPATH')) exit;

class WC_CRM_VALIDATION
{
    public static $upload_dir = 'customer_uploads';

    /**
     * WC_CRM_MY_ACCOUNT_VALIDATION constructor.
     */
    public function __construct()
    {
        // my account validation tab setup
        add_action( 'init', array($this, 'validation_endpoint') );
        add_filter( 'query_vars', array($this, 'validation_query_vars'));
        add_filter( 'woocommerce_account_menu_items', array($this, 'validation_tab') );
        add_action( 'woocommerce_account_validation_endpoint', array($this, 'validation_content') );

        // validation upload and update
        add_action( 'wp_ajax_validation_upload', array($this, 'validation_upload') );
        add_action( 'wp_ajax_update_validation_status', array($this, 'update_validation_status') );
        add_action( 'wp_ajax_remove_validation', array($this, 'remove_validation') );

        // meta box setup in validation page
        add_action( 'do_meta_boxes', array($this, 'setup_meta_boxes'), 10, 3 );

        // validation notes securing
        add_filter( 'comments_clauses', array( $this, 'exclude_validation_comments' ) );
        add_filter( 'comment_feed_where', array( $this, 'exclude_validation_comments_from_feed_where' ) );

        // disable validation note email notification
        add_filter('comment_notification_recipients', array($this, 'disable_comment_notification'), 10, 2);
        add_filter('comment_moderation_recipients', array( $this, 'disable_comment_notification' ), 10, 2 );

        // disable duplicate comment error
        add_filter('duplicate_comment_id', array( $this, 'disable_duplicate_comment' ), 15, 2 );

        // validation expiry schedule event
        if (! wp_next_scheduled ( 'wc_crm_validation_expiry' )) {
            wp_schedule_event(time(), 'daily', 'wc_crm_validation_expiry');
        }
        add_action('wc_crm_validation_expiry', array($this, 'validation_expiry_schedule'));

        // add validation description
        add_action('edit_form_after_title', array($this, 'add_validation_description'));

        // add new views to documents page
        add_filter('views_edit-wc_crm_validations', array($this, 'add_views'), 150);

        add_action('woocommerce_edit_account_form', array($this, 'my_account_fields'));

        add_action('woocommerce_save_account_details', array($this, 'save_my_account_fields'), 5);
    }

    /**
     * add my account page validation endpoint
     */
    public static function validation_endpoint()
    {
        add_rewrite_endpoint( 'validation', EP_ROOT | EP_PAGES );
        flush_rewrite_rules();
    }

    /**
     * set up query vars
     *
     * @param $vars array
     * @return array
     */
    public function validation_query_vars($vars)
    {
        $vars[] = 'validation';
        return $vars;
    }

    /**
     * add validation tab before customer logout tab
     *
     * @param $items array
     * @return mixed
     */
    public function validation_tab($items)
    {
        $customer_logout = $items['customer-logout'];
        unset($items['customer-logout']);

        $items['validation'] = 'Documents';
        $items['customer-logout'] = $customer_logout;

        return $items;

    }

    /**
     * validation tab content
     */
    public function validation_content()
    {
        include_once('screen/views/html-frontend-customer-validation.php');
    }

    /**
     * validation post type meta box
     */
    public static function output()
    {
        $validation_data = get_post();
        $id = $validation_data->ID;
        $customer = new WC_CRM_Customer(get_post_meta($id, 'validation_customer', true));
        $attachment = get_post_meta($id, 'validation_file', true)['url'];
        $status = get_post_meta($id, 'validation_status', true);
        $expiry = get_post_meta($id, 'validation_expiry', true);
        $v_id = get_post_meta($id, 'validation_id', true);
        $v_type = get_post_meta($id, 'validation_type', true);
        $types = array(
            'passport' => 'Passport',
            'driver-license' => 'Drivers License',
            'utility-bill' => 'Utility Bill',
            'other' => 'Other'
        );
        ?>
        <div id="validations_data" class="panel">
            <p class="form-field dropdown_customers_field">
                <label for="validation_id"><?php _e('Document ID:', 'wc_crm') ?></label>
                <input type="text" name="validation_id" id="validation_id" value="<?php echo $v_id ?>">
            </p>
            <p class="form-field dropdown_customers_field">
                <label for="validation_type"><?php _e('Document type:', 'wc_crm') ?></label>
                <select name="validation_type" id="validation_type">
                    <?php foreach ($types as $key => $type): ?>
                        <option value="<?php echo $key?>" <?php selected($v_type, $key, true) ?> ><?php _e($type, 'wc_crm'); ?></option>
                    <?php endforeach; ?>
                </select>
            </p>
            <p class="form-field dropdown_customers_field">
                <label for="status"><?php _e('Uploaded By:', 'wc_crm') ?></label>
                <input type="text" name="validation_customer_name" id="validation_customer_name" value="<?php printf('%s %s', $customer->first_name, $customer->last_name) ?>" disabled="disabled">
                <a href="<?php printf("admin.php?page=%s&c_id=%s", WC_CRM_TOKEN, $customer->id) ?>" class="button view_customer" target="_blank">
                    <?php _e('View Customer', 'wc_crm') ?>
                </a>
            </p>
            <p class="form-field">
                <label for="validation_status"><?php _e('Status:', 'wc_crm') ?></label>
                <select name="validation_status" id="validation_status">
                    <option value="1" <?php selected($status, 1) ?> ><?php _e('Awaiting Confirmation', 'wc_crm') ?></option>
                    <option value="2" <?php selected($status, 2) ?> ><?php _e('Confirmed', 'wc_crm') ?></option>
                    <option value="0" <?php selected($status, 0) ?> ><?php _e('Cancelled', 'wc_crm') ?></option>
                </select>
            </p>
            <p class="form-field">
                <label for="status"><?php _e('Expiry Date:', 'wc_crm') ?></label>
                <input type="text" id="validation_expiry" name="validation_expiry" value="<?php echo $expiry; ?>">
            </p>
            <p class="form-field">
                <label for="validation"><?php _e('Files:', 'wc_crm') ?></label>
                <a href="<?php echo $attachment ?>" target="_blank" class="button view_customer"><?php _e('Preview', 'wc_crm') ?></a>
            </p>
        </div>
        <?php
    }

    /**
     * validation notes meta box
     */
    public static function output_validation_notes()
    {
        include_once 'screen/views/html-customer-validation-notes.php';
    }

    /**
     * save validation post type meta box
     *
     * @param $post_id integer
     * @param $post WP_Post
     */
    public static function save_meta_boxes($post_id, $post)
    {
        // $post_id and $post are required
        if (empty($post_id) || empty($post)) return;

        // Dont' save meta boxes for revisions or autosaves
        if (defined('DOING_AUTOSAVE') || is_int(wp_is_post_revision($post)) || is_int(wp_is_post_autosave($post))) return;

        // Check the post being saved == the $post_id to prevent triggering this call for other save_post events
        if (empty($_POST['post_ID']) || $_POST['post_ID'] != $post_id) return;

        // Check user has permission to edit
        if (!current_user_can('edit_post', $post_id)) return;

        // Check post type
        if ($post->post_type != 'wc_crm_validations') return;

        if( isset($_POST['validation_id']) && !empty($_POST['validation_id']) ){
            update_post_meta( $post_id, 'validation_id', $_POST['validation_id'] );
        }

        if( isset($_POST['validation_id']) && !empty($_POST['validation_id']) ){
            update_post_meta( $post_id, 'validation_type', $_POST['validation_type'] );
        }

        if( isset($_POST['validation_type']) && !empty($_POST['validation_type']) ){
            update_post_meta( $post_id, 'validation_type', $_POST['validation_type'] );
        }

        if( isset($_POST['validation_expiry']) && !empty($_POST['validation_expiry']) ){
            $expiry = $_POST['validation_expiry'];
            $date = DateTime::createFromFormat('Y-m-d', $expiry);
            $date_errors = DateTime::getLastErrors();

            if( $date && $date_errors['error_count'] == 0 && $date->format('Y-m-d') == $expiry ){
                update_post_meta( $post_id, 'validation_expiry', $expiry );
            }
        }

        $old_status = get_post_meta($post_id, 'validation_status', true);
        update_post_meta($post_id, 'validation_status', $_POST['validation_status']);
        $new_status = get_post_meta($post_id, 'validation_status', true);

        self::add_validation_note($post_id, $old_status, $new_status);
    }

    /**
     * validation upload
     */
    public function validation_upload()
    {
        add_filter('upload_dir', array($this, 'filter_upload_dir'));

        $path = wp_upload_dir()['basedir'];

        if(!wp_mkdir_p($path)){
            wp_mkdir_p($path);
        }

        if(count($_FILES["file"]) < 1) wp_send_json_error('no file selected');

        $data = $_POST;

        if( $_FILES["file"]["error"] == UPLOAD_ERR_OK ){

            $attachment = $this->upload_file($_FILES["file"]['name'], $_FILES["file"]['tmp_name']);
            $this->insert_post($attachment, $data);

            wp_send_json_success("Success");
        }

        wp_send_json_error($_FILES["file"]["error"]);
    }

    /**
     * filter default wordpress upload directory
     *
     * @param $key array
     * @return mixed
     */
    public function filter_upload_dir($key)
    {
        $directory = '/'.self::$upload_dir;

        $key['basedir'] = $key['basedir'] . $directory;
        $key['baseurl'] = $key['baseurl'] . $directory;
        $key['path'] = $key['basedir'];
        $key['url'] = $key['baseurl'];

        return $key;
    }

    /**
     * upload file helper
     *
     * @param $filename string
     * @param $temp string
     * @return array
     */
    public function upload_file($filename, $temp)
    {
        $upload_file = wp_upload_bits($filename, null, file_get_contents($temp));

        return $upload_file;
    }

    /**
     * insert a validation post type
     *
     * @param $file
     * @param array $data
     */
    public function insert_post($file, $data = array())
    {
        $user = wp_get_current_user();

        if($user->ID == 0) return;

        $customer = wc_crm_get_customer($user->ID, 'user_id');

        $post_id = wp_insert_post(array(
            'post_title' => $user->get('display_name') ?: $user->get('user_nicename'),
            'post_type' => 'wc_crm_validations',
            'post_status' => 'publish',
            'meta_input' => array(
                'validation_customer' => $customer->c_id,
                'validation_status' => '1',
                'validation_file' => $file,
                'validation_type' => $data['validation_type']
            )
        ));

        $validation_data = array(
            'customer' => $customer,
            'post_url' => admin_url('post.php/?post='.$post_id.'&action=edit')
        );

        $mailer = WC()->mailer();
        do_action('wc_crm_send_validation_upload_notification', $validation_data);
    }

    /**
     * update validation status ajax
     */
    public function update_validation_status()
    {
        parse_str($_POST['data'], $params);
        $post_id = isset($params['post_id']) ? $params['post_id'] : 0;

        if( $post_id == 0 || !get_post_status($post_id)){
            wp_send_json_error([
                'success' => false,
                'message' => 'invalid validation record'
            ]);
        }

        $old_status = get_post_meta($post_id, 'validation_status', true);
        update_post_meta($post_id, 'validation_status', $params['validation_status']);
        $status = get_post_meta($post_id, 'validation_status', true);

        $this->add_validation_note($post_id, $old_status, $status);

        wp_send_json_success([
            'status' => $status,
        ]);
    }

    /**
     * remove validation ajax
     */
    public function remove_validation()
    {
        $post_id = $_POST['post_id'];

        if(!$post_id || empty($post_id) || !get_post_status($post_id))
            wp_send_json_error("invalid post id");

        if(!wp_delete_post($post_id, true))
            wp_send_json_error("An error occured");

        wp_send_json_success("successfully deleted");
    }

    /**
     * get validation status by int
     *
     * @param int $status
     * @return string
     */
    public static function get_validation_status($status = 0)
    {
        switch ($status){
            case 1:
                return "Awaiting Confirmation";
            case 2:
                return "Confirmed";
            case 0:
            default:
                return "Cancelled";
        }
    }

    /**
     * add a validation note
     *
     * @param $post_id integer
     * @param $old_status string
     * @param $new_status string
     */
    public static function add_validation_note($post_id, $old_status, $new_status)
    {
        if(!$post_id || !absint($post_id) || empty($old_status)) return;

        if(strcasecmp($old_status, $new_status) == 0) return;

        $content = sprintf(__('Validation status changed to %s from %s', 'wc_crm'), __(self::get_validation_status($new_status), 'wc_crm'), __(self::get_validation_status($old_status), 'wc_crm'));
        $comment_id = wp_new_comment(array(
            'comment_post_ID' => $post_id,
            'comment_author' => 'wc_crm',
            'comment_content' => $content,
            'comment_type' => 'validation_note',
            'comment_parent' => 0,
            'user_id' => get_current_user_id()
        ));
    }

    /**
     * get validation notes
     *
     * @param $customer WC_CRM_Customer
     * @return array
     */
    public static function get_validation_notes($customer)
    {
        if(!$customer) return array();

        if($customer instanceof WC_CRM_Customer){
            $customer_id = $customer->id;
        }else{
            $customer_id = $customer;
        }

        global $wpdb;

        $query = "SELECT comments.* from {$wpdb->comments} comments 
                  LEFT JOIN {$wpdb->posts} posts on comments.comment_post_ID = posts.ID 
                  LEFT JOIN {$wpdb->postmeta} postmeta on posts.ID = postmeta.post_id
                  WHERE comments.comment_type = 'validation_note' and postmeta.meta_key = 'validation_customer' and postmeta.meta_value = {$customer_id}
                  ORDER BY comments.comment_ID DESC";

        $validation_notes = $wpdb->get_results($query);

        return (array)$validation_notes;

    }

    /**
     * setup meta boxes in validation post screen
     *
     * @param $post_type
     * @param $context
     * @param $post
     */
    public function setup_meta_boxes($post_type, $context, $post)
    {
        remove_meta_box('commentsdiv', 'wc_crm_validations', 'normal');
        remove_meta_box('slugdiv', 'wc_crm_validations', 'normal');
        remove_meta_box( 'submitdiv', 'wc_crm_validations', 'side' );
        add_meta_box( 'submitdiv', __('Document Actions','wc_crm'), array($this, 'validation_post_submit_meta_box'), 'wc_crm_validations', 'side', 'high' );
    }

    /**
     * get validations helper
     *
     * @param string $key
     * @param string $value
     * @param string $compare
     * @param bool $is_count
     * @return array|int
     */
    public static function get_validations($key='status', $value='1', $compare="=", $is_count = true)
    {
        $key = 'validation_' . $key;
        $validations = get_posts(array(
            'post_type' => 'wc_crm_validations',
            'posts_per_page' => -1,
            'meta_query' => array(
                array(
                    'key' => $key,
                    'value' => $value,
                    'compare' => $compare
                )
            )
        ));

        if($is_count)
            return count($validations);

        return $validations;
    }

    /**
     * get validation types
     *
     * @return array
     */
    public static function get_validation_types()
    {
        return  array(
            '.jpg' => __('JPG', 'wc_crm'),
            '.png' => __('PNG', 'wc_crm'),
            '.pdf' => __('PDF', 'wc_crm'),
            '.doc' => __('DOC', 'wc_crm'),
            '.xls' => __('XLS', 'wc_crm'),
            '.ppt' => __('PPT', 'wc_crm'),
            '.docx' => __('DOCX', 'wc_crm'),
            '.xlsx' => __('XLSX', 'wc_crm'),
            '.pptx' => __('PPTX', 'wc_crm'),
            '.ai' => __('AI', 'wc_crm'),
            '.eps' => __('EPS', 'wc_crm')
        );
    }

    /**
     * secure validation_note comment types from get_comments query
     *
     * @param $clauses
     * @return mixed
     */
    public function exclude_validation_comments($clauses )
    {
        $clauses['where'] .= ( $clauses['where'] ? ' AND ' : '' ) . " comment_type != 'validation_note' ";

        return $clauses;
    }

    /**
     * secure validation_note comment types from get_comments query
     *
     * @param $where
     * @return string
     */
    public function exclude_order_comments_from_feed_where($where )
    {
        return $where . ( $where ? ' AND ' : '' ) . " comment_type != 'validation_note' ";
    }

    /**
     * disable comment notification when validation note added
     *
     * @param $emails array
     * @param $comment_id integer
     * @return array
     */
    public function disable_comment_notification($emails, $comment_id )
    {
        $comment = get_comment( $comment_id );

        if ( $comment && 'validation_note' === $comment->comment_type ) {
            $emails = array();
        }

        return $emails;
    }

    /**
     * modify validation screen publish meta box.
     * NOTE: pure code from wordpress meta-boxes.php
     *
     * @param $post WP_Post
     */
    public function validation_post_submit_meta_box($post ) {
        global $action;

        $meta = $post->tm_meta;
        $post_type = $post->post_type;
        $post_type_object = get_post_type_object($post_type);
        $can_publish = current_user_can($post_type_object->cap->publish_posts);
        ?>
        <div class="submitbox" id="submitpost">
            <div id="minor-publishing">
                <div style="display:none;">
                    <?php submit_button( __( 'Save', 'wc_crm' ), 'button', 'save' ); ?>
                </div>
                <div class="clear"></div>
            </div>
            <div id="misc-publishing-actions">
                <div class="misc-pub-section misc-pub-post-status">
                    <?php _e( 'Status:' ) ?>
                    <span id="post-status-display"><?php
                        $status = get_post_meta($post->ID, 'validation_status', true);
                        _e(self::get_validation_status($status));
                        ?>
                    </span>
                </div>
            </div>
            <?php
            $datef = __( 'M j, Y @ H:i' );
            if ( 0 != $post->ID ) {
                if ( 'future' == $post->post_status ) { // scheduled for publishing at a future date
                    /* translators: Post date information. 1: Date on which the post is currently scheduled to be published */
                    $stamp = __('Scheduled for: <b>%1$s</b>');
                } elseif ( 'publish' == $post->post_status || 'private' == $post->post_status ) { // already published
                    /* translators: Post date information. 1: Date on which the post was published */
                    $stamp = __('Submitted on: <b>%1$s</b>');
                } elseif ( '0000-00-00 00:00:00' == $post->post_date_gmt ) { // draft, 1 or more saves, no date specified
                    $stamp = __('Publish <b>immediately</b>');
                } elseif ( time() < strtotime( $post->post_date_gmt . ' +0000' ) ) { // draft, 1 or more saves, future date specified
                    /* translators: Post date information. 1: Date on which the post is to be published */
                    $stamp = __('Schedule for: <b>%1$s</b>');
                } else { // draft, 1 or more saves, date specified
                    /* translators: Post date information. 1: Date on which the post is to be published */
                    $stamp = __('Publish on: <b>%1$s</b>');
                }
                $date = date_i18n( $datef, strtotime( $post->post_date ) );
            } else { // draft (no saves, and thus no date specified)
                $stamp = __('Publish <b>immediately</b>');
                $date = date_i18n( $datef, strtotime( current_time('mysql') ) );
            }
            if ( $can_publish ) : // Contributors don't get to choose the date of publish ?>
            <div class="misc-pub-section curtime misc-pub-curtime">
                <span id="timestamp">
                <?php printf($stamp, $date); ?>
                </span>
                <a href="#edit_timestamp" class="edit-timestamp hide-if-no-js" role="button">
                    <span aria-hidden="true"><?php _e( 'Edit' ); ?></span>
                    <span class="screen-reader-text"><?php _e( 'Edit date and time' ); ?></span>
                </a>
                <fieldset id="timestampdiv" class="hide-if-js">
                    <legend class="screen-reader-text"><?php _e( 'Date and time' ); ?></legend>
                    <?php touch_time( ( $action === 'edit' ), 1 ); ?>
                </fieldset>
            </div><?php // /misc-pub-section ?>
            <?php endif; ?>
            <div id="major-publishing-actions">
                <div id="delete-action">
                    <?php
                    if ( current_user_can( "delete_post", $post->ID ) ) {
                        if ( !EMPTY_TRASH_DAYS ) {
                            $delete_text = __( 'Delete Permanently', 'wc_crm' );
                        } else {
                            $delete_text = __( 'Move to Trash', 'wc_crm' );
                        }
                        ?>
                        <a class="submitdelete deletion"
                           href="<?php echo get_delete_post_link( $post->ID ); ?>"><?php echo $delete_text; ?></a><?php
                    } ?>
                </div>
                <div id="publishing-action">
                    <span class="spinner"></span>
                    <?php
                    if ( !in_array( $post->post_status, array( 'publish', 'future', 'private' ) ) || 0 == $post->ID ) {
                        if ( $meta['can_publish'] ) : ?>
                            <input name="original_publish" type="hidden" id="original_publish"
                                   value="<?php esc_attr_e( 'Publish' ) ?>"/>
                            <?php submit_button( __( 'Publish', 'woocommerce-tm-extra-product-options' ), 'primary button-large', 'publish', FALSE, array( 'accesskey' => 'p' ) ); ?>
                        <?php
                        else : ?>
                            <input name="original_publish" type="hidden" id="original_publish"
                                   value="<?php esc_attr_e( 'Submit for Review' ) ?>"/>
                            <?php submit_button( __( 'Submit for Review', 'woocommerce-tm-extra-product-options' ), 'primary button-large', 'publish', FALSE, array( 'accesskey' => 'p' ) ); ?>
                        <?php
                        endif;
                    } else { ?>
                        <input name="original_publish" type="hidden" id="original_publish"
                               value="<?php esc_attr_e( 'Update' ) ?>"/>
                        <input name="save" type="submit" class="button button-primary button-large" id="publish"
                               accesskey="p" value="<?php esc_attr_e( 'Update' ) ?>"/>
                        <?php
                    } ?>
                </div>
                <div class="clear"></div>
            </div>
        </div>
        <?php
    }

    /**
     * disable duplicate comment error throwing
     *
     * @param $dupe_id integer
     * @param $comment_data array
     * @return array
     */
    public function disable_duplicate_comment($dupe_id, $comment_data)
    {
        if ( $comment_data && $comment_data['comment_type'] === 'validation_note' ) {
            $comment_data = array();
        }

        return $comment_data;
    }

    /**
     *  validation status update on expiry date
     *
     */
    public function validation_expiry_schedule()
    {
        $validations = WC_CRM_VALIDATION::get_validations();

        if (empty($validations)) {
            return;
        }
        foreach ( $validations as $validation ){

            $expiry_date = get_post_meta($validation->ID, 'validation_expiry', true);

            if( !$expiry_date || empty($expiry_date) ) continue;

            if( date('Y-m-d', strtotime($expiry_date)) === date('Y-m-d', strtotime('today')) ){
                update_post_meta( $validation->ID, 'validation_status', "0" );

                do_action('wc_crm_send_validation_expiry_notification', $validation->ID);
            }

        }
    }

    /**
     * description field for validation post type
     *
     * @param WP_Post $post
     */
    public function add_validation_description($post)
    {
        if( $post->post_type == 'wc_crm_validations') : ?>
        <textarea id="excerpt" name="excerpt" cols="5" rows="2" placeholder="<?php esc_attr_e( 'Description (optional)', 'wc_crm' ); ?>"><?php echo $post->post_excerpt ?></textarea>
        <?php endif;
    }

    /**
     * set confirmed view to validation posts list
     *
     * @param $views
     * @return mixed
     */
    public function add_views($views)
    {
        global $wpdb;
        $data = $wpdb->get_results("select 
                            SUM(post_meta.meta_value = '1') AS 'awaiting_confirmation', SUM(post_meta.meta_value = '2') AS 'confirmed', SUM(post_meta.meta_value = '0') AS 'cancelled'
                            from wp_posts posts
                            LEFT JOIN wp_postmeta post_meta on posts.ID = post_meta.post_id and post_meta.meta_key = 'validation_status'
                            WHERE posts.post_type = 'wc_crm_validations'", ARRAY_A);

        unset($views['mine']);
        unset($views['publish']);

        $new_views = array( 0 => 'cancelled', 1 => 'awaiting_confirmation', 2 => 'confirmed' );
        foreach ($new_views as $key => $view){
            if( $data[0][$view] != 0 ){
                $current = isset($_GET['validation_status']) && $_GET['validation_status'] == $key ? "current" : "";
                array_splice( $views, 1, 0, array(
                    $view => '<a href="edit.php?post_type=wc_crm_validations&#038;validation_status='.$key.'"
                                 class="' . $current . '" 
                                 aria-current="page">' . __(ucwords(str_replace('_', ' ', $view)), "wc_crm") . ' <span class="count">(' . $data[0][$view] . ')</span></a>'
                ));
            }
        }

        return $views;
    }

    /**
     * add customer fields in my account edit details
     */
    public function my_account_fields()
    {
        global $the_customer;

        if( !$the_customer ) {
            $customer = wc_crm_get_customer(get_current_user_id(), 'user_id')->c_id;

            if( !$customer ) return;

            $the_customer = new WC_CRM_Customer($customer);
            $the_customer->init_general_fields();
        }

        include_once(WC()->plugin_path() . '/includes/admin/wc-meta-box-functions.php');

        $exclude = get_option('wc_crm_my_account_fields');
        $counter = 0;
        foreach ( $the_customer->general_fields as $key => $field ){

            if( !in_array($key, $exclude) ) continue;

            $counter++;

            $field['id'] = $key;
            if (!isset($field['type']))
                $field['type'] = 'text';

            if ($key == 'customer_status' && empty($field['value'])) {
                $default_status = get_option('wc_crm_default_status_crm');
                $field['value'] = !empty($default_status) ? $default_status : 'Customer';
            }

            $is_last = $counter % 2 == 0;

            if( $is_last ){
                $field['wrapper_class'] = 'woocommerce-form-row woocommerce-form-row--last form-row form-row-last';
            }else{
                $field['wrapper_class'] = 'woocommerce-form-row woocommerce-form-row--first form-row form-row-first';
            }

            switch ($field['type']){
                case 'select':
                    woocommerce_wp_select($field);
                    break;
                case 'text':
                default:
                    $field['class'] = isset($field['class']) ? $field['class'] . 'woocommerce-Input woocommerce-Input--text input-text' : 'woocommerce-Input woocommerce-Input--text input-text';
                    woocommerce_wp_text_input($field);
                    break;
            }

            if( $is_last )
                echo '<div class="clear"></div>';
        }

        echo '<div class="clear"></div>';
    }

    /**
     * save customer details in my account edit details
     *
     * @param $user_id
     */
    public function save_my_account_fields($user_id)
    {
        $allowed_fields = get_option('wc_crm_my_account_fields');
        if( !$allowed_fields ) return;

        $the_customer = new WC_CRM_Customer(wc_crm_get_customer(get_current_user_id(), 'user_id'));
        if( !$the_customer ) return;

        $the_customer->init_general_fields();
        foreach ( $the_customer->general_fields as $key => $field ){

            if( !in_array($key, $allowed_fields) ) continue;

            update_user_meta($user_id, $field['meta_key'], $_POST[$key]);

        }
    }

}
return new WC_CRM_VALIDATION();
