<?php /* Insert order to database */
if ( ! function_exists( 'wpj_insert_job_purchase_order' ) ) {
	function wpj_insert_job_purchase_order( $args = [] ) {
		// Current time
		$current_time = current_time( 'timestamp', 1 );

		// Job info
		$pid  = ! empty( $args['jobid'] ) ? $args['jobid'] : WPJ_Form::get( 'jobid' );

		if ( ! $pid ) $pid = get_query_var( 'jobid' );

		$pid  = wpj_get_post_id( $pid );
		$post = get_post( $pid );

		// User info
		$buyer_id = ! empty( $args['uid'] ) ? $args['uid'] : get_current_user_id();

		// Check if a recent order exists
		$last_order = wpj_get_job_order( 'id, date_made', ['pid' => $pid, 'uid' => $buyer_id], 'row', '', 'date_made DESC' );

		if ( isset( $last_order->date_made ) && $last_order->date_made && ( $current_time - $last_order->date_made ) < 10 ) {
			return $last_order->id;
		}

		global $wpdb;
		
		// Start transaction
		$wpdb->query( 'START TRANSACTION' );
		
		try {

			// Check if order exist
			$row_order = wpj_get_job_order( 'id', ['pid' => $pid, 'uid' => $buyer_id, 'date_made' => $current_time], 'row' );

			// Insert order
			if ( ! $row_order && $pid && $buyer_id && $current_time ) {

				// Job info
				$job_title        = esc_sql( wpj_encode_emoji( apply_filters( 'wpj_order_insert_job_title_filter', $post->post_title, $pid ) ) );
				$job_description  = esc_sql( wpj_encode_emoji( $post->post_content ) );
				$job_instructions = esc_sql( wpj_encode_emoji( get_post_meta( $pid, 'instruction_box', true ) ) );
				$job_type         = esc_sql( get_post_meta( $pid, 'price_type', true ) );

				// Payment info
				$payment_status  = ! empty( $args['payment_status'] ) ? $args['payment_status'] : 'pending';
				$payment_gateway = ! empty( $args['payment_gateway'] ) ? $args['payment_gateway'] : WPJ_Form::get( 'pay_for_item' );

				$seller_confirmation = wpj_get_option( 'wpjobster_seller_order_rejection_enable' ) == 'yes' ? 0 : 1;

				// Currency
				$currency = ! empty( $args['currency'] ) ? $args['currency'] : apply_filters( 'wpjobster_take_allowed_currency_' . $payment_gateway, '' );

				if ( empty( $currency ) ) $currency = wpj_get_site_currency();

				// Extras
				$extras       = wpj_get_order_extras_info( ( ! empty( $args['extras'] ) ? $args['extras'] : '' ), $pid );
				$extras_price = apply_filters( 'wpj_order_insert_job_extras_price_filter', $extras['extras_price'], $pid );

				// Order price
				$sample_price = get_post_meta( $pid, 'job_packages', true ) == 'yes' ? WPJ_Form::get( 'package_price' ) : get_post_meta( $pid, 'price', true );
				$sample_price = apply_filters( 'wpj_order_insert_job_price_filter', $sample_price, $pid );

				$quantity = ! empty( $args['amount'] ) ? $args['amount'] : WPJ_Form::get( 'amount', 1 );

				if ( ! is_numeric( $sample_price ) || $sample_price < 0 ) {
					$sample_price = wpj_get_option( 'wpjobster_job_fixed_amount' );
				}

				$price = apply_filters( 'wpj_order_insert_job_price_with_quantity_filter', ( $sample_price * $quantity ), $pid );

				// Shipping
				$shipping = ! empty( $args['shipping'] ) ? $args['shipping'] : get_post_meta( $pid, 'shipping', true );

				if ( empty( $shipping ) ) $shipping = 0;

				// Buyer Fee
				$processing_fees = ! empty( $args['processing_fees'] ) ? $args['processing_fees'] : '';

				if ( ! $processing_fees ) $processing_fees = wpj_get_site_processing_fee_by_amount( $price, $extras_price, $shipping );

				// Tax
				$tax = ! empty( $args['tax'] ) ? $args['tax'] : '';

				if ( ! $tax ) $tax = wpj_get_site_tax_by_amount( $price, $extras_price, $shipping, $processing_fees );

				// Seller Fee
				$order_price = $price + $shipping + $extras_price;
				$site_fee    = wpj_get_site_fee_by_amount( $order_price, '', $post->post_author );
				$site_fee    = apply_filters( 'wpj_order_insert_job_site_fee_filter', $site_fee, $order_price, ( $sample_price * $quantity + $shipping + $extras['extras_price'] ) );

				// Final order price
				$payable_amount = ! empty( $args['payable_amount'] ) ? $args['payable_amount'] : ( $order_price + $processing_fees + $tax );
				$payable_amount = apply_filters( 'wpj_order_insert_job_payable_amount_filter', $payable_amount, $price, $extras_price, $shipping, $processing_fees, $tax );

				// Final order price exchanged
				if ( $currency ) {
					$payable_amount_exchanged = wpj_number_format_special_exchange( $payable_amount, '1', $currency );

				} else {
					$payable_amount_exchanged = wpj_number_format_special_exchange( $payable_amount );

				}

				// Decrease credits if payment method is Account Balance
				if ( $payment_gateway == 'credits' ) {
					$user_credit = wpj_get_user_credit( $buyer_id );

					if ( $payable_amount > $user_credit ) {
						wp_redirect( wpj_get_payment_link() . 'topup?no_credits=1' ); exit;
					}

					wpj_update_user_credit( $buyer_id, $user_credit - $payable_amount );
				}

				// Insert order to database
				$database_info = [
					'date_made'            => $current_time,

					'seller_confirmation'  => $seller_confirmation,

					'payment_status'       => $payment_status,
					'payment_gateway'      => $payment_gateway,

					'pid'                  => $pid,
					'uid'                  => $buyer_id,

					'mc_gross'             => $order_price,
					'processing_fees'      => $processing_fees,
					'site_fees'            => $site_fee,
					'tax_amount'           => $tax,
					'shipping'             => $shipping,
					'payedamount'          => $currency . '|' . wpj_number_format_special_exchange( $order_price, 1, $currency ),
					'final_paidamount'     => $currency . '|' . wpj_number_format_special_exchange( $payable_amount, 1, $currency ),

					'job_type'             => $job_type,
					'job_price'            => $sample_price,
					'job_amount'           => $quantity,
					'job_title'            => $job_title,
					'job_description'      => $job_description,
					'job_instructions'     => $job_instructions,

					'extra_fast'           => $extras['extra_fast_amount'],
					'extra_fast_price'     => $extras['extra_fast_price'],
					'extra_fast_days'      => $extras['extra_fast_days'],
					'extra_revision'       => $extras['extra_revision_amount'],
					'extra_revision_price' => $extras['extra_revision_price'],
					'extra_revision_days'  => $extras['extra_revision_days']
				];

				for ( $i = 1; $i <= 10; $i++ ) {
					$database_info['extra' . $i]            = $extras['extra' . $i];
					$database_info['extra' . $i . '_price'] = $extras['extra' . $i . '_price'];
					$database_info['extra' . $i . '_title'] = $extras['extra' . $i . '_title'];
					$database_info['extra' . $i . '_days']  = $extras['extra' . $i . '_days'];
				}

				if ( ! empty( $_GET['package_delivery_days'] ) && get_post_meta( $pid, 'job_packages', true ) == 'yes' ) {
					$database_info['expected_delivery'] = $_GET['package_delivery_days'];
				}

				$database_info_type = [
					'%d',
					'%d',
					'%s', '%s',
					'%d', '%d',
					'%f', '%f', '%f', '%f', '%f', '%s', '%s',
					'%s', '%f', '%d', '%s', '%s', '%s',
					'%d', '%f', '%d', '%d', '%f', '%d',

					'%d', '%f', '%s', '%d',
					'%d', '%f', '%s', '%d',
					'%d', '%f', '%s', '%d',
					'%d', '%f', '%s', '%d',
					'%d', '%f', '%s', '%d',
					'%d', '%f', '%s', '%d',
					'%d', '%f', '%s', '%d',
					'%d', '%f', '%s', '%d',
					'%d', '%f', '%s', '%d',
					'%d', '%f', '%s', '%d',
				];

				if ( ! empty( $_GET['package_delivery_days'] ) && get_post_meta( $pid, 'job_packages', true ) == 'yes' ) {
					array_push( $database_info_type, '%d' );
				}

				$orderid = wpj_insert_job_order( $database_info, $database_info_type );

				// Commit transaction
				$wpdb->query('COMMIT');

				do_action( 'wpj_after_insert_order', $orderid );

				// Insert payment to database
				wpj_insert_payment(
					[
						'payment_status'         => $payment_status == 'completed' ? 1 : 0,
						'payment_gateway'        => $payment_gateway,
						'payment_type'           => 'job_purchase',
						'payment_type_id'        => $orderid,
						'fees'                   => $processing_fees,
						'amount'                 => $price,
						'datemade'               => $current_time,
						'tax'                    => $tax,
						'currency'               => wpj_get_site_default_currency(),
						'final_amount'           => $payable_amount,
						'final_amount_exchanged' => $payable_amount_exchanged,
						'final_amount_currency'  => $currency,
					],
					['%d', '%s', '%s', '%d', '%f', '%f', '%d', '%f', '%s', '%f', '%f', '%s']
				);

				// Save package info
				if ( isset( $_GET['package_no'] ) && is_numeric( $_GET['package_no'] ) && get_post_meta( $pid, 'job_packages', true ) == 'yes' ) {
					update_post_meta( $pid, 'order_package_no_' . $orderid, $_GET['package_no'] );
				}

				return $orderid;

			} else {

				// Order already exists, rollback transaction
				$wpdb->query('ROLLBACK');

				return $row_order->id;

			}
		} catch (Exception $e) {
			// Error occurred, rollback transaction
			$wpdb->query('ROLLBACK');
			
			// Handle or log the error
			return false;
		}
	}
}