<?php

namespace Gigneo;

use Exception;
use WC_Customer;

if ( ! defined( 'ABSPATH' ) ) {
	exit; // Exit if accessed directly.
}

/**
 * Class Withdrawals
 *
 * Plugin Withdrawals class for Gigneo.
 *
 * @since 0.0.1
 */
class Withdrawals {


	/**
	 * The single instance of the class.
	 *
	 * @var Withdrawals|null
	 * @since 0.0.1
	 */
	private static $instance = null;

	/**
	 * Constructor for the class.
	 *
	 * @since 0.0.1
	 */
	public function __construct() {
		// Remove quick edit and edit links from gigneo_withdrawal post type
		add_filter( 'post_row_actions', array( $this, 'remove_quick_edit_and_edit_links' ), 10, 2 );
		// Add custom withdrawal columns.
		add_filter( 'manage_gigneo_withdrawal_posts_columns', array( $this, 'define_custom_columns' ), 20 );
		// Output content for custom withdrawal columns.
		add_action( 'manage_gigneo_withdrawal_posts_custom_column', array( $this, 'render_column_content' ), 10, 2 );
		//Process Withdrawals via AJAX
		add_action( 'wp_ajax_gigneo_withdrawal_action', array( $this, 'withdrawal_action' ) );
		//Save Payout Method
		add_action( 'wp_ajax_gigneo_save_payout_method', array( $this, 'save_payout_method' ) );
		//Delete Payout Method
		add_action( 'wp_ajax_gigneo_delete_payout_method', array( $this, 'delete_payout_method' ) );
		//Withdraw Funds
		add_action( 'wp_ajax_gigneo_withdraw_funds', array( $this, 'withdraw_fund_request' ) );
		//Cancel Withdraw Funds Request
		add_action( 'wp_ajax_gigneo_cancel_withdrawal_request', array( $this, 'cancel_withdrawal_request' ) );
		//Menu Counter
		add_action( 'admin_menu', array( $this, 'menu_counter' ) );
	}

	/**
	 * Ensures only one instance of the class is loaded or can be loaded.
	 *
	 * @return Withdrawals
	 * @since 0.0.1
	 */
	public static function instance() {
		if ( is_null( self::$instance ) ) {
			self::$instance = new self();
		}

		return self::$instance;
	}

	/**
	 * Handle pending withdrawal counter in admin menu.
	 *
	 * Adds a badge to the "Withdrawal Requests" menu item showing count of request Pending.
	 *
	 * @return void
	 */
	public function menu_counter() {

		global $submenu;
		$counts  = wp_count_posts( 'gigneo_withdrawal' );
		$pending = isset( $counts->{'publish'} ) ? (int) $counts->{'publish'} : 0;

		if ( $pending <= 0 || ! isset( $submenu['gigneo'] ) ) {
			return;
		}

		foreach ( $submenu['gigneo'] as $key => $item ) {
			if ( isset( $item[2] ) && 'edit.php?post_type=gigneo_withdrawal' === $item[2] ) {
                // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
				$submenu['gigneo'][ $key ][0] .= sprintf(
						// translators: %1$d is the count of pending withdrawal requests.
					' <span class="update-plugins count-%1$d"><span class="plugin-count">%1$d</span></span>',
					esc_html( $pending )
				);
				break;
			}
		}
	}
	/**
	 * Handle withdraw funds from wallet.
	 *
	 * @throws Exception
	 * @since 0.0.1
	 */
	public function withdraw_fund_request() {

		// Check if nonce is valid
		$security = isset( $_POST['security'] ) ? sanitize_text_field( wp_unslash( $_POST['security'] ) ) : '';
		if ( empty( $security ) || ! wp_verify_nonce( $security, 'gigneo_security' ) ) {
			wp_send_json_error( array( 'message' => esc_html__( 'Security verification failed. Please reload and try again.', 'gigneo' ) ), 403 );
		}

		$amount = isset( $_POST['amount'] ) ? abs( floatval( wp_unslash( $_POST['amount'] ) ) ) : 0;

		if ( empty( $amount ) || ! is_numeric( $amount ) || $amount < 1 ) {
			wp_send_json_error( array( 'message' => esc_html__( 'Required fields could not be empty.', 'gigneo' ) ), 403 );
		}

		if ( ! isset( $_POST['payout'] ) ) {
			wp_send_json_error( array( 'message' => esc_html__( 'Payout method not selected.', 'gigneo' ) ), 403 );
		}

		$payout = absint( wp_unslash( $_POST['payout'] ) );

		$platform_access = gigneo_user_have_access();
		$profile_id      = gigneo_active_profile_id();
		$current_user    = wp_get_current_user();

		if ( empty( $current_user->ID ) || ! $platform_access || empty( $profile_id ) ) {
			wp_send_json_error( array( 'message' => esc_html__( 'You do not have permission to do that.', 'gigneo' ) ), 403 );
		}

		$profile_type = gigneo_profile_type();

		if ( 'freelancer' !== $profile_type && 'employer' !== $profile_type ) {
			wp_send_json_error( array( 'message' => esc_html__( 'You do not have permission to do that.', 'gigneo' ) ), 403 );
		}

		$customer = new WC_Customer( $current_user->ID );

		$country  = $customer->get_billing_country() ?? '';
		$state    = $customer->get_billing_state() ?? '';
		$postcode = $customer->get_billing_postcode() ?? '';
		$city     = $customer->get_billing_city() ?? '';

		if ( empty( $country ) || empty( $state ) || empty( $postcode ) || empty( $city ) ) {
			wp_send_json_error( array( 'message' => esc_html__( 'Billing information not set. Please update on account billing settings.', 'gigneo' ) ), 400 );
		}

		$minimum_withdrawal = gigneo_option( '_gigneo_ts_minimum_withdraw_amount', 0 );

		if ( $amount < $minimum_withdrawal ) {
			wp_send_json_error(
				array(
					'message' => sprintf(
							// translators: %s is the minimum withdrawal amount with currency symbol.
						esc_html__( 'The minimum withdrawal amount is %s.', 'gigneo' ),
						esc_html( gigneo_price_format( $minimum_withdrawal ) )
					),
					403,
				)
			);
		}

		$wallet_balance = gigneo_wallet_balance( $profile_id );

		if ( $amount > $wallet_balance ) {
			wp_send_json_error( array( 'message' => esc_html__( 'Insufficient wallet balance.', 'gigneo' ) ), 403 );
		}

		$profile_payouts = gigneo_profile_payouts( $profile_id, 'active' );

		if ( ! isset( $profile_payouts[ $payout ] ) ) {
			wp_send_json_error( array( 'message' => esc_html__( 'Invalid payout method selected.', 'gigneo' ) ), 403 );
		}

		$subtotal = $amount;

		$profile_payout   = $profile_payouts[ $payout ];
		$total_commission = 0;

		$profile_payouts_meta = gigneo_post_meta( $profile_id, '_gigneo_pm_payouts' );

		if ( ! isset( $profile_payouts_meta[ $payout ] ) ) {
			wp_send_json_error( array( 'message' => esc_html__( 'Invalid payout method selected.', 'gigneo' ) ), 403 );
		}

		$profile_payout_meta = $profile_payouts_meta[ $payout ];

		if ( ! isset( $profile_payout['type'] ) || ! isset( $profile_payout_meta['type'] ) || $profile_payout_meta['type'] !== $profile_payout['type'] ) {
			wp_send_json_error( array( 'message' => esc_html__( 'Payout method configuration mismatch.', 'gigneo' ) ), 403 );
		}

		//Payout Info
		$payout_fields = array();

		$profile_payout_type = $profile_payout['type'];

		if ( 'payoneer' === $profile_payout_type ) {
			$payout_fields['payoneer_account']['label'] = esc_html__( 'Payoneer account', 'gigneo' );
			$payout_fields['payoneer_account']['value'] = $profile_payout_meta['payoneer_account'] ?? '';
		} elseif ( 'paypal' === $profile_payout_type ) {
			$payout_fields['paypal_account']['label'] = esc_html__( 'Paypal account', 'gigneo' );
			$payout_fields['paypal_account']['value'] = $profile_payout_meta['paypal_account'] ?? '';
		} elseif ( 'bank' === $profile_payout_type ) {
			$bank_field_list = gigneo_payout_bank_fields();
			if ( ! empty( $bank_field_list ) && is_array( $bank_field_list ) ) {
				foreach ( $bank_field_list as $bank_field_key => $bank_field_title ) {
					$payout_fields[ 'bank_' . $bank_field_key ]['label'] = $bank_field_title;
					$payout_fields[ 'bank_' . $bank_field_key ]['value'] = $profile_payout_meta[ 'bank_' . $bank_field_key ] ?? '';
				}
			}
		} else {
			$payout_fields = apply_filters( 'gigneo_profile_custom_payout_fields', $payout_fields, $profile_payout_type, $profile_payout_meta );
		}

		$payout_info = array(
			'id'     => $payout,
			'type'   => $profile_payout_type,
			'label'  => $profile_payout['label'],
			'title'  => $profile_payout['title'],
			'fields' => $payout_fields,
		);

		if ( ! empty( $profile_payout['commission']['percentage'] ) ) {
			$percentage        = abs( $profile_payout['commission']['percentage'] );
			$percentage_amount = ( $percentage * $amount ) / 100;
			$total_commission += floatval( $percentage_amount );
			$subtotal          = floatval( $subtotal - $percentage_amount );
		}

		if ( ! empty( $profile_payout['commission']['fixed'] ) ) {
			$fixed             = abs( $profile_payout['commission']['fixed'] );
			$total_commission += floatval( $fixed );
			$subtotal          = floatval( $subtotal - $fixed );
		}

		$post_id = wp_insert_post(
			array(
				'post_type'   => 'gigneo_withdrawal',
				'post_status' => 'publish',
				'post_title'  => esc_html__( 'Withdraw request', 'gigneo' ),
			)
		);

		if ( is_wp_error( $post_id ) ) {
			wp_send_json_error( array( 'message' => esc_html__( 'Something went wrong.', 'gigneo' ) ), 403 );
		}

		update_post_meta( $post_id, '_gigneo_pm_profile_id', $profile_id );
		update_post_meta( $post_id, '_gigneo_pm_subtotal', $subtotal );
		update_post_meta( $post_id, '_gigneo_pm_total', $amount );

		if ( ! empty( $profile_payout['commission']['percentage'] ) || ! empty( $profile_payout['commission']['fixed'] ) ) {
			$commission          = $profile_payout['commission'];
			$commission['total'] = $total_commission;

			update_post_meta( $post_id, '_gigneo_pm_commission', $commission );
		}

		update_post_meta( $post_id, '_gigneo_pm_payout', $payout_info );

		// Trigger Email.
		$wc_mailer = WC()->mailer();
		$wc_emails = $wc_mailer->get_emails();

		if ( isset( $wc_emails['Gigneo_Withdraw_Request'] ) ) {
			$wc_emails['Gigneo_Withdraw_Request']->trigger( $profile_id, $post_id );
		}

		$response             = array();
		$response['message']  = esc_html__( 'Withdrawal request submitted successfully.', 'gigneo' );
		$response['redirect'] = wc_get_checkout_url();

		wp_send_json_success( $response, 200 );
	}

	/**
	 * Handle cancel withdrawal request.
	 *
	 * @since 0.0.1
	 */
	public function cancel_withdrawal_request() {

		// Check if nonce is valid
		$security = isset( $_POST['security'] ) ? sanitize_text_field( wp_unslash( $_POST['security'] ) ) : '';
		if ( empty( $security ) || ! wp_verify_nonce( $security, 'gigneo_security' ) ) {
			wp_send_json_error( array( 'message' => esc_html__( 'Security verification failed. Please reload and try again.', 'gigneo' ) ), 403 );
		}

		$p_id = isset( $_POST['id'] ) ? absint( wp_unslash( $_POST['id'] ) ) : 0;

		if ( empty( $p_id ) ) {
			wp_send_json_error( array( 'message' => esc_html__( 'Something went wrong.', 'gigneo' ) ), 403 );
		}

		$platform_access = gigneo_user_have_access();
		$profile_id      = gigneo_active_profile_id();
		$current_user    = wp_get_current_user();

		if ( empty( $current_user->ID ) || ! $platform_access || empty( $profile_id ) ) {
			wp_send_json_error( array( 'message' => esc_html__( 'You do not have permission to do that.', 'gigneo' ) ), 403 );
		}

		$profile_type = gigneo_profile_type();

		if ( 'freelancer' !== $profile_type && 'employer' !== $profile_type ) {
			wp_send_json_error( array( 'message' => esc_html__( 'You do not have permission to do that.', 'gigneo' ) ), 403 );
		}

		$p_status     = get_post_status( $p_id );
		$p_profile_id = gigneo_post_meta( $p_id, '_gigneo_pm_profile_id' );

		if ( 'publish' !== $p_status || absint( $profile_id ) !== absint( $p_profile_id ) ) {
			wp_send_json_error( array( 'message' => esc_html__( 'You do not have permission to do that.', 'gigneo' ) ), 403 );
		}

		wp_delete_post( $p_id, true );

		wp_send_json_success( array( 'message' => esc_html__( 'Withdrawal request cancelled successfully.', 'gigneo' ) ), 200 );
	}

	/**
	 * Save payout method via AJAX.
	 *
	 * Handles the saving and validation of payout method data submitted via AJAX.
	 *
	 * @since 0.0.1
	 * @return void Sends JSON response and exits.
	 */
	public function save_payout_method() {

		// Check if nonce is valid
		$security = isset( $_POST['security'] ) ? sanitize_text_field( wp_unslash( $_POST['security'] ) ) : '';
		if ( empty( $security ) || ! wp_verify_nonce( $security, 'gigneo_security' ) ) {
			wp_send_json_error( array( 'message' => esc_html__( 'Security verification failed. Please reload and try again.', 'gigneo' ) ), 403 );
		}

		$platform_access = gigneo_user_have_access();
		$profile_id      = gigneo_active_profile_id();
		$current_user    = wp_get_current_user();

		if ( empty( $current_user->ID ) || empty( $profile_id ) || ! $platform_access ) {
			wp_send_json_error( array( 'message' => esc_html__( 'You do not have permission to do that.', 'gigneo' ) ), 403 );
		}

		$type   = isset( $_POST['type'] ) ? sanitize_text_field( wp_unslash( $_POST['type'] ) ) : '';
		$id     = isset( $_POST['payout_id'] ) ? sanitize_text_field( wp_unslash( $_POST['payout_id'] ) ) : '';
		$label  = isset( $_POST['payout_label'] ) ? sanitize_text_field( wp_unslash( $_POST['payout_label'] ) ) : '';
		$status = isset( $_POST['payout_status'] ) ? sanitize_text_field( wp_unslash( $_POST['payout_status'] ) ) : 'active';

		if ( empty( $type ) || empty( $status ) ) {
			wp_send_json_error( array( 'message' => esc_html__( 'Something went wrong.', 'gigneo' ) ), 400 );
		}

		$active_payout_list = gigneo_withdrawal_payout_list();
		$payouts            = gigneo_post_meta( $profile_id, '_gigneo_pm_payouts' );
		$payouts            = ! empty( $payouts ) && is_array( $payouts ) ? $payouts : array();
		$custom_payouts     = gigneo_option( '_gigneo_ts_payment_custom_payouts', array() );

		if ( ! isset( $active_payout_list[ $type ] ) ) {
			wp_send_json_error( array( 'message' => esc_html__( 'Something went wrong.', 'gigneo' ) ), 400 );
		}

		$response            = array();
		$response['message'] = esc_html__( 'Payout setting update successfully.', 'gigneo' );

		//Paypal Payout
		if ( 'paypal' === $type ) {
			$paypal_account = isset( $_POST['paypal_account'] ) ? sanitize_text_field( wp_unslash( $_POST['paypal_account'] ) ) : '';

			if ( empty( $paypal_account ) ) {
				wp_send_json_error( array( 'message' => esc_html__( 'Required fields could not be empty.', 'gigneo' ) ), 403 );
			}

			$payout_data = array(
				'value'          => '_',
				'type'           => 'paypal',
				'label'          => $label,
				'status'         => $status,
				'paypal_account' => $paypal_account,
			);

			if ( '' !== $id && isset( $payouts[ $id ] ) ) {
				$payouts[ $id ] = $payout_data;
			} else {
				array_unshift( $payouts, $payout_data );
			}

			update_post_meta( $profile_id, '_gigneo_pm_payouts', $payouts );

			ob_start();
			gigneo_load_template( 'dashboard/setting/parts/billing/payouts' );
			$payouts_markup                = ob_get_clean();
			$response['markup']['payouts'] = $payouts_markup;

			wp_send_json_success( $response, 200 );
		}

		//Payoneer Payout
		if ( 'payoneer' === $type ) {
			$payoneer_account = isset( $_POST['payoneer_account'] ) ? sanitize_text_field( wp_unslash( $_POST['payoneer_account'] ) ) : '';

			if ( empty( $payoneer_account ) ) {
				wp_send_json_error( array( 'message' => esc_html__( 'Required fields could not be empty.', 'gigneo' ) ), 403 );
			}

			$payout_data = array(
				'value'            => '_',
				'type'             => 'payoneer',
				'label'            => $label,
				'status'           => $status,
				'payoneer_account' => $payoneer_account,
			);

			if ( '' !== $id && isset( $payouts[ $id ] ) ) {
				$payouts[ $id ] = $payout_data;
			} else {
				array_unshift( $payouts, $payout_data );
			}

			update_post_meta( $profile_id, '_gigneo_pm_payouts', $payouts );

			ob_start();
			gigneo_load_template( 'dashboard/setting/parts/billing/payouts' );
			$payouts_markup                = ob_get_clean();
			$response['markup']['payouts'] = $payouts_markup;

			wp_send_json_success( $response, 200 );
		}

		//Bank Payout
		if ( 'bank' === $type ) {

			$bank_field_list      = gigneo_payout_bank_fields();
			$bank_required_fields = gigneo_option( '_gigneo_ts_payment_bank_required_fields', array( 'name', 'acc_name', 'acc_number' ) );

			$bank_fields = array(
				'value'  => '_',
				'type'   => 'bank',
				'label'  => $label,
				'status' => $status,
			);

			foreach ( $_POST as $key => $value ) {

				if ( in_array( $key, array( 'action', 'security', 'type', 'payout_id', 'payout_label', 'payout_status' ), true ) ) {
					continue;
				}

				$bank_key = str_replace( 'bank_', '', $key );

				if ( ! isset( $bank_field_list[ $bank_key ] ) ) {
					continue;
				}

				if ( in_array( $bank_key, $bank_required_fields, true ) && empty( $value ) ) {
					wp_send_json_error( array( 'message' => esc_html__( 'Required fields could not be empty.', 'gigneo' ) ), 403 );
				}

				$bank_fields[ $key ] = sanitize_text_field( wp_unslash( $value ) );
			}

			if ( '' !== $id && isset( $payouts[ $id ] ) ) {
				$payouts[ $id ] = $bank_fields;
			} else {
				array_unshift( $payouts, $bank_fields );
			}

			update_post_meta( $profile_id, '_gigneo_pm_payouts', $payouts );

			ob_start();
			gigneo_load_template( 'dashboard/setting/parts/billing/payouts' );
			$payouts_markup                = ob_get_clean();
			$response['markup']['payouts'] = $payouts_markup;

			wp_send_json_success( $response, 200 );
		}

		//Custom Payouts
		$custom_payouts_saved = apply_filters( 'gigneo_save_custom_payout_settings', false, $type, $id, $label, $status, $profile_id, $payouts );
		if ( $custom_payouts_saved ) {
			ob_start();
			gigneo_load_template( 'dashboard/setting/parts/billing/payouts' );
			$payouts_markup                = ob_get_clean();
			$response['markup']['payouts'] = $payouts_markup;

			wp_send_json_success( $response, 200 );
		}

		wp_send_json_error( array( 'message' => esc_html__( 'Something went wrong.', 'gigneo' ) ), 400 );
	}

	/**
	 * Handle AJAX request for deleting a payout method.
	 *
	 * Validates the nonce and current user's permission, parses serialized form
	 * data from the request POST body, removes the specified payout method from the
	 * profile meta (`_gigneo_pm_payouts`), updates the stored payouts, reloads the
	 * payouts markup and returns a JSON success or error response.
	 *
	 * @since 0.0.1
	 * @return void
	 */
	public function delete_payout_method() {

		// Check if nonce is valid
		$security = isset( $_POST['security'] ) ? sanitize_text_field( wp_unslash( $_POST['security'] ) ) : '';
		if ( empty( $security ) || ! wp_verify_nonce( $security, 'gigneo_security' ) ) {
			wp_send_json_error( array( 'message' => esc_html__( 'Security verification failed. Please reload and try again.', 'gigneo' ) ), 403 );
		}

		$platform_access = gigneo_user_have_access();
		$profile_id      = gigneo_active_profile_id();
		$current_user    = wp_get_current_user();

		if ( empty( $current_user->ID ) || ! $platform_access || empty( $profile_id ) ) {
			wp_send_json_error( array( 'message' => esc_html__( 'You do not have permission to do that.', 'gigneo' ) ), 403 );
		}

		if ( ! isset( $_POST['id'] ) ) {
			wp_send_json_error( array( 'message' => esc_html__( 'Something went wrong.', 'gigneo' ) ), 400 );
		}

		$id      = isset( $_POST['id'] ) ? sanitize_text_field( wp_unslash( $_POST['id'] ) ) : '';
		$payouts = gigneo_post_meta( $profile_id, '_gigneo_pm_payouts' );

		if ( isset( $payouts[ $id ] ) ) {
			$response            = array();
			$response['message'] = __( 'Payout method removed successfully.', 'gigneo' );

			unset( $payouts[ $id ] );

			update_post_meta( $profile_id, '_gigneo_pm_payouts', $payouts );

			ob_start();
			gigneo_load_template( 'dashboard/setting/parts/billing/payouts' );
			$payouts_markup                = ob_get_clean();
			$response['markup']['payouts'] = $payouts_markup;

			wp_send_json_success( $response, 200 );
		}

		wp_send_json_error( array( 'message' => esc_html__( 'Something went wrong.', 'gigneo' ) ), 400 );
	}

	/**
	 * Remove the default quick edit and edit gigneo_withdrawal edit screen.
	 *
	 */
	public function remove_quick_edit_and_edit_links( $actions, $post ) {
		// Only target your custom post type
		if ( 'gigneo_withdrawal' === $post->post_type ) {
			unset( $actions['edit'] );
			unset( $actions['inline hide-if-no-js'] );
			unset( $actions['view'] );
		}
		return $actions;
	}



	/**
	 * withdrawal action
	 *
	 *
	 * @throws Exception
	 * @since 0.0.1
	 */
	public function withdrawal_action() {

		// Check if nonce is valid
		$security = isset( $_POST['security'] ) ? sanitize_text_field( wp_unslash( $_POST['security'] ) ) : '';
		if ( empty( $security ) || ! wp_verify_nonce( $security, 'gigneo_security' ) ) {
			wp_send_json_error( array( 'message' => esc_html__( 'Security verification failed. Please reload and try again.', 'gigneo' ) ), 403 );
		}

		if ( ! current_user_can( 'manage_options' ) ) {
			wp_send_json_error( array( 'message' => esc_html__( 'You do not have permission to perform this action.', 'gigneo' ) ), 403 );
		}

		$withdrawal_action = ! empty( $_POST['withdrawal_action'] ) ? sanitize_text_field( wp_unslash( $_POST['withdrawal_action'] ) ) : '';
		$withdrawal_note   = ! empty( $_POST['withdrawal_note'] ) ? sanitize_text_field( wp_unslash( $_POST['withdrawal_note'] ) ) : '';
		$withdrawal_id     = ! empty( $_POST['withdrawal_id'] ) ? absint( $_POST['withdrawal_id'] ) : 0;

		$current_status = get_post_status( $withdrawal_id );

		if ( 'publish' === $current_status && 'publish' === $withdrawal_action ) {
			wp_send_json_error( array( 'message' => __( 'Withdrawal request already in pending', 'gigneo' ) ), 403 );
		}

		if ( ! $withdrawal_id ) {
			wp_send_json_error( array( 'message' => __( 'Invalid withdrawal ID.', 'gigneo' ) ), 403 );
		}

		if ( ! in_array( $withdrawal_action, array( 'on-hold', 'in-progress', 'completed', 'rejected' ), true ) ) {
			wp_send_json_error( array( 'message' => __( 'You do not have permission to perform this action.', 'gigneo' ) ), 403 );
		}

		$withdrawal_subtotal = gigneo_post_meta( $withdrawal_id, '_gigneo_pm_subtotal' );
		$withdrawal_total    = gigneo_post_meta( $withdrawal_id, '_gigneo_pm_total' );
		$profile_id          = gigneo_post_meta( $withdrawal_id, '_gigneo_pm_profile_id' );
		$post_author_id      = get_post_field( 'post_author', $profile_id );

		if ( empty( $profile_id ) || empty( $post_author_id ) || empty( $withdrawal_subtotal ) || empty( $withdrawal_total ) ) {
			wp_send_json_error( array( 'message' => esc_html__( 'Something went wrong.', 'gigneo' ) ), 400 );
		}

		if ( $withdrawal_action !== $current_status ) {

			if ( 'completed' === $withdrawal_action ) {

				$withdrawal_product_id = gigneo_option( '_gigneo_ts_withdrawal_product' );
				$withdrawal_product    = ! empty( $withdrawal_product_id ) ? wc_get_product( $withdrawal_product_id ) : false;

				if ( ! $withdrawal_product ) {
					wp_send_json_error( array( 'message' => esc_html__( 'The wallet product is not configured correctly.', 'gigneo' ) ), 403 );
				}

				$customer = new WC_Customer( $post_author_id );

				$first_name = $customer->get_billing_first_name() ?? '';
				$last_name  = $customer->get_billing_last_name() ?? '';
				$country    = $customer->get_billing_country() ?? '';
				$state      = $customer->get_billing_state() ?? '';
				$postcode   = $customer->get_billing_postcode() ?? '';
				$city       = $customer->get_billing_city() ?? '';

				if ( empty( $country ) || empty( $state ) || empty( $postcode ) || empty( $city ) ) {
					wp_send_json_error( array( 'message' => esc_html__( 'User billing information is not setup.', 'gigneo' ) ), 400 );
				}

				$order = wc_create_order();

				// Add product with positive subtotal for tax calculation
				$order->add_product(
					$withdrawal_product,
					1,
					array(
						'subtotal' => $withdrawal_subtotal,
						'total'    => $withdrawal_subtotal,
					)
				);

				$order->set_customer_id( $post_author_id );
				$order->set_billing_first_name( $first_name );
				$order->set_billing_last_name( $last_name );
				$order->set_billing_country( $country );
				$order->set_billing_state( $state );
				$order->set_billing_postcode( $postcode );
				$order->set_billing_city( $city );
				$order->calculate_taxes();
				$order->calculate_totals( false );

				$tax        = $order->get_total_tax(); // positive tax
				$net_payout = $withdrawal_subtotal - $tax; // subtract tax from payout

				// Set order total as negative (payout)
				$order->set_total( - $net_payout );

				// Keep tax positive in reports/meta
				$order->set_cart_tax( $tax );

				$order->update_status( 'completed', esc_html__( 'Order auto-completed by wallet withdrawal process.', 'gigneo' ) );
				$order->save();
				$total_tax = $order->get_total_tax();
				//Create Invoice for Order
				$withdrawal_invoice_args = array(
					'post_type'   => 'gigneo_invoice',
					'post_title'  => sprintf(
						// translators: %s is Withdrawal ID
						esc_html__( 'Withdrawal — %s', 'gigneo' ),
						esc_html( gigneo_format_id( $withdrawal_id, 'withdraw', false ) )
					),
					'post_status' => 'withdrawn',
					'post_author' => $post_author_id,
				);

				$withdrawal_invoice_id = wp_insert_post( $withdrawal_invoice_args );

				if ( is_wp_error( $withdrawal_invoice_id ) ) {
					wp_send_json_error( array( 'message' => esc_html__( 'Something went wrong.', 'gigneo' ) ), 400 );
				}

				update_post_meta( $withdrawal_id, '_gigneo_pm_invoice_id', $withdrawal_invoice_id );
				update_post_meta( $withdrawal_id, '_gigneo_pm_order_id', $order->get_id() );

				update_post_meta( $withdrawal_invoice_id, '_gigneo_pm_order_id', $order->get_id() );
				update_post_meta( $withdrawal_invoice_id, '_gigneo_pm_type', 'withdraw' );
				update_post_meta( $withdrawal_invoice_id, '_gigneo_pm_profile_id', $profile_id );
				update_post_meta( $withdrawal_invoice_id, '_gigneo_pm_withdraw_id', $withdrawal_id );
				update_post_meta( $withdrawal_invoice_id, '_gigneo_pm_total', - $withdrawal_subtotal );
				update_post_meta( $withdrawal_invoice_id, '_gigneo_pm_tax', $total_tax );

				//Commission
				$commission       = gigneo_post_meta( $withdrawal_id, '_gigneo_pm_commission' );
				$commission_total = isset( $commission['total'] ) ? floatval( $commission['total'] ) : 0;

				if ( ! empty( $commission_total ) ) {
					$commission_invoice_args = array(
						'post_type'   => 'gigneo_invoice',
						'post_title'  => sprintf(
						// translators: %s is Withdrawal ID
							esc_html__( 'Withdrawal commission — %s', 'gigneo' ),
							esc_html( gigneo_format_id( $withdrawal_id, 'withdraw_commission', false ) )
						),
						'post_status' => 'paid',
						'post_author' => $post_author_id,
					);

					$commission_invoice_id = wp_insert_post( $commission_invoice_args );

					if ( is_wp_error( $commission_invoice_id ) ) {
						wp_send_json_error( array( 'message' => esc_html__( 'Something went wrong.', 'gigneo' ) ), 400 );
					}

					update_post_meta( $withdrawal_id, '_gigneo_pm_commission_invoice_id', $commission_invoice_id );

					update_post_meta( $commission_invoice_id, '_gigneo_pm_type', 'withdraw_commission' );
					update_post_meta( $commission_invoice_id, '_gigneo_pm_profile_id', $profile_id );
					update_post_meta( $commission_invoice_id, '_gigneo_pm_withdraw_id', $withdrawal_id );
					update_post_meta( $commission_invoice_id, '_gigneo_pm_total', - floatval( $commission_total ) );
				}
			}

			// Update note
			update_post_meta( $withdrawal_id, '_gigneo_pm_withdrawal_note', $withdrawal_note );

			$notification_info = array(
				'on-hold'     => array(
					'title'   => esc_html__( 'Withdrawal on hold', 'gigneo' ),
					'content' => sprintf(
						// translators: %s: Withdrawal ID.
						esc_html__( 'Withdrawal request %s is currently on hold for further review.', 'gigneo' ),
						gigneo_format_id( $withdrawal_id, 'withdraw', false )
					),
				),
				'in-progress' => array(
					'title'   => esc_html__( 'Withdrawal processing', 'gigneo' ),
					'content' => sprintf(
						// translators: %s: Withdrawal ID
						esc_html__( 'Withdrawal request %s is now being in processing.', 'gigneo' ),
						gigneo_format_id( $withdrawal_id, 'withdraw', false )
					),
				),
				'approved'    => array(
					'title'   => esc_html__( 'Withdrawal approved', 'gigneo' ),
					'content' => sprintf(
						// translators: %s: Withdrawal ID
						esc_html__( 'Withdrawal request %s has been approved and funds have been transferred.', 'gigneo' ),
						gigneo_format_id( $withdrawal_id, 'withdraw', false )
					),
				),
				'rejected'    => array(
					'title'   => esc_html__( 'Withdrawal rejected', 'gigneo' ),
					'content' => sprintf(
						// translators: %s: Withdrawal ID
						esc_html__( 'Withdrawal request %s has been rejected. Please review the details.', 'gigneo' ),
						gigneo_format_id( $withdrawal_id, 'withdraw', false )
					),
				),
			);

			$notification_title   = $notification_info[ $withdrawal_action ]['title'] ?? '';
			$notification_content = $notification_info[ $withdrawal_action ]['content'] ?? '';

			wp_update_post(
				array(
					'ID'          => $withdrawal_id,
					'post_status' => $withdrawal_action,
				)
			);

			if ( ! empty( $notification_title ) && ! empty( $notification_content ) ) {
				Notifications::trigger_notification( $notification_title, $notification_content, 'wallet', 'withdrawal-' . $withdrawal_action, $profile_id, $withdrawal_id );
			}

			// Trigger Email.
			$wc_mailer = WC()->mailer();
			$wc_emails = $wc_mailer->get_emails();

			if ( isset( $wc_emails['Gigneo_Withdraw_Response'] ) ) {
				$wc_emails['Gigneo_Withdraw_Response']->trigger( $profile_id, $withdrawal_id );
			}
		}

		wp_send_json_success( array( 'message' => __( 'Withdrawal updated successfully.', 'gigneo' ) ) );
	}

	/**
	 * Define custom withdrawal admin columns.
	 * @since 0.0.1
	 */
	public function define_custom_columns( array $columns ): array {

		$columns = array(
			'cb'                        => $columns['cb'],
			'gigneo_withdrawal_no'      => __( 'Withdrawal No', 'gigneo' ),
			'gigneo_withdrawal_amount'  => __( 'Amount', 'gigneo' ),
			'gigneo_withdrawal_method'  => __( 'Method', 'gigneo' ),
			'gigneo_withdrawal_profile' => __( 'Profile', 'gigneo' ),
			'gigneo_withdrawal_status'  => __( 'Status', 'gigneo' ),
			'gigneo_withdrawal_actions' => __( 'Actions', 'gigneo' ),
			'date'                      => __( 'Date', 'gigneo' ),
		);

		unset( $columns['title'] );

		return $columns;
	}


	/**
	 * Render withdrawal columns.
	 * @since 0.0.1
	 */
	public function render_column_content( $column_name, $post_id ) {

		if ( ! $post_id ) {
			return;
		}

		switch ( $column_name ) {

			/**
			 * Withdrawal ID
			 */
			case 'gigneo_withdrawal_no':
				$withdrawal_id = gigneo_format_id( $post_id, 'withdraw', false );
				printf(
					'<span class="gn-withdrawal-no">%s</span>',
					esc_html( $withdrawal_id )
				);
				break;

			/**
			 * Amount
			 */
			case 'gigneo_withdrawal_amount':
				$total = gigneo_post_meta( $post_id, '_gigneo_pm_total' );
				printf(
					'<span class="gn-withdrawal-amount">%s</span>',
					esc_html( gigneo_price_format( $total, true ) )
				);
				break;

			/**
			 * Method
			 */
			case 'gigneo_withdrawal_method':
				$method = get_post_meta( $post_id, '_gigneo_pm_payout', true );
				$label  = $method['title'] ?? __( 'Unknown', 'gigneo' );

				printf(
					'<span class="gn-withdrawal-payout">%s</span>',
					esc_html( $label )
				);
				break;

			/**
			 * Profile (User)
			 */
			case 'gigneo_withdrawal_profile':
				$profile_id   = gigneo_post_meta( $post_id, '_gigneo_pm_profile_id' );
				$profile_name = gigneo_profile_name( $profile_id );
				$profile_type = gigneo_profile_type( $profile_id );

				if ( ! $profile_id || ! $profile_name ) {
					echo '<span class="na">&mdash;</span>';
					break;
				}

				$url = add_query_arg(
					array(
						's'         => $profile_id,
						'post_type' => 'gigneo_' . $profile_type,
					),
					admin_url( 'edit.php' )
				);

				$role_label = ( 'freelancer' === $profile_type ) ? gigneo_freelancer_singular() : gigneo_employer_singular();

				$html = '<a class="gn-profile gn-link" href="' . esc_url( $url ) . '">' . esc_html( $profile_name ) . '</a><br><span class="gn-type">' . esc_html( $role_label ) . '</span>';
				echo wp_kses_post( $html );

				break;

			/**
			 * Status Tag
			 */
			case 'gigneo_withdrawal_status':
				$status       = get_post_status( $post_id );
				$status       = ( 'publish' === $status ) ? 'pending' : $status;
				$status_class = gigneo_status_class( $status );
				$label        = gigneo_status_label( $status );
				printf(
					'<span class="gn-withdrawal-status gn-status-tag %s">%s</span>',
					esc_attr( $status_class ),
					esc_html( $label )
				);
				break;

			/**
			 * Actions (modal button)
			 */
			case 'gigneo_withdrawal_actions':
				$status = get_post_status( $post_id );
				$icons  = array(
					'completed'   => __( 'Completed', 'gigneo' ),
					'publish'     => __( 'Pending', 'gigneo' ),
					'on-hold'     => __( 'On Hold', 'gigneo' ),
					'rejected'    => __( 'Rejected', 'gigneo' ),
					'in-progress' => __( 'In Progress', 'gigneo' ),
				);

				$tooltip  = $icons[ $status ] ?? __( 'Pending', 'gigneo' );
				$icon_url = GIGNEO_DIR_URL . "assets/img/icon/withdraw-$status.png";
				?>

				<span class="gn-withdrawal-action">
				<button type="button"
						class="gn-withdrawal-details"
						data-gn-modal-toggle="gn-withdraw-detail-modal-<?php echo esc_attr( $post_id ); ?>"
						data-gn-tooltip="<?php echo esc_attr( $tooltip ); ?>">
					<img src="<?php echo esc_url( $icon_url ); ?>"
						alt="<?php esc_html_e( 'View details', 'gigneo' ); ?>">
				</button>
			</span>

				<?php
				// Load the detail modal template.
				gigneo_load_template(
					'admin/parts/withdrawal/request-detail.php',
					false,
					array( 'p_id' => $post_id )
				);
				break;
		}
	}
}
