<?php
/**
 * ProfilesPage class
 * 
 */

class ProfilesPage extends WPL_Page {

	const slug = 'profiles';

    protected $profilesTable;

	public function onWpInit() {
		// parent::onWpInit();

		// Add custom screen options
		$load_action = "load-".$this->main_admin_menu_slug."_page_wplister-".self::slug;
		add_action( $load_action, array( &$this, 'addScreenOptions' ) );

		wp_enqueue_script( 'selectWoo' );
		wp_enqueue_style( 'select2' );

	}

	public function onWpAdminMenu() {
		parent::onWpAdminMenu();

		add_submenu_page( self::ParentMenuId, $this->getSubmenuPageTitle( 'Profiles' ), __( 'Profiles', 'wp-lister-for-ebay' ),
						  'manage_ebay_listings', $this->getSubmenuId( 'profiles' ), array( &$this, 'onDisplayProfilesPage' ) );
	}

	public function handleSubmit() {
		if ( ! current_user_can('manage_ebay_listings') ) return;

        // handle duplicate profile
		if ( $this->requestAction() == 'duplicate_auction_profile' ) {
		    check_admin_referer( 'duplicate_auction_profile' );
			$this->duplicateProfile();
		}
		// handle download profile
		if ( isset( $_REQUEST['profile'] ) && ( $this->requestAction() == 'download_listing_profile' ) ) {
            check_admin_referer( 'download_listing_profile' );
			$this->downloadProfile( wple_clean($_REQUEST['profile']) );
		}
		// handle upload profile
		if ( $this->requestAction() == 'wple_upload_listing_profile' ) {
            check_admin_referer( 'wple_upload_listing_profile' );
			$this->uploadProfile();
		}
		// handle delete action
		if ( isset( $_REQUEST['profile'] ) && ( $this->requestAction() == 'wplister_delete_profile' ) ) {
		    if ( is_array( $_REQUEST['profile'] ) ) {
		        check_admin_referer( 'bulk-profiles' );
            } else {
                check_admin_referer( 'wplister_delete_profile' );
            }

			$this->initEC();
			$this->EC->deleteProfiles( wple_clean($_REQUEST['profile']) );
			$this->EC->closeEbay();
		}
	}
	
	function addScreenOptions() {
		$option = 'per_page';
		$args = array(
	    	'label' => 'Profiles',
	        'default' => 20,
	        'option' => 'profiles_per_page'
	        );
		add_screen_option( $option, $args );

		// this needs to be instantiated early, or the profiles page will not load:
		// (doing this in onDisplayProfilesPage() is too late!)
		$this->profilesTable = new ProfilesTable();

		// load styles and scripts for this page only
		add_action( 'admin_print_styles', array( &$this, 'onWpPrintStyles' ) );
		add_action( 'admin_enqueue_scripts', array( &$this, 'onWpEnqueueScripts' ) );		

	}
	
	// handle save profile action
	// this needs to be called after WooCommerce initialized its taxonomies, but before the first byte is sent
	public function onWpAdminInit() {
		if ( ! current_user_can('manage_ebay_listings') ) return;

		// handle save profile
		if ( $this->requestAction() == 'save_listing_profile' ) {
		    check_admin_referer( 'wplister_save_profile' );

			$this->saveProfile();

			if ( @$_POST['return_to'] == 'listings' ) {
				$return_url = get_admin_url().'admin.php?page=wplister';
		        if ( isset($_REQUEST['listing_status']) )	$return_url = add_query_arg( 'listing_status', wple_clean($_REQUEST['listing_status']), $return_url );
		        if ( isset($_REQUEST['s']) )				$return_url = add_query_arg( 's', wple_clean($_REQUEST['s']), $return_url );
				wp_redirect( $return_url );
			}
		}

	}


	public function onDisplayProfilesPage() {
		$this->check_wplister_setup();
	
		// edit profile
		if ( ( $this->requestAction() == 'edit' ) || ( $this->requestAction() == 'add_new_profile' ) ) {
			return $this->displayEditPage();			
		} 

    	// Fetch, prepare, sort, and filter our table data...
	    $profilesTable = $this->profilesTable;
	    $profilesTable->prepare_items();

		// process errors 		
		// if ($this->IC->message) $this->showMessage( $this->IC->message,1 );
		
		$aData = array(
			'plugin_url'				=> self::$PLUGIN_URL,
			'message'					=> $this->message,

			'profilesTable'				=> $profilesTable,
		
			'form_action'				=> 'admin.php?page='.self::ParentMenuId.'-profiles'
		);
		$this->display( 'profiles_page', $aData );
		
	}

	public function displayEditPage() {
        // init model
		$profilesModel = new ProfilesModel();

		// get item
		if ( $this->requestAction() == 'add_new_profile' ) {
			$item = $profilesModel->newItem();
		} else {
			$item = $profilesModel->getItem( wple_clean($_REQUEST['profile']) );
		}

		// set account id
		$account_id = $item['account_id'];
		$site_id    = $item['site_id'] ?? false;
		if ( ! $account_id ) $account_id = get_option( 'wplister_default_account_id' );

		if ( !$site_id && isset( WPLE()->accounts[ $account_id ] ) ) {
		    $site_id = WPLE()->accounts[ $account_id ]->site_id;
        }
        $wpl_site = new WPLE_eBaySite( $site_id );
	
		// check site data - prompt to refresh if countries are missing
		$countries = EbayShippingModel::getEbayCountries( $site_id );
		if ( empty( $countries ) ) {
			// show warning
			$msg1 = __( 'You need to refresh site specific eBay details before you can save a listing profile.', 'wp-lister-for-ebay' );
			$msg2 = __( 'Please visit your %s and click on "Refresh Details".', 'wp-lister-for-ebay' );
			$accounts_page = get_option( 'wplister_enable_accounts_page' ) ? 'wplister-settings-accounts' : 'wplister-settings&tab=accounts';
			$link = sprintf( '<a href="admin.php?page=%s">%s</a>', $accounts_page, __( 'Account Settings', 'wp-lister-for-ebay' ) );
			$msg2 = sprintf($msg2, $link);
			$msg = "<b>$msg1</b></p><p>$msg2";
			wple_show_message($msg,'error');
		}

		// get ebay data
		$payment_options           = EbayPaymentModel::getAll( $site_id );
		$loc_flat_shipping_options = EbayShippingModel::getAllLocal( $site_id, 'flat' );
		$int_flat_shipping_options = EbayShippingModel::getAllInternational( $site_id, 'flat' );
		$shipping_locations        = EbayShippingModel::getShippingLocations( $site_id );
		$exclude_locations         = EbayShippingModel::getExcludeShippingLocations( $site_id );
		$countries                 = EbayShippingModel::getEbayCountries( $site_id );
		$template_files            = $this->getTemplatesList();
		$store_categories          = $this->getStoreCategories( $account_id );

		$loc_calc_shipping_options = EbayShippingModel::getAllLocal( $site_id, 'calculated' );
		$int_calc_shipping_options = EbayShippingModel::getAllInternational( $site_id, 'calculated' );
		$available_attributes      = ProductWrapper::getAttributeTaxonomies();

		// process custom attributes
		$wpl_custom_attributes = wple_get_custom_attributes();


		$available_dispatch_times        = WPLE_eBaySite::getSiteObj( $site_id )->getDispatchTimeMaxDetails();
		$available_shipping_packages     = WPLE_eBaySite::getSiteObj( $site_id )->getShippingPackageDetails();
		$ReturnsWithinOptions            = WPLE_eBaySite::getSiteObj( $site_id )->getReturnsWithinOptions();
		$ShippingCostPaidByOptions       = WPLE_eBaySite::getSiteObj( $site_id )->getShippingCostPaidByOptions();

		if ( empty( $available_shipping_packages ) ) {
		    $available_shipping_packages = WPLE_eBaySite::getDefaultShippingPackages();
        }
		

		$prepared_listings  = WPLE_ListingQueryHelper::countItemsUsingProfile( $item['profile_id'], 'prepared' );
		$verified_listings  = WPLE_ListingQueryHelper::countItemsUsingProfile( $item['profile_id'], 'verified' );
		$published_listings = WPLE_ListingQueryHelper::countItemsUsingProfile( $item['profile_id'], 'published' );
		$ended_listings     = WPLE_ListingQueryHelper::countItemsUsingProfile( $item['profile_id'], 'ended' );
		$locked_listings    = WPLE_ListingQueryHelper::countItemsUsingProfile( $item['profile_id'], 'locked' );

		// do we have a primary category?
        $primary_category_id = 0;
        $default_category_id = 0;
        $specifics = [];

		$details = $item['details'];
		if ( intval( $details['ebay_category_1_id'] ) != 0 ) {
			$primary_category_id = $details['ebay_category_1_id'];
		} else {
            // 04/11/2024: Do not load the Item Specifics for the default category. Instead, always add it to the set of loaded item specifics
			// if not use default category
			//$primary_category_id = $account_id ? WPLE()->accounts[ $account_id ]->default_ebay_category_id : self::getOption('default_ebay_category_id');
		}

		// fetch updated item specifics for category
        if ( !empty( $primary_category_id ) ) {
	        $specifics = EbayCategoriesModel::getItemSpecificsForCategory( $primary_category_id, $site_id, $account_id );
        }

        // Load the item specifics from the default eBay Category and add them to the list of Item Specifics
        if ( $account_id ) {
	        $default_category_id = WPLE()->accounts[ $account_id ]->default_ebay_category_id;
            $default_specifics = EbayCategoriesModel::getItemSpecificsForCategory( $default_category_id, $site_id, $account_id );

            $specifics = EbayCategoriesModel::mergeItemSpecifics( $specifics, $default_specifics );
        }

		// fetch updated available conditions array
		$current_primary_category_id = $primary_category_id ?: $default_category_id;
		$available_conditions = EbayCategoriesModel::getConditionsForCategory( $current_primary_category_id, false, $account_id );
		$available_condition_descriptions = [];
        $conditions_and_descriptions = [];
        $condition_descriptor_fields = [];

		if ( in_array( $details['ebay_category_1_id'], EbayCategoriesModel::getTradingCardsCategories() ) ) {
            $conditions_and_descriptions = EbayCategoriesModel::getTradingCardsConditionDescriptions();

            $available_condition_descriptions = $conditions_and_descriptions[ $details['ebay_category_1_id'] ];
			$condition_descriptor_fields = EbayCategoriesModel::getTradingCardsDescriptorFields();
        }

		// // build available conditions array
		// $available_conditions = false;
		// if ( isset( $item['conditions'][ $primary_category_id ] ) ) {
		// 	$available_conditions = $item['conditions'][ $primary_category_id ];
		// }
		// // echo "<pre>";print_r($available_conditions);echo"</pre>";

		// check if COD is available on the selected site
		$cod_available = false;
		foreach ( $payment_options as $po ) {
			if ( 'COD' == $po['payment_name'] ) $cod_available = true;
		}

		// fetch available shipping discount profiles
		$shipping_flat_profiles = array();
		$shipping_calc_profiles = array();
	    $ShippingDiscountProfiles = self::getOption('ShippingDiscountProfiles', array() );
		if ( isset( $ShippingDiscountProfiles['FlatShippingDiscount'] ) ) {
			$shipping_flat_profiles = $ShippingDiscountProfiles['FlatShippingDiscount'];
		}
		if ( isset( $ShippingDiscountProfiles['CalculatedShippingDiscount'] ) ) {
			$shipping_calc_profiles = $ShippingDiscountProfiles['CalculatedShippingDiscount'];
		}
		// echo "<pre>";print_r($shipping_flat_profiles);echo"</pre>";


		// get available seller profiles
		$seller_profiles_enabled  = get_option('wplister_ebay_seller_profiles_enabled');
		$seller_shipping_profiles = get_option('wplister_ebay_seller_shipping_profiles');
		$seller_payment_profiles  = get_option('wplister_ebay_seller_payment_profiles');
		$seller_return_profiles   = get_option('wplister_ebay_seller_return_profiles');

		if ( isset( WPLE()->accounts[ $account_id ] ) ) {
			$account = WPLE()->accounts[ $account_id ];
			$seller_profiles_enabled  = $account->seller_profiles;
			$seller_shipping_profiles = maybe_unserialize( $account->shipping_profiles );
			$seller_payment_profiles  = maybe_unserialize( $account->payment_profiles );
			$seller_return_profiles   = maybe_unserialize( $account->return_profiles );
            $shipping_profiles        = maybe_unserialize( $account->shipping_discount_profiles );

            if ( !empty( $shipping_profiles ) ) {
                //get the shipping discount profile from wp_ebay_account
                if ( isset( $shipping_profiles['FlatShippingDiscount'] ) ) {
                    $shipping_flat_profiles = $shipping_profiles['FlatShippingDiscount'];
                }
                if ( isset( $shipping_profiles['CalculatedShippingDiscount'] ) ) {
                    $shipping_calc_profiles = $shipping_profiles['CalculatedShippingDiscount'];
                }
            }
		}


		$aData = array(
			'plugin_url'				=> self::$PLUGIN_URL,
			'message'					=> $this->message,

			'item'                      => $item,
			'site_id'                   => $site_id,
			'account_id'                => $account_id,
			'payment_options'           => $payment_options,
			'loc_flat_shipping_options' => $loc_flat_shipping_options,
			'int_flat_shipping_options' => $int_flat_shipping_options,
			'loc_calc_shipping_options' => $loc_calc_shipping_options,
			'int_calc_shipping_options' => $int_calc_shipping_options,
			'available_attributes'      => $available_attributes,
			'custom_attributes'      	=> $wpl_custom_attributes,
			'calc_shipping_enabled'	 	=> in_array( self::getOption('ebay_site_id'), array(0,2,15,100) ),
			'default_ebay_category_id'	=> $account_id ? WPLE()->accounts[ $account_id ]->default_ebay_category_id : self::getOption('default_ebay_category_id'),
			'shipping_locations'        => $shipping_locations,
			'exclude_locations'         => $exclude_locations,
			'countries'                 => $countries,
			'template_files'            => $template_files,
			'store_categories'          => $store_categories,
			'prepared_listings_count'   => $prepared_listings,
			'verified_listings_count'   => $verified_listings,
			'published_listings_count'  => $published_listings,
			'ended_listings_count'      => $ended_listings,
			'locked_listings_count'     => $locked_listings,
			'total_listings_count'      => $prepared_listings + $verified_listings + $published_listings,
			'available_dispatch_times'  => $available_dispatch_times,
			'specifics'  				=> $specifics,
            'conditions_and_descriptions' => $conditions_and_descriptions,
			'available_conditions'  	=> $available_conditions,
			'available_condition_descriptions'  	=> $available_condition_descriptions,
            'condition_descriptor_fields' => $condition_descriptor_fields,
			'available_shipping_packages' => $available_shipping_packages,
			'shipping_flat_profiles'  	=> $shipping_flat_profiles,
			'shipping_calc_profiles'  	=> $shipping_calc_profiles,
			'cod_available'  			=> $cod_available,
			'ReturnsWithinOptions'  	=> $ReturnsWithinOptions,
			'ShippingCostPaidByOptions' => $ShippingCostPaidByOptions,
			'seller_profiles_enabled'	=> $seller_profiles_enabled,
			'seller_shipping_profiles'	=> $seller_shipping_profiles,
			'seller_payment_profiles'	=> $seller_payment_profiles,
			'seller_return_profiles'	=> $seller_return_profiles,
			'hazardous_materials_labels'=> maybe_unserialize( $wpl_site->HazardousMaterialsLabels ),
			'product_safety_labels'     => maybe_unserialize( $wpl_site->ProductSafetyLabels ),
			'form_action'				=> 'admin.php?page='.self::ParentMenuId.'-profiles'
		);
		$this->display( 'profiles_edit_page', array_merge( $aData, $item ) );
		
	}

	private function duplicateProfile() {
				
		// init model
		$profilesModel = new ProfilesModel();
		$new_profile_id = $profilesModel->duplicateProfile( wple_clean($_REQUEST['profile']) );
		
		// redirect to edit new profile
		wp_redirect( get_admin_url().'admin.php?page=wplister-profiles&action=edit&profile='.$new_profile_id );

	}


	private function downloadProfile( $profile_id ) {

		// load profile
		$profile_id = intval( $profile_id );
		$profilesModel = new ProfilesModel();
		$data = $profilesModel->getItem( $profile_id );

		// preprocess data
		unset( $data['profile_id'] );			// profile id will be generated on upload
		unset( $data['details']['profile_id'] );
		unset( $data['conditions'] );			// deprecated column
		unset( $data['category_specifics'] );	// deprecated column
		$profile_name = str_replace( '_', ' ', sanitize_file_name( str_replace( ' ', '_', $data['profile_name'] ) ) );

    	// send as json
    	$filename = "WPLE profile $profile_id - $profile_name"; 
        header('Content-Disposition: attachment; filename='.$filename.'.json');
        echo json_encode( $data );
        exit;	
	}


    private function uploadProfile() {

        $uploaded_file = $this->process_upload();
        if ( ! $uploaded_file ) return;

        $result = $this->import_json( $uploaded_file );

        if ( $result ) {
            wple_show_message( 'Profile "' . $result . '" was uploaded and restored successfully.');
        } else {
            wple_show_message( 'The uploaded file could not be imported. Please make sure you use a JSON backup file exported from this plugin.','warn');                
        }

        // clean up
        if ( file_exists($uploaded_file) ) unlink($uploaded_file);
    }

    // process content of JSON file
    private function import_json( $uploaded_file ) {
        global $wpdb;

        $json = file_get_contents( $uploaded_file );
        $data = json_decode( $json, true );

        // prepare data
        $profile_name = $data['profile_name'];
        $data['profile_name'] .= ' (restored)';
        $data['details'] = json_encode( $data['details'] );
		if ( ! $profile_name ) return false;

        // insert into db
		$result = $wpdb->insert( $wpdb->prefix.'ebay_profiles', $data );
		if ( ! $result ) return false;

		return $profile_name;
    }

    // process file upload
    private function process_upload() {

        if ( isset( $_FILES['wple_file_upload_profile'] ) ) {

			// set target path
			$upload_dir  = wp_upload_dir(); // Array of key => value pairs
            $target_path = $upload_dir['basedir'].'/wple-tmp-import-file.json';

            // delete last import
            if ( file_exists($target_path) ) unlink($target_path);

            if ( move_uploaded_file( $_FILES['wple_file_upload_profile']['tmp_name'], $target_path ) ) {
                return $target_path;
            } else {
                echo "There was an error uploading the file, please try again!";
            }
            return false;
        }
        echo "no file_upload set";
        return false;
    }




	static public function convertToDecimal( $price ) {
		$price = str_replace(',', '.', $price );
		$price = str_replace('$', '', $price );
		// $price = preg_replace( '/[^\d\.]/', '', $price );  
		return $price;
	}

	static public function fixProfilePrices( $details ) {
	
		if ( isset( $details['start_price'] ) ) $details['start_price'] = self::convertToDecimal( $details['start_price'] );
		if ( isset( $details['fixed_price'] ) ) $details['fixed_price'] = self::convertToDecimal( $details['fixed_price'] );
		if ( isset( $details['bo_minimum_price'] ) ) $details['bo_minimum_price'] = self::convertToDecimal( $details['bo_minimum_price'] );
		if ( isset( $details['bo_autoaccept_price'] ) ) $details['bo_autoaccept_price'] = self::convertToDecimal( $details['bo_autoaccept_price'] );

		if ( is_array( $details['loc_shipping_options'] ) )
		foreach ($details['loc_shipping_options'] as $key => &$option) {
			if ( isset( $option['price'] )) $option['price'] = self::convertToDecimal( $option['price'] );
			if ( isset( $option['add_price'] )) $option['add_price'] = self::convertToDecimal( $option['add_price'] );
		}

		if ( is_array( $details['int_shipping_options'] ) )
		foreach ($details['int_shipping_options'] as $key => &$option) {
			if ( isset( $option['price'] )) $option['price'] = self::convertToDecimal( $option['price'] );
			if ( isset( $option['add_price'] )) $option['add_price'] = self::convertToDecimal( $option['add_price'] );
		}

		return $details;
	}

	static public function getPreprocessedPostDetails() {
	    WPLE()->logger->info( 'getPreprocessedPostDetails' );

		// item details
		$details = array();
		foreach ( $_POST as $key => $val ) {
			if ( substr($key, 0, 8 ) == 'wpl_e2e_' ) {
				$field = substr( $key, 8);
				$details[$field] = stripslashes_deep( $val );
			}
		}
		WPLE()->logger->debug( 'Details: '. print_r( $details, 1 ) );
		// print_r($details);die();

		// fix condition_description
		$details['condition_description'] = isset( $details['condition_description'] ) ? stripslashes( $details['condition_description'] ) : '';

		// handle flat and calculated shipping
		$service_type = $details['shipping_service_type'] ?? 'flat';
		WPLE()->logger->info( 'service_type: ', $service_type );

		// process domestic and international shipping options arrays
		switch ( $service_type ) {
			case 'calc':
				$details['loc_shipping_options'] = $details['loc_shipping_options_calc'];
				$details['int_shipping_options'] = $details['int_shipping_options_calc'];
				break;
			
			case 'FlatDomesticCalculatedInternational':
				$details['loc_shipping_options'] = $details['loc_shipping_options_flat'];
				$details['int_shipping_options'] = $details['int_shipping_options_calc'];
				break;
			
			case 'CalculatedDomesticFlatInternational':
				$details['loc_shipping_options'] = $details['loc_shipping_options_calc'];
				$details['int_shipping_options'] = $details['int_shipping_options_flat'];
				break;
			
			default:
				$details['loc_shipping_options'] = $details['loc_shipping_options_flat'];
				$details['int_shipping_options'] = $details['int_shipping_options_flat'];
				break;
		}

		// handle free shipping option
		$loc_free_shipping = strstr( 'calc', strtolower($service_type) ) ? $details['shipping_loc_calc_free_shipping'] : $details['shipping_loc_flat_free_shipping'];
		$details['shipping_loc_enable_free_shipping'] = $loc_free_shipping;

		WPLE()->logger->debug( 'details after switch: '. print_r( $details, 1 ) );

        // record GPSR

		// fix entered prices
		$details = self::fixProfilePrices( $details );

		// clean details array
		unset( $details['loc_shipping_options_flat'] );
		unset( $details['loc_shipping_options_calc'] );
		unset( $details['int_shipping_options_flat'] );
		unset( $details['int_shipping_options_calc'] );
		unset( $details['shipping_loc_calc_free_shipping'] );
		unset( $details['shipping_loc_flat_free_shipping'] );

		return $details;
	}

    protected function processGpsrImages( $details, $account_id ) {
	    $profile_id = $this->getValueFromPost( 'profile_id' );
	    // init model
	    $profilesModel = new ProfilesModel();

	    // get item
	    $profile = $profilesModel->getItem( $profile_id );
        $prev_details = [];

        if ( $profile ) {
            $prev_details = $profile['details'];
        }

        WPLE()->initEC( $account_id );

        // Energy Efficiency Label Image
        if ( !empty( $details['gpsr_energy_efficiency_image'] ) ) {
            if ( $prev_details['gpsr_energy_efficiency_image'] != $details['gpsr_energy_efficiency_image'] ) {
	            $url = wp_get_attachment_url( $details['gpsr_energy_efficiency_image'] );
                $result = WPLE()->EC->uploadToEPS( $url, WPLE()->EC->session );

	            if ( is_wp_error( $result ) ) {
		            // let the user know which image failed to upload if there was an error
		            wple_show_message( $result->get_error_message(), 'error' );
		            return false;
	            }

                $details['gpsr_energy_efficiency_image_eps'] = $result->SiteHostedPictureDetails->FullURL;
            }
        } else {
            // clear the EPS
	        $details['gpsr_energy_efficiency_image_eps'] = '';
        }

        // Energy Efficiency Information Sheet Image
	    if ( !empty( $details['gpsr_energy_efficiency_sheet_image'] ) ) {
		    if ( $prev_details['gpsr_energy_efficiency_sheet_image'] != $details['gpsr_energy_efficiency_sheet_image'] ) {
			    $url = wp_get_attachment_url( $details['gpsr_energy_efficiency_sheet_image'] );
			    $result = WPLE()->EC->uploadToEPS( $url, WPLE()->EC->session );

			    if ( is_wp_error( $result ) ) {
				    // let the user know which image failed to upload if there was an error
				    wple_show_message( $result->get_error_message(), 'error' );
				    return false;
			    }

			    $details['gpsr_energy_efficiency_sheet_image_eps'] = $result->SiteHostedPictureDetails->FullURL;
		    }
	    } else {
		    // clear the EPS
		    $details['gpsr_energy_efficiency_sheet_image_eps'] = '';
	    }


        return $details;
    }

	private function saveProfile() {
		global $wpdb;	

		$details    = $this->getPreprocessedPostDetails();

		$profile_id = $this->getValueFromPost( 'profile_id' );
		$account_id = $this->getValueFromPost( 'account_id' );
		if ( ! $account_id ) $account_id = get_option( 'wplister_default_account_id' );
		$account    = WPLE()->accounts[ $account_id ];

		// fix entered prices
		$details = self::fixProfilePrices( $details );

        // Upload GPSR images to EPS
        $details = self::processGpsrImages( $details, $account_id );

		// process item specifics
		$item_specifics  = array();
		$itmSpecs_name   = wple_clean(@$_POST['itmSpecs_name']);
		$itmSpecs_value  = wp_kses_post_deep($_POST['itmSpecs_value'] ?? '');
		$itmSpecs_attrib = wple_clean(@$_POST['itmSpecs_attrib']);

		if ( is_array( $itmSpecs_name ) )
		foreach ($itmSpecs_name as $key => $name) {
			
			#$name = str_replace('\\\\', '', $name );
			$name = stripslashes( $name );

			$value = trim( $itmSpecs_value[$key] );
			$attribute = trim( $itmSpecs_attrib[$key] );

			if ( ( $value != '') || ( $attribute != '' ) ) {
				$spec = new stdClass();
				$spec->name       = $name;
				$spec->value      = $value;
				$spec->attribute  = $attribute;
				$item_specifics[] = $spec;
			}

		}
		$details['item_specifics'] = $item_specifics;

	
		// add category names
		$details['ebay_category_1_name']  = EbayCategoriesModel::getCategoryName( $details['ebay_category_1_id'], $account->site_id );
		$details['ebay_category_2_name']  = EbayCategoriesModel::getCategoryName( $details['ebay_category_2_id'], $account->site_id );
		$details['store_category_1_name'] = EbayCategoriesModel::getStoreCategoryName( $details['store_category_1_id'] );
		$details['store_category_2_name'] = EbayCategoriesModel::getStoreCategoryName( $details['store_category_2_id'] );

		// fix prices - already done in fixProfilePrices()
		// $details['start_price'] = str_replace(',', '.', $details['start_price'] );
		// $details['fixed_price'] = str_replace(',', '.', $details['fixed_price'] );

		// if the user enters only fixed price but no start price, move fixed price to start price
		if ( ( $details['start_price'] == '' ) && ( $details['fixed_price'] != '' ) ) {
			$details['start_price'] = $details['fixed_price'];
			$details['fixed_price'] = '';
		}

		// fix quantities
		if ( ! $details['custom_quantity_enabled'] ) {
			$details['quantity']     = '';
			$details['max_quantity'] = '';
		}
		
		// do we have a primary category?
		if ( intval( $details['ebay_category_1_id'] ) != 0 ) {
			$primary_category_id = $details['ebay_category_1_id'];
		} else {
			// if not use default category
		    $primary_category_id = self::getOption('default_ebay_category_id');
		}

		// Optional Secondary Category
        $details['enable_secondary_category'] = $this->getValueFromPost( 'secondary_category' );

        // Condition Descriptors
        $details['professional_grader'] = $this->getValueFromPost( 'professional_grader' );
        $details['grade'] = $this->getValueFromPost( 'grade' );
        $details['certification_number'] = $this->getValueFromPost('certification_number' );

		if ( WPLE_IS_LITE_VERSION ) $specifics = array();
			
		// sql columns
		$item = array();
		$item['profile_id'] 				= $profile_id;
		//$item['profile_name'] 				= $this->getValueFromPost( 'profile_name' );
		$item['profile_name'] 				= stripslashes( $this->getValueFromPost( 'profile_name', null, true ) );
		$item['profile_description'] 		= stripslashes( $this->getValueFromPost( 'profile_description' ) );
		$item['listing_duration'] 			= $this->getValueFromPost( 'listing_duration' );
		$item['type']						= $this->getValueFromPost( 'auction_type' );
		$item['sort_order'] 				= intval( $this->getValueFromPost( 'sort_order' ) );
		$item['details']			 		= json_encode( $details );		
		// $item['conditions']			 		= serialize( $conditions );	// deprecated	
		// $item['category_specifics']	 		= serialize( $specifics );	// deprecated	
		$item['conditions']			 		= '';
		$item['category_specifics']	 		= '';
		$item['account_id']					= $account_id;
		$item['site_id']					= WPLE()->accounts[ $item['account_id'] ]->site_id;
		
		// insert or update
		if ( empty( $item['profile_id'] ) ) {
			// insert new profile
			unset( $item['profile_id'] );
			$result = $wpdb->insert( $wpdb->prefix.'ebay_profiles', $item );
		} else {
			// update profile
			$result = $wpdb->update( $wpdb->prefix.'ebay_profiles', $item, 
				array( 'profile_id' => $item['profile_id'] ) 
			);
		}

		// proper error handling
		if ($result===false) {
			$this->showMessage( "There was a problem saving your profile.<br>SQL:<pre>".$wpdb->last_query.'</pre>'.$wpdb->last_error, true );	
		} else {
			$this->showMessage( __( 'Profile saved.', 'wp-lister-for-ebay' ) );

			// if we were updating this template as part of setup, move to next step
			if ( '4' == self::getOption('setup_next_step') ) self::updateOption('setup_next_step', 5);

		}

		// if this is a new profile, skip further processing
		if ( ! $profile_id ) return;

		// handle delayed update option
		if ( isset($_POST['wple_delay_profile_application']) ) {
		    // only if any of the status checkboxes is checked
            $activated_checkboxes = apply_filters( 'wple_activate_profile_update_checkboxes', true );

            if ( $activated_checkboxes ) {
                update_option( 'wple_job_reapply_profile_id', $profile_id );
                return;
            } else {
                if (
                    isset($_POST['wpl_e2e_apply_changes_to_all_prepared']) ||
                    isset($_POST['wpl_e2e_apply_changes_to_all_verified']) ||
                    isset($_POST['wpl_e2e_apply_changes_to_all_published']) ||
                    isset($_POST['wpl_e2e_apply_changes_to_all_ended'])
                ) {
                    update_option( 'wple_job_reapply_profile_id', $profile_id );
                    return;
                }
            }
		}

		// prepare for updating items
		$listingsModel = new ListingsModel();
		$profilesModel = new ProfilesModel();
        $profile = $profilesModel->getItem( $this->getValueFromPost( 'profile_id' ) );

		// re-apply profile to all prepared
		if ( $this->getValueFromPost( 'apply_changes_to_all_prepared' ) == 'yes' ) {
			$items = WPLE_ListingQueryHelper::getAllPreparedWithProfile( $item['profile_id'] );
	        $listingsModel->applyProfileToItems( $profile, $items );
			$this->showMessage( sprintf( __( '%s prepared items updated.', 'wp-lister-for-ebay' ), count($items) ) );
		}
		
		// re-apply profile to all verified
		if ( $this->getValueFromPost( 'apply_changes_to_all_verified' ) == 'yes' ) {
			$items = WPLE_ListingQueryHelper::getAllVerifiedWithProfile( $item['profile_id'] );
	        $listingsModel->applyProfileToItems( $profile, $items );
			$this->showMessage( sprintf( __( '%s verified items updated.', 'wp-lister-for-ebay' ), count($items) ) );
		}
		
		// re-apply profile to all published
		if ( $this->getValueFromPost( 'apply_changes_to_all_published' ) == 'yes' ) {
			$items = WPLE_ListingQueryHelper::getAllPublishedWithProfile( $item['profile_id'] );
	        $listingsModel->applyProfileToItems( $profile, $items );
			$this->showMessage( sprintf( __( '%s published items changed.', 'wp-lister-for-ebay' ), count($items) ) );
		}
		
		// re-apply profile to all ended
		if ( $this->getValueFromPost( 'apply_changes_to_all_ended' ) == 'yes' ) {
			$items = WPLE_ListingQueryHelper::getAllEndedWithProfile( $item['profile_id'] );
	        $listingsModel->applyProfileToItems( $profile, $items );
			$this->showMessage( sprintf( __( '%s ended items updated.', 'wp-lister-for-ebay' ), count($items) ) );

			// update ended listings - required for autorelist to be applied
			// $listingsModel->updateEndedListings();
			$this->initEC( $account_id );
			$this->EC->updateListings();
			$this->EC->closeEbay();			
		}
		
	} // saveProfile()
	
	public function getTemplatesList() {

		$templatesModel = new TemplatesModel();
		$templates = $templatesModel->getAll();
		return $templates;
	}
	
	public function getStoreCategories( $account_id ) {
		global $wpdb;
		
		$results = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}ebay_store_categories WHERE account_id = %d", $account_id ) );
		return $results;
	}

	
	public function onWpPrintStyles() {

		// jqueryFileTree
		wp_register_style('jqueryFileTree_style', self::$PLUGIN_URL.'js/jqueryFileTree/jqueryFileTree.css' );
		wp_enqueue_style('jqueryFileTree_style'); 

		// load styles for chosen.js
		global $woocommerce;
		if ( is_object($woocommerce) )
 			wp_enqueue_style( 'woocommerce_admin_styles', $woocommerce->plugin_url() . '/assets/css/admin.css' );

		if ( version_compare( WC_VERSION, '2.6.0', '>=' ) ) {
			wp_register_style( 'chosen_css', self::$PLUGIN_URL.'js/chosen/chosen.css' );
			wp_enqueue_style( 'chosen_css' ); 
		}

	}

	public function onWpEnqueueScripts() {

		// jqueryFileTree
		wp_register_script( 'jqueryFileTree', self::$PLUGIN_URL.'js/jqueryFileTree/jqueryFileTree.js', array( 'jquery' ) );
		wp_enqueue_script( 'jqueryFileTree' );

		// nano template engine
		// wp_register_script( 'jquery_nano', self::$PLUGIN_URL.'/js/template/jquery.nano.js', array( 'jquery' ) );
		// wp_enqueue_script( 'jquery_nano' );

		// mustache template engine
		wp_register_script( 'mustache', self::$PLUGIN_URL.'js/template/mustache.js', array( 'jquery' ) );
		wp_enqueue_script( 'mustache' );

		// enqueue chosen.js from WooCommerce (removed in WC2.6)
      	// wp_enqueue_script( 'ajax-chosen' );
		if ( version_compare( WC_VERSION, '2.6.0', '>=' ) ) {
			wp_register_script( 'chosen', self::$PLUGIN_URL.'js/chosen/chosen.jquery.min.js', array( 'jquery' ) );
		}
	   	wp_enqueue_script( 'chosen' );

		// jQuery UI Autocomplete
		wp_enqueue_script( 'jquery-ui-button' );
		wp_enqueue_script( 'jquery-ui-autocomplete' );

		// Enqueue WordPress media scripts
		//wp_enqueue_script( 'wple' );
		wp_enqueue_media();

		// add_thickbox();
		wp_enqueue_script( 'thickbox' );
		wp_enqueue_style( 'thickbox' );

		wp_enqueue_script( 'jquery-blockui' );

	}


	static public function wpl_generate_shipping_option_tags( $services, $selected_service ) {
		?>

		<option value="">-- <?php echo __( 'Please select', 'wp-lister-for-ebay' ); ?> --</option>
		
		<?php
        $lastShippingCategory = '';
        if ( isset( $services[0]['ShippingCategory'] ) ):
            $lastShippingCategory = @$services[0]['ShippingCategory'];
        ?>
		<optgroup label="<?php echo @$services[0]['ShippingCategory'] ?>">
        <?php endif; ?>
		
		<?php foreach ($services as $service) : ?>
			
			<?php if ( $lastShippingCategory != $service['ShippingCategory'] ) : ?>
			</optgroup>
			<optgroup label="<?php echo $service['ShippingCategory'] ?>">
			<?php $lastShippingCategory = $service['ShippingCategory'] ?>
			<?php endif; ?>

			<option value="<?php echo $service['service_name'] ?>" 
				<?php if ( isset($selected_service['service_name']) && $selected_service['service_name'] == $service['service_name'] ) : ?>
					selected="selected"
				<?php endif; ?>
				><?php echo $service['service_description'] ?></option>
		<?php endforeach; ?>
		</optgroup>

		<?php	
	}



}
