<?php

namespace Gigneo;

use Dompdf\Dompdf;
use Dompdf\Options;

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

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


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

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

		return self::$instance;
	}

	/**
	 * Constructor for the class.
	 *
	 * @since 0.0.1
	 */
	public function __construct() {

		//Register invoice style
		add_action( 'init', array( $this, 'register_invoice_style' ) );

		// Remove quick edit and edit links from gigneo_invoice post type
		add_filter( 'post_row_actions', array( $this, 'remove_quick_edit_and_edit_links' ), 10, 2 );
		// Output content for invoice pdf.
		add_filter( 'manage_gigneo_invoice_posts_columns', array( $this, 'define_custom_columns' ), 20 );
		// Output content for custom withdrawal columns.
		add_action( 'manage_gigneo_invoice_posts_custom_column', array( $this, 'render_column_content' ), 10, 2 );
	}

	public function register_invoice_style() {
		wp_register_style(
			'gigneo-invoice-style',
			GIGNEO_DIR_URL . 'assets/dashboard/css/invoice.css',
			array(),
			GIGNEO_VERSION
		);
	}

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

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

		$columns = array(
			'cb'                     => $columns['cb'],
			'title'                  => $columns['title'],
			'gigneo_invoice_no'      => esc_html__( 'Invoice No', 'gigneo' ),
			'gigneo_invoice_type'    => esc_html__( 'Invoice Type', 'gigneo' ),
			'gigneo_invoice_amount'  => esc_html__( 'Credit / Amount', 'gigneo' ),
			'gigneo_invoice_profile' => esc_html__( 'Profile', 'gigneo' ),
			'gigneo_invoice_status'  => esc_html__( 'Status', 'gigneo' ),
			'gigneo_invoice_actions' => esc_html__( 'Action', 'gigneo' ),
			'date'                   => esc_html__( 'Date', 'gigneo' ),
		);

		return $columns;
	}


	/**
	 * Render invoice column content.
	 *
	 * @since 0.0.1
	 */
	public function render_column_content( $column_name, $post_id ) {

		if ( ! $post_id ) {
			return;
		}

		switch ( $column_name ) {

			/**
			 * Invoice No
			 */
			case 'gigneo_invoice_no':
				$invoice_id = gigneo_format_id( $post_id, 'invoice', false );
				printf(
					'<span class="gn-invoice-no">%s</span>',
					esc_html( $invoice_id )
				);
				break;

			/**
			 * Invoice Type
			 */
			case 'gigneo_invoice_type':
				$profile_id     = gigneo_post_meta( $post_id, '_gigneo_pm_profile_id' );
				$profile_type   = gigneo_profile_type( $profile_id );
				$invoice_type   = gigneo_post_meta( $post_id, '_gigneo_pm_type' );
				$invoice_amount = gigneo_post_meta( $post_id, '_gigneo_pm_credit' );
				// Handle credit type
				if ( 'credit' === $invoice_type ) {
					$invoice_type = $invoice_amount > 0 ? esc_html( 'credit_purchased' ) : esc_html( 'credit_spent' );
				}
				// If commission type, choose freelancer or employer version
				if ( 'service_commission' === $invoice_type ) {
					$invoice_type = ( 'freelancer' === $profile_type ) ? esc_html( 'freelancer_fee' ) : esc_html( 'employer_fee' );
				}
				$invoice_label = gigneo_invoice_label( $invoice_type );
				printf(
					'<span class="gn-invoice-type">%s</span>',
					esc_html( $invoice_label )
				);
				break;

			/**
			 * Invoice Amount / Credits
			 */
			case 'gigneo_invoice_amount':
				$total_amount  = abs( (float) gigneo_post_meta( $post_id, '_gigneo_pm_total' ) );
				$total_credits = gigneo_post_meta( $post_id, '_gigneo_pm_credit' );
				$wallet_type   = gigneo_post_meta( $post_id, '_gigneo_pm_type' );

				$dir_class = $total_amount > 0 ? 'gn-up' : 'gn-down';

				echo '<span class="gn-invoice-amount ' . esc_attr( $dir_class ) . '">';
				if ( in_array( $wallet_type, array( 'bulk_credit', 'credit', 'service_creation', 'job_creation', 'proposal_submission', 'monthly_credit', 'credit_plan' ), true ) ) {
					echo esc_html( $total_credits );

					if ( $total_amount ) {
						echo ' / ' . esc_html( gigneo_price_format( $total_amount, true ) );
					}
				} else {
					echo esc_html( gigneo_price_format( $total_amount, true, true ) );
				}

				echo '</span>';
				break;

			/**
			 * Profile (Buyer/Freelancer)
			 */
			case 'gigneo_invoice_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-invoice-profile" href="' . esc_url( $url ) . '">' . esc_html( $profile_name ) . '</a><br><span class="gn-profile-type">' . esc_html( $role_label ) . '</span>';

				echo wp_kses_post( $html );

				break;

			/**
			 * Status Tag
			 */
			case 'gigneo_invoice_status':
				$status         = get_post_status( $post_id );
				$invoice_class  = gigneo_status_class( $status );
				$invoice_status = gigneo_status_label( $status );

				printf(
					'<span class="gn-invoice-status gn-status-tag %s">%s</span>',
					esc_attr( $invoice_class ),
					esc_html( $invoice_status )
				);
				break;

			/**
			 * Download Action Button
			 */
			case 'gigneo_invoice_actions':
				$invoice_amount = gigneo_post_meta( $post_id, '_gigneo_pm_total' );
				if ( ! $invoice_amount ) {
					break;
				}
				?>
				<span class="gn-invoice-action">
					<button type="button" class="gn-invoice-download gn-btn gn-btn-sm gn-btn-outline-grey" data-gn-invoice-id="<?php echo esc_attr( $post_id ); ?>">
						<i class="hi hi-arrow-down-tray" aria-hidden="true"></i>
					</button>
				</span>
				<?php
				break;
		}
	}


	/**
	 * Output content for invoice pdf.
	 *
	 * @param int $invoice_id The post ID.
	 * @param bool $markup Whether to return HTML markup instead of PDF.
	 * @since 0.0.1
	 */

	public static function generate_pdf( $invoice_id, $markup = false ) {

		if ( empty( $invoice_id ) ) {
			return false;
		}

		$type       = gigneo_post_meta( $invoice_id, '_gigneo_pm_type' );
		$profile_id = gigneo_post_meta( $invoice_id, '_gigneo_pm_profile_id' );
		$order_id   = gigneo_post_meta( $invoice_id, '_gigneo_pm_order_id' );

		$data = array();

		if ( 'service_order' === $type ) {
			$data = self::service_order_invoice_data( $invoice_id, $order_id, $profile_id );
		} elseif ( 'service_commission' === $type ) {
			$data = self::service_commission_invoice_data( $invoice_id, $order_id, $profile_id );
		} elseif ( 'wallet' === $type ) {
			$data = self::wallet_funds_invoice_data( $invoice_id, $profile_id );
		} elseif ( 'credit' === $type ) {
			$data = self::credit_funds_invoice_data( $invoice_id, $profile_id );
		} elseif ( 'bulk_wallet' === $type ) {
			$data = self::bulk_wallet_funds_invoice_data( $invoice_id, $profile_id );
		} elseif ( 'withdraw' === $type ) {
			$data = self::withdraw_invoice_data( $invoice_id, $profile_id );
		} elseif ( 'withdraw_commission' === $type ) {
			$data = self::withdraw_commission_invoice_data( $invoice_id, $profile_id );
		} elseif ( 'job_order' === $type ) {
			$data = self::job_order_invoice_data( $invoice_id, $order_id, $profile_id );
		} elseif ( 'job_commission' === $type ) {
			$data = self::job_commission_invoice_data( $invoice_id, $order_id, $profile_id );
		}
		$data = apply_filters( 'gigneo_invoice_data_after', $data, $type, $invoice_id, $profile_id );

		if ( empty( $data ) ) {
			return false;
		}

		// Load your custom invoice template (HTML + inline CSS)
		ob_start();
		gigneo_load_template( 'invoice/general', true, array( 'data' => $data ) );
		$html = ob_get_clean();

		if ( $markup ) {
			echo wp_kses_post( $html );
			return false;
		}

		// Generate PDF
		$options = new Options();
		$options->set( 'isRemoteEnabled', true );
		$options->set( 'defaultFont', 'DejaVu Sans, Arial, sans-serif' );
		$dompdf = new Dompdf( $options );
		$dompdf->loadHtml( $html );
		$dompdf->setPaper( 'A4' );
		$dompdf->render();

		// Return PDF as base64
		$pdf = $dompdf->output();

		$invoice_pdf_id = gigneo_format_id( $invoice_id, 'invoice', false );

		$pdf_data = array(
			'file_data' => base64_encode( $pdf ), // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode -- Required to encode binary PDF for JSON/API response.
			'file_name' => "$invoice_pdf_id.pdf",
		);

		return apply_filters( 'gigneo_invoice_pdf', $pdf_data );
	}

	/**
	 * Output content for invoice pdf.
	 *
	 * @param int $invoice_id The post ID.
	 * @param int $order_id The order ID.
	 * @param int $profile_id The profile ID.
	 * @since 0.0.1
	 */

	public static function service_order_invoice_data( $invoice_id, $order_id, $profile_id ) {

		$profile_type = gigneo_profile_type( $profile_id );

		$service_title = gigneo_post_meta( $order_id, '_gigneo_pm_service_title' );
		$addons        = gigneo_post_meta( $order_id, '_gigneo_pm_addons' );
		$plan          = gigneo_post_meta( $order_id, '_gigneo_pm_price_plan' );

		if ( ! empty( $service_title ) && ! empty( $plan['title'] ) ) {
			$service_title .= ' - ' . $plan['title'];
		}

		$timezone       = wp_timezone_string();
		$invoice_status = get_post_status( $invoice_id );

		$subtotal_amount = $plan['price'];

		$data['invoice_id']     = gigneo_format_id( $invoice_id, 'invoice', false );
		$data['order_id']       = gigneo_format_id( $order_id, 'order', false );
		$data['issue_date']     = get_the_date( get_option( 'date_format' ), $invoice_id );
		$data['timezone']       = str_replace( '_', ' ', $timezone );
		$data['invoice_status'] = esc_html( $invoice_status );
		$data['type']           = esc_html( 'order' );

		$data['items'][] = array(
			'type'     => esc_html( 'plan' ),
			'quantity' => 1,
			'title'    => $service_title ?? esc_html__( 'Service', 'gigneo' ),
			'amount'   => gigneo_price_format( $plan['price'] ?? 0, true ),
			'total'    => gigneo_price_format( $plan['price'] ?? 0, true ),
		);

		//Addons
		if ( ! empty( $addons ) ) {
			foreach ( $addons as $addon ) {
				$addon_total      = ( $addon['price'] ?? 0 ) * ( $addon['quantity'] ?? 1 );
				$subtotal_amount += $addon_total;
				$data['items'][]  = array(
					'type'     => esc_html( 'addon' ),
					'quantity' => $addon['quantity'] ?? 1,
					'title'    => $addon['title'] ?? esc_html__( 'Addon', 'gigneo' ),
					'amount'   => gigneo_price_format( $addon['price'] ?? 0, true ),
					'total'    => gigneo_price_format( $addon_total ?? 0, true ),
				);
			}
		}

		//Travel Charges
		$order_location       = gigneo_post_meta( $order_id, '_gigneo_pm_location' );
		$total_travel_charges = isset( $order_location['total_travel_charges'] ) ? floatval( $order_location['total_travel_charges'] ) : 0;

		if ( ! empty( $total_travel_charges ) ) {
			$subtotal_amount += $total_travel_charges;
			$data['items'][]  = array(
				'type'     => esc_html( 'travel' ),
				'quantity' => 1,
				'title'    => esc_html__( 'Travel Charges', 'gigneo' ),
				'amount'   => gigneo_price_format( $total_travel_charges, true ),
				'total'    => gigneo_price_format( $total_travel_charges, true ),
			);
		}

		if ( 'freelancer' === $profile_type || 'refunded' === $invoice_status ) {
			$data['from'] = self::platform_invoice_info();
			$data['to']   = self::profile_invoice_info( $profile_id );
		} else {
			$data['from'] = self::profile_invoice_info( $profile_id );
			$data['to']   = self::platform_invoice_info();
		}

		$data['subtotal'] = gigneo_price_format( $subtotal_amount, true );

		$total_amount = $subtotal_amount;

		$data['total'] = gigneo_price_format( $total_amount, true );

		return apply_filters( 'gigneo_service_order_invoice_data', $data, $order_id );
	}

	/**
	 * Output content for invoice pdf.
	 *
	 * @param int $invoice_id The post ID.
	 * @param int $order_id The order ID.
	 * @param int $profile_id The profile ID.
	 * @since 0.0.1
	 */

	public static function service_commission_invoice_data( $invoice_id, $order_id, $profile_id ) {

		$total_amount = gigneo_post_meta( $invoice_id, '_gigneo_pm_total' );
		$total_amount = abs( $total_amount ) ?? 0;
		$fee_name     = gigneo_option( '_gigneo_ts_platform_fee_name', esc_html__( 'Platform fee', 'gigneo' ) );

		$timezone       = wp_timezone_string();
		$invoice_status = get_post_status( $invoice_id );

		$data['invoice_id']     = gigneo_format_id( $invoice_id, 'invoice', false );
		$data['order_id']       = gigneo_format_id( $order_id, 'order', false );
		$data['issue_date']     = get_the_date( get_option( 'date_format' ), $invoice_id );
		$data['timezone']       = str_replace( '_', ' ', $timezone );
		$data['invoice_status'] = esc_html( $invoice_status );
		$data['type']           = esc_html( 'commission' );

		$data['items'][] = array(
			'quantity' => 1,
			'title'    => $fee_name,
			'amount'   => gigneo_price_format( $total_amount, true ),
			'total'    => gigneo_price_format( $total_amount, true ),
		);
		if ( 'refunded' === $invoice_status ) {
			$data['from'] = self::platform_invoice_info();
			$data['to']   = self::profile_invoice_info( $profile_id );
		} else {
			$data['from'] = self::profile_invoice_info( $profile_id );
			$data['to']   = self::platform_invoice_info();
		}

		$data['subtotal'] = gigneo_price_format( $total_amount, true );
		$data['total']    = gigneo_price_format( $total_amount, true );

		return apply_filters( 'gigneo_service_commission_invoice_data', $data, $order_id );
	}

	/**
	 * Output content for invoice pdf.
	 *
	 * @return array
	 * @since 0.0.1
	 */

	public static function platform_invoice_info() {

		$platform_invoice_name          = gigneo_option( '_gigneo_ts_invoice_from_name', get_bloginfo( 'name' ) );
		$platform_invoice_country_state = gigneo_option( '_gigneo_ts_invoice_from_country_state' );
		$platform_invoice_country_state = ! empty( $platform_invoice_country_state ) && 'none' !== $platform_invoice_country_state ? $platform_invoice_country_state : '';
		$platform_invoice_address       = gigneo_option( '_gigneo_ts_invoice_from_address' );
		$platform_invoice_email         = gigneo_option( '_gigneo_ts_invoice_from_email' );
		$platform_invoice_phone         = gigneo_option( '_gigneo_ts_invoice_from_phone' );

		$platform_invoice_info = array(
			'name'          => esc_html( $platform_invoice_name ) ?? '',
			'country_state' => esc_html( $platform_invoice_country_state ) ?? '',
			'address'       => esc_html( $platform_invoice_address ) ?? '',
			'email'         => esc_html( $platform_invoice_email ) ?? '',
			'phone'         => esc_html( $platform_invoice_phone ) ?? '',
		);

		return apply_filters( 'gigneo_platform_invoice_info', $platform_invoice_info );
	}

	/**
	 * Output content for invoice pdf.
	 *
	 * @param int $profile_id The profile ID.
	 * @return array
	 * @since 0.0.1
	 */

	public static function profile_invoice_info( $profile_id ) {

		if ( empty( $profile_id ) ) {
			return array();
		}

		$profile_type = gigneo_profile_type( $profile_id );

		if ( 'freelancer' !== $profile_type && 'employer' !== $profile_type ) {
			return array();
		}

		$user_id   = get_post_field( 'post_author', $profile_id );
		$user_date = get_user_by( 'id', $user_id );

		//Profile Invoice info
		$profile_name          = gigneo_profile_name( $profile_id );
		$profile_country_state = gigneo_post_meta( $profile_id, '_gigneo_pm_country_state' );
		$profile_address       = gigneo_post_meta( $profile_id, '_gigneo_pm_address' );
		$profile_phone         = gigneo_post_meta( $profile_id, '_gigneo_pm_phone' );
		$profile_email         = $user_date->user_email ?? '';

		$profile_invoice_info = array(
			'name'          => $profile_name ?? '',
			'country_state' => $profile_country_state ?? '',
			'address'       => $profile_address ?? '',
			'email'         => $profile_email ?? '',
			'phone'         => $profile_phone ?? '',
		);

		return apply_filters( 'gigneo_profile_invoice_info', $profile_invoice_info, $profile_id );
	}

	/**
	 * Output content for invoice pdf.
	 *
	 * @param int $invoice_id The post ID.
	 * @param int $profile_id The profile ID.
	 * @since 0.0.1
	 */

	public static function wallet_funds_invoice_data( $invoice_id, $profile_id ) {

		$total_amount = gigneo_post_meta( $invoice_id, '_gigneo_pm_total' );
		$total_amount = abs( $total_amount ) ?? 0;

		$total_tax = gigneo_post_meta( $invoice_id, '_gigneo_pm_tax' );
		$total_tax = abs( $total_tax ) ?? 0;

		$total    = $total_tax + $total_amount;
		$timezone = wp_timezone_string();

		$data['invoice_id']     = gigneo_format_id( $invoice_id, 'invoice', false );
		$data['issue_date']     = get_the_date( get_option( 'date_format' ), $invoice_id );
		$data['invoice_status'] = get_post_status( $invoice_id );
		$data['timezone']       = str_replace( '_', ' ', $timezone );
		$data['type']           = esc_html( 'wallet' );

		$data['items'][] = array(
			'quantity' => 1,
			'title'    => esc_html__( 'Wallet Funds', 'gigneo' ),
			'amount'   => gigneo_price_format( $total_amount, true ),
			'total'    => gigneo_price_format( $total_amount, true ),
		);

		$data['to']   = self::platform_invoice_info();
		$data['from'] = self::profile_invoice_info( $profile_id );

		$data['subtotal'] = gigneo_price_format( $total_amount, true );
		$data['total']    = gigneo_price_format( $total, true );
		$order_id         = gigneo_post_meta( $invoice_id, '_gigneo_pm_order_id' );
		$data['tax']      = self::order_tax( $order_id );
		return apply_filters( 'gigneo_wallet_funds_invoice_data', $data, $invoice_id );
	}

	/**
	 * Output content for invoice pdf.
	 *
	 * @param int $invoice_id The post ID.
	 * @param int $profile_id The profile ID.
	 * @since 0.0.1
	 */

	public static function bulk_wallet_funds_invoice_data( $invoice_id, $profile_id ) {

		$total_amount = gigneo_post_meta( $invoice_id, '_gigneo_pm_total' );
		$invoice_type = $total_amount > 0 ? 'platform' : 'profile';
		$total_amount = abs( $total_amount ) ?? 0;

		$timezone       = wp_timezone_string();
		$moderator_name = gigneo_moderator_name();

		$data['invoice_id'] = gigneo_format_id( $invoice_id, 'invoice', false );
		$data['issue_date'] = get_the_date( get_option( 'date_format' ), $invoice_id );

		$data['timezone']       = str_replace( '_', ' ', $timezone );
		$data['invoice_status'] = get_post_status( $invoice_id );
		$data['type']           = esc_html( 'bulk_wallet' );

		$data['items'][] = array(
			'quantity' => 1,
			'title'    => sprintf(
			// translators: %1$s Moderator name %2$s Rewarded/Deducted
				esc_html__( '%1$s %2$s wallet funds', 'gigneo' ),
				esc_html( $moderator_name ),
				0 < $total_amount ? esc_html__( 'rewarded', 'gigneo' ) : esc_html__( 'deducted', 'gigneo' )
			),
			'amount'   => gigneo_price_format( $total_amount, true ),
			'total'    => gigneo_price_format( $total_amount, true ),
		);

		if ( 'platform' === $invoice_type ) {
			$data['to']   = self::platform_invoice_info();
			$data['from'] = self::profile_invoice_info( $profile_id );
		} else {
			$data['from'] = self::platform_invoice_info();
			$data['to']   = self::profile_invoice_info( $profile_id );
		}
		$data['subtotal'] = gigneo_price_format( $total_amount, true );
		$data['total']    = gigneo_price_format( $total_amount, true );

		return apply_filters( 'gigneo_bulk_wallet_funds_invoice_data', $data, $invoice_id );
	}

	/**
	 * Output content for invoice pdf.
	 *
	 * @param int $invoice_id The post ID.
	 * @param int $profile_id The profile ID.
	 * @since 0.0.1
	 */

	public static function credit_funds_invoice_data( $invoice_id, $profile_id ) {

		$total_amount = gigneo_post_meta( $invoice_id, '_gigneo_pm_total' );
		if ( ! $total_amount ) {
			return array();
		}
		$total_credit    = gigneo_post_meta( $invoice_id, '_gigneo_pm_credit' );
		$per_credit_rate = gigneo_option( '_gigneo_ts_credit_rate' );
		$timezone        = wp_timezone_string();

		$data['invoice_id'] = gigneo_format_id( $invoice_id, 'invoice', false );
		$data['issue_date'] = get_the_date( get_option( 'date_format' ), $invoice_id );

		$data['timezone']       = str_replace( '_', ' ', $timezone );
		$data['invoice_status'] = get_post_status( $invoice_id );
		$data['type']           = esc_html( 'credit' );

		$data['items'][] = array(
			'quantity' => esc_html( $total_credit ),
			'title'    => esc_html__( 'Credits Purchased', 'gigneo' ),
			'amount'   => gigneo_price_format( $per_credit_rate, true ), //Unit Price
			'total'    => gigneo_price_format( abs( $total_amount ), true ),
		);

		$data['to']       = self::platform_invoice_info();
		$data['from']     = self::profile_invoice_info( $profile_id );
		$data['subtotal'] = gigneo_price_format( abs( $total_amount ), true );
		$data['total']    = gigneo_price_format( abs( $total_amount ), true );

		return apply_filters( 'gigneo_wallet_funds_invoice_data', $data, $invoice_id );
	}


	/**
	 * Output content for withdraw invoice.
	 *
	 * @param int $invoice_id The post ID.
	 * @param int $profile_id The profile ID.
	 * @since 0.0.1
	 */

	public static function withdraw_invoice_data( $invoice_id, $profile_id ) {

		$order_id        = gigneo_post_meta( $invoice_id, '_gigneo_pm_order_id' );
		$withdrawal_id   = gigneo_post_meta( $invoice_id, '_gigneo_pm_withdraw_id' );
		$total_amount    = gigneo_post_meta( $invoice_id, '_gigneo_pm_total' );
		$subtotal_amount = gigneo_post_meta( $invoice_id, '_gigneo_pm_subtotal' );
		$total_amount    = abs( $total_amount ) ?? 0;

		$total_tax = gigneo_post_meta( $invoice_id, '_gigneo_pm_tax' );
		$total_tax = abs( $total_tax ) ?? 0;

		$total = $total_amount - $total_tax;

		$timezone = wp_timezone_string();

		$payout_details = gigneo_post_meta( $withdrawal_id, '_gigneo_pm_payout' );

		$data['invoice_id'] = gigneo_format_id( $invoice_id, 'invoice', false );
		$data['issue_date'] = get_the_date( get_option( 'date_format' ), $invoice_id );

		$data['timezone']       = str_replace( '_', ' ', $timezone );
		$data['invoice_status'] = get_post_status( $invoice_id );
		$data['type']           = 'commission';

		$invoice_title = esc_html__( 'Withdrawal', 'gigneo' );

		if ( ! empty( $payout_details['title'] ) ) {
			$invoice_title = sprintf(
			// translators: %s payout title
				esc_html__( 'Withdrawal - %s', 'gigneo' ),
				esc_html( $payout_details['title'] )
			);
		}

		$data['items'][] = array(
			'quantity' => 1,
			'title'    => $invoice_title,
			'subtotal' => gigneo_price_format( $subtotal_amount, true ),
			'amount'   => gigneo_price_format( $total_amount, true ),
			'total'    => gigneo_price_format( $total_amount, true ),
		);

		$data['tax']      = self::order_tax( $order_id, 'withdraw' );
		$data['from']     = self::platform_invoice_info();
		$data['to']       = self::profile_invoice_info( $profile_id );
		$data['subtotal'] = gigneo_price_format( $total_amount, true );
		$data['total']    = gigneo_price_format( $total, true );

		return apply_filters( 'gigneo_withdraw_invoice_data', $data, $invoice_id );
	}

	/**
	 * Output content for withdraw Commission invoice.
	 *
	 * @param int $invoice_id The post ID.
	 * @param int $profile_id The profile ID.
	 * @since 0.0.1
	 */

	public static function withdraw_commission_invoice_data( $invoice_id, $profile_id ) {

		$total_amount = gigneo_post_meta( $invoice_id, '_gigneo_pm_total' );
		$total_amount = abs( $total_amount ) ?? 0;
		$fee_name     = gigneo_option( '_gigneo_ts_separator_withdrawal_fee', esc_html__( 'Withdrawal fee', 'gigneo' ) );

		$timezone       = wp_timezone_string();
		$invoice_status = get_post_status( $invoice_id );

		$data['invoice_id']     = gigneo_format_id( $invoice_id, 'invoice', false );
		$data['issue_date']     = get_the_date( get_option( 'date_format' ), $invoice_id );
		$data['timezone']       = str_replace( '_', ' ', $timezone );
		$data['invoice_status'] = esc_html( $invoice_status );
		$data['type']           = esc_html( 'commission' );

		$data['items'][] = array(
			'quantity' => 1,
			'title'    => $fee_name,
			'amount'   => gigneo_price_format( $total_amount, true ),
			'total'    => gigneo_price_format( $total_amount, true ),
		);
		if ( 'refunded' === $invoice_status ) {
			$data['from'] = self::platform_invoice_info();
			$data['to']   = self::profile_invoice_info( $profile_id );
		} else {
			$data['from'] = self::profile_invoice_info( $profile_id );
			$data['to']   = self::platform_invoice_info();
		}

		$data['subtotal'] = gigneo_price_format( $total_amount, true );
		$data['total']    = gigneo_price_format( $total_amount, true );

		return apply_filters( 'gigneo_withdraw_commission_invoice_data', $data, $invoice_id );
	}

	/**
	 * Get the tax breakdown for a WooCommerce order.
	 *
	 * @param int    $order_id The order ID.
	 * @param string $type     Optional order type (e.g., 'withdraw' for payout/withdrawal orders).
	 *                         If 'withdraw', tax amounts will be returned as negative values.
	 * @return array Array of tax lines with label, amount, and formatted amount.
	 * @since 0.0.1
	 */
	public static function order_tax( $order_id, $type = '' ) {
		if ( empty( $order_id ) ) {
			return array();
		}

		$order = wc_get_order( $order_id );

		if ( ! $order ) {
			return array();
		}

		$tax_list = array();

		// Use get_tax_totals() for merged tax lines grouped by rate
		foreach ( $order->get_tax_totals() as $tax ) {
			$amount = (float) $tax->amount;

			// If this is a withdrawal/payout order, show tax as negative
			if ( 'withdraw' === $type ) {
				$amount = - $amount;
			}

			$tax_list[] = array(
				'label'            => $tax->label,              // e.g., "VAT", "GST"
				'amount'           => $amount,                  // Numeric tax amount (negative for withdraw)
				'formatted_amount' => gigneo_price_format( $amount, true ),      // Formatted with currency symbol and sign
			);
		}

		return $tax_list;
	}

	/**
	 * Get the job order invoice data.
	 *
	 * @param int $invoice_id The invoice ID.
	 * @param int $order_id The order ID.
	 * @param int $profile_id The profile ID.
	 * @since 0.0.1
	 */
	public static function job_order_invoice_data( $invoice_id, $order_id, $profile_id ) {
		$profile_type = gigneo_profile_type( $profile_id );

		$job_title = gigneo_post_meta( $order_id, '_gigneo_pm_job_title' );

		$timezone       = wp_timezone_string();
		$invoice_status = get_post_status( $invoice_id );

		$subtotal_amount = gigneo_post_meta( $order_id, '_gigneo_pm_subtotal' );

		$data['invoice_id']     = gigneo_format_id( $invoice_id, 'invoice', false );
		$data['order_id']       = gigneo_format_id( $order_id, 'order', false );
		$data['issue_date']     = get_the_date( get_option( 'date_format' ), $invoice_id );
		$data['timezone']       = str_replace( '_', ' ', $timezone );
		$data['invoice_status'] = esc_html( $invoice_status );
		$data['type']           = esc_html( 'order' );

		$data['items'][] = array(
			'type'     => esc_html( 'job' ),
			'quantity' => 1,
			'title'    => $job_title ?? esc_html__( 'Job', 'gigneo' ),
			'amount'   => gigneo_price_format( $subtotal_amount ?? 0, true ),
			'total'    => gigneo_price_format( $subtotal_amount ?? 0, true ),
		);

		if ( 'freelancer' === $profile_type || 'refunded' === $invoice_status ) {
			$data['from'] = self::platform_invoice_info();
			$data['to']   = self::profile_invoice_info( $profile_id );
		} else {
			$data['from'] = self::profile_invoice_info( $profile_id );
			$data['to']   = self::platform_invoice_info();
		}

		$data['subtotal'] = gigneo_price_format( $subtotal_amount, true );

		$total_amount = $subtotal_amount;

		$data['total'] = gigneo_price_format( $total_amount, true );

		return apply_filters( 'gigneo_job_order_invoice_data', $data, $order_id );
	}

	/**
	 * Get the job commission invoice data.
	 *
	 * @param int $invoice_id The invoice ID.
	 * @param int $order_id The order ID.
	 * @param int $profile_id The profile ID.
	 * @since 0.0.1
	 */
	public static function job_commission_invoice_data( $invoice_id, $order_id, $profile_id ) {

		$total_amount = gigneo_post_meta( $invoice_id, '_gigneo_pm_total' );
		$total_amount = abs( $total_amount ) ?? 0;

		$fee_name = gigneo_option( '_gigneo_ts_platform_fee_name', esc_html__( 'Platform fee', 'gigneo' ) );

		$timezone       = wp_timezone_string();
		$invoice_status = get_post_status( $invoice_id );

		$data['invoice_id']     = gigneo_format_id( $invoice_id, 'invoice', false );
		$data['order_id']       = gigneo_format_id( $order_id, 'order', false );
		$data['issue_date']     = get_the_date( get_option( 'date_format' ), $invoice_id );
		$data['timezone']       = str_replace( '_', ' ', $timezone );
		$data['invoice_status'] = esc_html( $invoice_status );
		$data['type']           = esc_html( 'commission' );

		$data['items'][] = array(
			'quantity' => 1,
			'title'    => $fee_name,
			'amount'   => gigneo_price_format( $total_amount, true ),
			'total'    => gigneo_price_format( $total_amount, true ),
		);

		if ( 'refunded' === $invoice_status ) {
			$data['from'] = self::platform_invoice_info();
			$data['to']   = self::profile_invoice_info( $profile_id );
		} else {
			$data['from'] = self::profile_invoice_info( $profile_id );
			$data['to']   = self::platform_invoice_info();
		}

		$data['subtotal'] = gigneo_price_format( $total_amount, true );
		$data['total']    = gigneo_price_format( $total_amount, true );

		return apply_filters( 'gigneo_job_commission_invoice_data', $data, $order_id );
	}
}
