<?php 

if ( !defined( 'ABSPATH' ) ) {
	exit();
}



// Get Coins List
// ======================================================

function cryptoniq_get_coins_list( $type = 'all' ) {
	$data = array(
		'BTC' => array(
			'name' => 'BTC',
			'chain' => 'bitcoin-mainnet',
			'decimal' => '8',
			'type' => 'coin'
		),
		'ETH' => array(
			'name' => 'ETH',
			'chain' => 'ethereum-mainnet',
			'decimal' => '8',
			'type' => 'coin'
		),
		'LTC' => array(
			'name' => 'LTC',
			'chain' => 'LTC',
			'decimal' => '8',
			'type' => 'coin'
		),
		'DOGE' => array(
			'name' => 'DOGE',
			'chain' => 'doge-mainnet',
			'decimal' => '8',
			'type' => 'coin'
		),
		'ETH_ARB' => array(
			'name' => 'Arbitrum One ETH',
			'chain' => 'arb-one-mainnet',
			'decimal' => '8',
			'type' => 'coin'
		),
		'ETH_OP' => array(
			'name' => 'Optimism ETH',
			'chain' => 'optimism-mainnet',
			'decimal' => '8',
			'type' => 'coin'
		),
		'BNB' => array(
			'name' => 'BNB',
			'chain' => 'bsc-mainnet',
			'decimal' => '8',
			'type' => 'coin'
		),
		'SOL' => array(
			'name' => 'SOL',
			'chain' => 'SOL',
			'decimal' => '9',
			'type' => 'coin'
		),
		'TRX' => array(
			'name' => 'TRX',
			'chain' => 'tron-mainnet',
			'decimal' => '6',
			'type' => 'coin'
		),
		
		'USDT_ETH' => array(
			'name' => 'ERC-20 USDT',
			'chain' => 'ethereum-mainnet',
			'decimal' => '6',
			'contract' => '0xdac17f958d2ee523a2206206994597c13d831ec7',
			'parent' => 'ETH',
			'type' => 'contract'
		),
		'USDT_ETH_ARB' => array(
			'name' => 'Arbitrum One USDT',
			'chain' => 'arb-one-mainnet',
			'decimal' => '6',
			'contract' => '0xfd086bc7cd5c481dcc9c85ebe478a1c0b69fcbb9',
			'parent' => 'ETH_ARB',
			'type' => 'contract'
		),
		'USDT_ETH_OP' => array(
			'name' => 'Optimism USDT ',
			'chain' => 'optimism-mainnet',
			'decimal' => '6',
			'contract' => '0x94b008aa00579c1307b0ef2c499ad98a8ce58e58',
			'parent' => 'ETH_OP',
			'type' => 'contract'
		),
		'USDT_BNB' => array(
			'name' => 'BEP-20 USDT',
			'chain' => 'bsc-mainnet',
			'decimal' => '6',
			'contract' => '0x55d398326f99059ff775485246999027b3197955',
			'parent' => 'BNB',
			'type' => 'contract'
		),
		'USDT_SOL' => array(
			'name' => 'SOL USDT',
			'chain' => 'solana-mainnet',
			'decimal' => '6',
			'contract' => 'es9vmfrzacermjfrf4h2fyd4kconky11mcce8benwnyb',
			'parent' => 'SOL',
			'type' => 'contract'
		),
		'USDT_TRX' => array(
			'name' => 'TRC-20 USDT',
			'chain' => 'tron-mainnet',
			'decimal' => '6',
			'contract' => 'tr7nhqjekqxgtci8q8zy4pl8otszgjlj6t',
			'parent' => 'TRX',
			'type' => 'contract'
		),
		
		'USDC_ETH' => array(
			'name' => 'ETH-20 USDC',
			'chain' => 'ethereum-mainnet',
			'decimal' => '6',
			'contract' => '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
			'parent' => 'ETH',
			'type' => 'contract'
		),
		'USDC_ETH_ARB' => array(
			'name' => 'Arbitrum One USDC',
			'chain' => 'arb-one-mainnet',
			'decimal' => '6',
			'contract' => '0xaf88d065e77c8cc2239327c5edb3a432268e5831',
			'parent' => 'ETH_ARB',
			'type' => 'contract'
		),
		'USDC_ETH_OP' => array(
			'name' => 'Optimism USDC',
			'chain' => 'optimism-mainnet',
			'decimal' => '6',
			'contract' => '0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85',
			'parent' => 'ETH_OP',
			'type' => 'contract'
		),
		'USDC_BNB' => array(
			'name' => 'BEP20 USDC',
			'chain' => 'bsc-mainnet',
			'decimal' => '6',
			'contract' => '0x8ac76a51cc950d9822d68b83fe1ad97b32cd580d',
			'parent' => 'BNB',
			'type' => 'contract'
		),
		'USDC_SOL' => array(
			'name' => 'SOL USDC',
			'chain' => 'solana-mainnet',
			'decimal' => '6',
			'contract' => 'epjfwdd5aufqssqem2qn1xzybapc8g4weggkzwytdt1v',
			'parent' => 'SOL',
			'type' => 'contract'
		),
	);
	
	if ( $type == 'wallets' ) {
		return array_map(
			function( $key ) {
				return 'wallets_' . strtolower( $key );
			},
			array_keys( $data )
		);		
	} else {
		return $data;
	}
}

function cryptoniq_get_coin_data($coin = '', $value = '') {
	$coins = cryptoniq_get_coins_list();
	
	if (!array_key_exists( $coin, $coins )) {
		return;
	}
	
	$data = $coins[$coin];
	
	if ($value) {
		$data = $coins[$coin][$value];
	}
	
	return $data;
}

// Get Payment Coins
// ======================================================

function cryptoniq_get_payment_coins() {
	$pay_coins = cryptoniq_get_option( 'pay_coins' );
	$pay_usdt  = cryptoniq_get_option( 'pay_usdt' );
	$pay_usdc  = cryptoniq_get_option( 'pay_usdc' );

	$pay_coins_list = array_merge(
		is_array( $pay_coins ) ? $pay_coins : array(),
		is_array( $pay_usdt )  ? $pay_usdt  : array(),
		is_array( $pay_usdc )  ? $pay_usdc  : array()
	);

	// Every coin this build knows about. What stops an unlicensed site taking
	// payment is the licence check at checkout, not a shorter coin list —
	// offering two coins that also cannot be paid for was never protection.
	$allowed = cryptoniq_features_unlocked()
		? cryptoniq_get_coins_list()
		: array_intersect_key( cryptoniq_get_coins_list(), array_flip( array( 'BTC', 'ETH' ) ) );

	return array_intersect_key( $pay_coins_list, $allowed );
}

// Get Panel Options
// ======================================================

function cryptoniq_get_option( $var = '' ) {
	if ( $var === '' ) {
		return '';
	}
	$opts = get_option( CRYPTONIQ_OPTION, array() );
	if ( ! is_array( $opts ) || ! array_key_exists( $var, $opts ) ) {
		return '';
	}
	return $opts[ $var ] ?: '';
}

/**
 * Is a valid license active?
 *
 * Source of truth: a non-empty `license_key` option. The license validator
 * only persists a key after the API server confirms it's valid, so the
 * mere presence of a value is enough — no extra live check needed on each
 * page load. The API server is the actual gatekeeper anyway: requests
 * without a valid license fail server-side (prices/currencies/webhooks).
 */
function cryptoniq_is_pro() {
	return ! empty( cryptoniq_get_option( 'license_key' ) );
}

/**
 * Is every feature of this build available?
 *
 * Always yes. This is the PRO plugin; the free tier is a separate plugin
 * (cryptoniq-lite) rather than a mode inside this one. Locking coins and
 * capping wallets here only ever produced a PRO install that looked crippled
 * before its key was entered.
 *
 * Client-side locks were never the thing protecting the product anyway — the
 * plugin runs on the merchant's server, where any check can be edited out. The
 * API is the gatekeeper: without a valid licence it will not subscribe an
 * address and will not forward a payment notification.
 *
 * Kept as a function rather than deleted at each site so the boundary between
 * the two builds stays visible, and so the lite plugin can answer differently.
 */
function cryptoniq_features_unlocked() {
	return true;
}

/**
 * Maximum total wallet addresses the merchant can store across all coins.
 */
function cryptoniq_wallet_limit() {
	return cryptoniq_features_unlocked() ? 50 : 10;
}

/**
 * Wallet-field IDs that are editable right now.
 */
function cryptoniq_active_wallet_keys() {
	if ( cryptoniq_features_unlocked() ) {
		// Field IDs in admin/index.php's wallet builder are lowercased
		// (e.g. wallets_btc, wallets_eth_arb). Match that exactly here so
		// the JS counter and pre_update_option filter find the right rows.
		return array_map(
			function ( $coin ) { return 'wallets_' . strtolower( $coin ); },
			array_keys( cryptoniq_get_coins_list() )
		);
	}
	return array( 'wallets_btc', 'wallets_eth' );
}

/**
 * Count active (currently-editable) wallet addresses across all coins.
 * Locked-coin addresses (e.g. leftover from before a license expired) are
 * preserved in storage but don't count toward the smaller no-license cap —
 * otherwise an unlicensed merchant would be blocked from editing BTC/ETH.
 */
function cryptoniq_count_active_wallets( $values = null ) {
	if ( $values === null ) {
		$values = get_option( CRYPTONIQ_OPTION, array() );
	}
	if ( ! is_array( $values ) ) {
		return 0;
	}

	$active = cryptoniq_active_wallet_keys();
	$total  = 0;
	foreach ( $active as $key ) {
		if ( isset( $values[ $key ] ) && is_array( $values[ $key ] ) ) {
			$total += count( array_filter( $values[ $key ], function ( $v ) {
				return is_string( $v ) && trim( $v ) !== '';
			} ) );
		}
	}
	return $total;
}

// Set Custom Template For Payment Type
// ======================================================

function cryptoniq_set_custom_template( $located, $template_name, $args, $template_path, $default_path ) {
	if (!isset($args['order']) || $template_name !== 'checkout/order-receipt.php') {
		return $located;
	}
	
	$pay_method = $args['order']->get_payment_method();
    
	if ( $pay_method == CRYPTONIQ_PAY_ID ) {
		$located = CRYPTONIQ_DIR_PATH . 'payment.php';
	}
    
	return $located;
}
add_filter( 'wc_get_template', 'cryptoniq_set_custom_template', 10, 5 );

// Update Order Transaction Data
// ======================================================

function cryptoniq_tx_data_update( $txid = '', $order_id = '' ) {
	if ( !$txid || !$order_id ) {
		return;
	}
	
	$order = wc_get_order( $order_id );
	
	if ( empty( $order->get_meta('cryptoniq_tx') ) ) {
		$order->update_meta_data( 'cryptoniq_tx', $txid );
		$order->save();
							
		// update txlist option
		Cryptoniq_AJAX::options_txlist_update( $txid, $order_id );							
	}
}

// Check if Transaction ID exists
// ======================================================

function cryptoniq_check_txid( $txid = '', $id = '' ) { 		
	$answer = '';
	$tx_list = get_option( 'cryptoniq_pay_txlist' );
		
	if ( is_array( $tx_list ) && array_key_exists( $txid, $tx_list ) ) {
		$answer = 1;
			
		if ( $id != null && $id == $tx_list[$txid] ) {
			$answer = '';
		}
	}
		
	return $answer;
}


// Update Meta Fields
// ======================================================

function cryptoniq_update_order_meta_fields( $order_id ) {
    $order = wc_get_order( $order_id );

    if ( ! $order || $order->get_payment_method() !== CRYPTONIQ_PAY_ID ) {
        return;
    }

    // Safer input
    $coin_ticker = isset( $_POST['cryptoniq_coin_ticker'] )
        ? sanitize_text_field( wp_unslash( $_POST['cryptoniq_coin_ticker'] ) )
        : '';

    $payment_coins = cryptoniq_get_payment_coins();
    if ( empty( $coin_ticker ) || ! isset( $payment_coins[ $coin_ticker ] ) ) {
        return;
    }

    $wallets = (array) cryptoniq_get_option( 'wallets_' . strtolower( $coin_ticker ) );
    if ( empty( $wallets ) ) {
        return;
    }

    $coin_wallet = preg_replace( '/\s+/', '', $wallets[ array_rand( $wallets ) ] );
    $total       = (float) $order->get_total();
    $coin_amount = cryptoniq_get_price( $coin_ticker, $total, '', true, false );
    $time        = time();

    $order->update_meta_data( 'cryptoniq_coin_ticker', $coin_ticker );
    $order->update_meta_data( 'cryptoniq_coin_amount', $coin_amount );
    $order->update_meta_data( 'cryptoniq_coin_wallet', $coin_wallet );
    $order->update_meta_data( 'cryptoniq_time_start', $time );

    $order->save();
}
add_action( 'woocommerce_checkout_update_order_meta', 'cryptoniq_update_order_meta_fields', 100, 1 );

// Add Custom Data To Header
// ======================================================

function cryptoniq_add_custom_header_data() {
?>

<script>
var cryptoniq_paybox_notes = {
	fail: '<?php esc_html_e( 'Payment is failed', 'cryptoniq-pro' ); ?>',
	check: '<?php esc_html_e( 'Checking...', 'cryptoniq-pro' ); ?>',
	process: '<?php esc_html_e( 'Processing...', 'cryptoniq-pro' ); ?>',
	error: '<?php esc_html_e( 'Error. Refresh the page', 'cryptoniq-pro' ); ?>'
}; 
</script>		

<style>
<?php 
	$pg_error_color = cryptoniq_get_option('pg_bar_tx_errors');
	$pg_check_color = cryptoniq_get_option('pg_bar_tx_checking');
	$pg_process_color = cryptoniq_get_option('pg_bar_tx_process');
?>
	
	.cryptoniq-paybox-tx-failed {
		background-color: <?php echo esc_attr( $pg_error_color ); ?>
	}

	.cryptoniq-paybox-tx-form {
		background-color: <?php echo esc_attr( $pg_check_color ); ?>
	}

	.cryptoniq-paybox-tx-processing {
		background-color: <?php echo esc_attr( $pg_process_color ); ?>
	}
<?php }
add_action( 'wp_head', 'cryptoniq_add_custom_header_data' );

// Add Payment Data (Coin) To Success Page
// ======================================================

function cryptoniq_data_thankyou( $order_id ) {
	$order = wc_get_order( $order_id );
	
	$coin = $order->get_meta('cryptoniq_coin_ticker');
	$amount = $order->get_meta('cryptoniq_coin_amount');
	$wallet = $order->get_meta('cryptoniq_coin_wallet');
	$txid = $order->get_meta('cryptoniq_tx');
?>
 
	<section class="cryptoniq-woocommerce-order-details">
		<h2 class="woocommerce-order-details__title">Cryptoniq</h2>
		<table class="woocommerce-table woocommerce-table--order-details shop_table order_details">
			<tr>
				<th><?php esc_html_e( 'Coin', 'cryptoniq-pro' ); ?>:</th>
				<th class="woocommerce-table__product-table product-total"><?php echo esc_html( $coin ); ?></th>
			</tr>
			<tr>
				<th scope="row"><?php esc_html_e( 'Total:', 'cryptoniq-pro' ); ?></th>
				<td><?php echo esc_html( $order->get_meta( 'cryptoniq_coin_amount' ) ); ?></td>
			</tr>
			<tr>
				<th scope="row"><?php esc_html_e( 'Address:', 'cryptoniq-pro' ); ?></th>
				<td><?php echo esc_html( $wallet ); ?></td>
			</tr>
			<tr>
				<th scope="row"><?php esc_html_e( 'Transaction:', 'cryptoniq-pro' ); ?></th>
				<td><?php echo esc_html( $txid ); ?></td>
			</tr>
		</table>
	</section>

<?php
}
add_action( 'woocommerce_thankyou_cryptoniq', 'cryptoniq_data_thankyou' );

// Set Custom Hold Time For Products
// ======================================================

function cryptoniq_custom_hold_time() {
	$time = '60';
	$duration = get_option( 'woocommerce_hold_stock_minutes' );

	if ( get_option( 'woocommerce_manage_stock' ) != 'yes' || $duration > $time ) {
		return;
	}
	
	update_option( 'woocommerce_hold_stock_minutes', $time );
}
add_action( 'admin_init', 'cryptoniq_custom_hold_time' );