<?php

namespace AffiliateWP\Core\Payouts\Methods\StoreCredit;

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

/**
 * Registers `store_credit` as a first-class payout method when Store Credit is globally
 * enabled. Prior to 2.33.0 Store Credit was modelled as an "overlay" that fired on any
 * paid referral rather than as a selectable method; the per-affiliate payout method
 * model requires it to appear in the canonical list so affiliates can pick it and the
 * UI can render its label.
 *
 * @since 2.33.0
 *
 * @param array $methods Existing `key => label` map.
 * @return array
 */
function register_store_credit_payout_method( $methods ) {
	if ( ! affiliate_wp()->settings->get( 'store-credit' ) ) {
		return $methods;
	}

	if ( ! isset( $methods['store_credit'] ) ) {
		$methods['store_credit'] = __( 'Store Credit', 'affiliate-wp' );
	}

	return $methods;
}
add_filter( 'affwp_payout_methods', __NAMESPACE__ . '\\register_store_credit_payout_method' );

/**
 * Whether an e-commerce platform that can back Store Credit is active and integrated.
 *
 * Mirrors the requirement gate in the Store Credit settings panel: WooCommerce or EDD must be
 * both active AND enabled as an AffiliateWP integration. Unlike
 * affiliatewp_store_credit_get_active_integration(), this does not depend on Store Credit's own
 * integration classes (which only load once Store Credit is enabled), so it can answer "could
 * Store Credit be turned on here?" while the method is still disabled.
 *
 * @since 2.33.0
 *
 * @return bool
 */
function affiliatewp_store_credit_payouts_available() : bool {
	$enabled = array_keys( affiliate_wp()->integrations->get_enabled_integrations() );

	$woo = class_exists( 'WooCommerce' ) && in_array( 'woocommerce', $enabled, true );
	$edd = class_exists( 'Easy_Digital_Downloads' ) && in_array( 'edd', $enabled, true );

	return $woo || $edd;
}

/**
 * Advertises Store Credit as an "available, not enabled" rail on admin payout surfaces.
 *
 * Store Credit doesn't register on `affwp_payout_methods` while its setting is off, so the
 * default disabled-method scan can't see it. Surface it here, but only when WooCommerce or EDD
 * is active to back it — advertising a method that can't function without first installing a
 * platform would be a dead end.
 *
 * @since 2.33.0
 *
 * @param array<string,string> $methods Disabled method key => label.
 * @return array<string,string>
 */
function advertise_store_credit_when_disabled( $methods ) {
	if ( affiliate_wp()->settings->get( 'store-credit' ) ) {
		return $methods;
	}

	if ( ! affiliatewp_store_credit_payouts_available() ) {
		return $methods;
	}

	$methods['store_credit'] = __( 'Store Credit', 'affiliate-wp' );

	return $methods;
}
add_filter( 'affwp_disabled_payout_methods_for_display', __NAMESPACE__ . '\\advertise_store_credit_when_disabled' );

/**
 * Get the affiliate's WooCommerce store credit balance.
 *
 * @access public
 * @since 2.1.0
 * @since 2.6.0 Added `$formatted` parameter so you can remove formatting if needed.
 *
 * @param array $args      Arguments.
 * @param bool  $formatted Set to `true` to return formatted.
 *
 * @return string $current_balance The affiliate's current store credit balance.
 */
function affwp_store_credit_balance( $args = [], bool $formatted = true ) {

	// Get the User ID.
	$user_id = isset( $args['user_id'] )

		// Use the User ID passed by the user.
		? intval( $args['user_id'] )

		// Fallback to the Affiliate ID.
		: affwp_get_affiliate_user_id(
			! empty( $args['affiliate_id'] )
				? $args['affiliate_id']
				: affwp_get_affiliate_id()
		);

	$integration = affiliatewp_store_credit_get_active_integration();

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

	switch ( $integration ) {

		case 'woocommerce':
			$current_balance = get_user_meta( $user_id, 'affwp_wc_credit_balance', true );
			break;

		case 'edd':
			$current_balance = \edd_wallet()->wallet->balance( $user_id );
			break;
	}

	$current_balance = $formatted
		? \affwp_currency_filter( \affwp_format_amount( $current_balance ) )
		: floatval( $current_balance );

	return $current_balance;
}

/**
 * Get the Active Integration
 *
 * Prioritizes WooCommerce over EDD.
 *
 * @since 2.29.0
 *
 * @return string Empty if none.
 */
function affiliatewp_store_credit_get_active_integration() : string {

	$enabled_integrations = array_keys( affiliate_wp()->integrations->get_enabled_integrations() );

	if (
		// Check for both namespaced (core) and non-namespaced (addon) versions
		( class_exists( 'AffiliateWP\Core\Payouts\Methods\StoreCredit\AffiliateWP_Store_Credit_WooCommerce' )
			|| class_exists( 'AffiliateWP_Store_Credit_WooCommerce' ) )

			// And they actually enabled the WooCommerce integration.
			&& in_array( 'woocommerce', $enabled_integrations, true )
	) {
		return 'woocommerce';
	} elseif (
		// Check for both namespaced (core) and non-namespaced (addon) versions
		( class_exists( 'AffiliateWP\Core\Payouts\Methods\StoreCredit\AffiliateWP_Store_Credit_EDD' )
			|| class_exists( 'AffiliateWP_Store_Credit_EDD' ) )
			&& class_exists( 'EDD_Wallet' )

			// And they actually enabled the EDD integration.
			&& in_array( 'edd', $enabled_integrations, true )
	) {
		return 'edd';
	}

	return '';
}


/**
 * Get Store Credit settings for the payouts tab.
 *
 * @since 2.29.0
 *
 * @return array Settings array.
 */
function affwp_store_credit_get_settings() {
	$settings = [
		'store-credit' => [
			'name' => __( 'Enable Store Credit', 'affiliate-wp' ),
			'desc' => __( 'Check this box to enable store credit for referrals.', 'affiliate-wp' ),
			'type' => 'checkbox',
		],
	];

	// Add WooCommerce Subscriptions setting if available
	if ( class_exists( 'WC_Subscriptions' ) ) {
		$settings['store-credit-woocommerce-subscriptions'] = [
			'name' => __( 'Apply Store Credit To WooCommerce Subscriptions Renewal Orders', 'affiliate-wp' ),
			'desc' => __( 'Check this box to automatically apply the affiliate store credit to WooCommerce Subscriptions renewal orders.', 'affiliate-wp' ),
			'type' => 'checkbox',
		];
	}

	return $settings;
}
