<?php
/**
 * Checkout Manager
 *
 * Handles custom checkout behavior for donations.
 *
 * @package DonorCore\WooCommerce
 */

namespace DonorCore\WooCommerce;

defined( 'ABSPATH' ) || exit;

/**
 * Checkout Manager Class
 */
class Checkout_Manager {

	/**
	 * Initialize hooks.
	 */
	public function init() {
		// Add custom amount field to product page.
		add_action( 'woocommerce_before_add_to_cart_button', array( $this, 'add_amount_field' ) );
		
		// Validate and store custom amount.
		add_filter( 'woocommerce_add_cart_item_data', array( $this, 'add_cart_item_data' ), 10, 3 );
		
		// Set custom price in cart.
		add_action( 'woocommerce_before_calculate_totals', array( $this, 'set_cart_item_price' ) );
		
		// Display custom amount in cart.
		add_filter( 'woocommerce_cart_item_name', array( $this, 'display_cart_item_meta' ), 10, 2 );
		
		// Add campaign meta to order item.
		add_action( 'woocommerce_checkout_create_order_line_item', array( $this, 'add_order_item_meta' ), 10, 4 );
		
		// Record donation after order completion.
		add_action( 'woocommerce_payment_complete', array( $this, 'record_donation' ) );
		add_action( 'woocommerce_order_status_completed', array( $this, 'record_donation' ) );
		add_action( 'woocommerce_order_status_processing', array( $this, 'record_donation' ) );
		
		// Disable default WooCommerce emails for donation orders only.
		add_filter( 'woocommerce_email_enabled_customer_processing_order', array( $this, 'disable_default_emails' ), 10, 3 );
		add_filter( 'woocommerce_email_enabled_customer_completed_order', array( $this, 'disable_default_emails' ), 10, 3 );
		
		// Conditional order status based on payment method.
		add_action( 'woocommerce_thankyou', array( $this, 'set_conditional_order_status' ), 10, 1 );
		
		// Bypass shipping and taxes for donation products.
		add_filter( 'woocommerce_package_rates', array( $this, 'disable_shipping_for_donations' ), 100, 2 );
		add_action( 'woocommerce_cart_calculate_fees', array( $this, 'remove_taxes_from_donations' ), 100 );
		add_filter( 'woocommerce_product_get_tax_class', array( $this, 'set_donation_tax_class' ), 10, 2 );
		
		add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_assets' ) );
	}

	/**
	 * Enqueue assets for checkout.
	 */
	public function enqueue_assets() {
		if ( ! is_product() ) {
			return;
		}
		
		// We can use a dummy handle or check if we are on a donation product
		global $post;
		if ( ! $post ) {
			return;
		}
		$product = wc_get_product( $post->ID );
		if ( ! $product || 'donation' !== $product->get_type() ) {
			return;
		}

		wp_register_script( 'donor-core-checkout', false, array( 'jquery' ), DONOR_CORE_VERSION, true );
		wp_enqueue_script( 'donor-core-checkout' );
		
		$js = "
		jQuery(document).ready(function($) {
			$('.dc-amount-button').on('click', function() {
				$('.dc-amount-button').removeClass('selected');
				$(this).addClass('selected');
				$('#donorcore_donation_amount').val($(this).data('amount'));
			});
			$('.dc-amount-button').first().addClass('selected');
		});
		";
		wp_add_inline_script( 'donor-core-checkout', $js );

		wp_register_style( 'donor-core-checkout-style', false, array(), DONOR_CORE_VERSION );
		wp_enqueue_style( 'donor-core-checkout-style' );
		
		$css = "
			.dc-donation-amount-selector { margin-bottom: 20px; }
			.dc-suggested-amounts { display: flex; gap: 10px; margin: 10px 0; flex-wrap: wrap; }
			.dc-amount-button { 
				padding: 10px 20px; 
				border: 2px solid #ddd; 
				background: white; 
				cursor: pointer; 
				border-radius: 4px;
			}
			.dc-amount-button.selected { 
				background: #007cba; 
				color: white; 
				border-color: #007cba; 
			}
			.dc-custom-amount { margin-top: 15px; }
			.dc-custom-amount input { width: 100%; max-width: 200px; }
		";
		$css = wp_strip_all_tags( $css );
		wp_add_inline_style( 'donor-core-checkout-style', $css );
	}

	/**
	 * Add custom amount input field to donation products.
	 */
	public function add_amount_field() {
		global $product;

		if ( ! $product || 'donation' !== $product->get_type() ) {
			return;
		}

		$suggested_amounts = get_post_meta( $product->get_id(), '_donorcore_suggested_amounts', true );
		$min_amount        = get_post_meta( $product->get_id(), '_donorcore_min_donation', true );

		if ( is_string( $suggested_amounts ) && ! empty( $suggested_amounts ) ) {
			$decoded = json_decode( $suggested_amounts, true );
			if ( is_array( $decoded ) ) {
				$suggested_amounts = $decoded;
			}
		}

		if ( is_array( $suggested_amounts ) ) {
			$suggested_amounts = array_filter( array_map( 'floatval', $suggested_amounts ) );
		}

		if ( empty( $suggested_amounts ) || ! is_array( $suggested_amounts ) ) {
			$global_suggested  = get_option( 'donorcore_suggested_amounts', '50,100,250,500' );
			$suggested_amounts = array_map( 'floatval', array_filter( array_map( 'trim', explode( ',', $global_suggested ) ) ) );
			if ( empty( $suggested_amounts ) ) {
				$suggested_amounts = array( 50, 100, 250, 500 );
			}
		}
		$suggested_amounts = array_values( $suggested_amounts );

		?>
		<div class="dc-donation-amount-selector">
			<?php wp_nonce_field( 'donorcore_add_to_cart_' . $product->get_id(), 'donorcore_add_to_cart_nonce' ); ?>
			<label for="donorcore_donation_amount"><?php esc_html_e( 'Select Donation Amount:', 'donorcore-donations' ); ?></label>
			
			<div class="dc-suggested-amounts">
				<?php foreach ( $suggested_amounts as $amount ) : ?>
					<button type="button" class="dc-amount-button" data-amount="<?php echo esc_attr( $amount ); ?>">
						<?php echo wp_kses_post( wc_price( $amount ) ); ?>
					</button>
				<?php endforeach; ?>
			</div>

			<div class="dc-custom-amount">
				<label for="donorcore_donation_amount">
					<?php esc_html_e( 'Or enter custom amount:', 'donorcore-donations' ); ?>
					<?php if ( $min_amount ) : ?>
						(<?php 
						/* translators: %s: minimum donation amount */
						echo wp_kses_post( sprintf( __( 'Min: %s', 'donorcore-donations' ), wc_price( $min_amount ) ) ); ?>)
					<?php endif; ?>
				</label>
				<input type="number" 
					id="donorcore_donation_amount" 
					name="donorcore_donation_amount" 
					step="0.01" 
					min="<?php echo esc_attr( $min_amount ?: 0 ); ?>" 
					value="<?php echo esc_attr( $suggested_amounts[0] ); ?>" 
					class="input-text amount text" />
			</div>
		</div>
		<?php
	}

	/**
	 * Save custom donation amount to cart item data.
	 *
	 * @param array $cart_item_data Cart item data.
	 * @param int   $product_id     Product ID.
	 * @return array
	 */
	public function add_cart_item_data( $cart_item_data, $product_id ) {
		$product = wc_get_product( $product_id );
		if ( ! $product ) {
			return $cart_item_data;
		}

		// Check if it's a donation product or linked to a campaign.
		$is_donation  = 'donation' === $product->get_type();
		$has_campaign = ! empty( $product->get_meta( '_donorcore_campaign_id', true ) );

		if ( ! $is_donation && ! $has_campaign ) {
			return $cart_item_data;
		}

		// Nonce validation check on input origin
		$nonce_valid = false;
		if ( isset( $_POST['donorcore_add_to_cart_nonce'] ) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['donorcore_add_to_cart_nonce'] ) ), 'donorcore_add_to_cart_' . $product_id ) ) {
			$nonce_valid = true;
		} elseif ( isset( $_POST['add-to-cart'] ) && absint( $_POST['add-to-cart'] ) === $product_id ) {
			$nonce_valid = true;
		}

		if ( ! $nonce_valid ) {
			return $cart_item_data;
		}

		if ( isset( $_POST['donorcore_donation_amount'] ) ) {
			$amount = floatval( wp_unslash( $_POST['donorcore_donation_amount'] ) );
			
			// Validate minimum.
			$min_amount = $product->get_meta( '_donorcore_min_donation', true );
			if ( $min_amount && $amount < floatval( $min_amount ) ) {
				wc_add_notice( 
					sprintf( 
						/* translators: %s: minimum amount */
						__( 'Minimum donation amount is %s.', 'donorcore-donations' ), 
						wc_price( $min_amount ) 
					), 
					'error' 
				);
				return $cart_item_data;
			}

			$cart_item_data['donorcore_donation_amount'] = $amount;
			$cart_item_data['donorcore_campaign_id']     = $product->get_meta( '_donorcore_campaign_id', true );
		}

		return $cart_item_data;
	}

	/**
	 * Set custom price in cart.
	 *
	 * @param \WC_Cart $cart Cart object.
	 */
	public function set_cart_item_price( $cart ) {
		if ( is_admin() && ! defined( 'DOING_AJAX' ) ) {
			return;
		}

		foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
			if ( isset( $cart_item['donorcore_donation_amount'] ) ) {
				$cart_item['data']->set_price( $cart_item['donorcore_donation_amount'] );
			}
		}
	}

	/**
	 * Display custom amount in cart.
	 *
	 * @param string $name      Product name.
	 * @param array  $cart_item Cart item data.
	 * @return string
	 */
	public function display_cart_item_meta( $name, $cart_item ) {
		if ( isset( $cart_item['donorcore_donation_amount'] ) ) {
			$name .= sprintf( 
				'<br><small>%s: %s</small>', 
				esc_html__( 'Donation Amount', 'donorcore-donations' ),
				wc_price( $cart_item['donorcore_donation_amount'] )
			);
		}

		if ( isset( $cart_item['donorcore_campaign_id'] ) ) {
			$campaign = get_post( $cart_item['donorcore_campaign_id'] );
			if ( $campaign ) {
				$name .= sprintf( 
					'<br><small>%s: %s</small>', 
					esc_html__( 'Campaign', 'donorcore-donations' ),
					esc_html( $campaign->post_title )
				);
			}
		}

		return $name;
	}

	/**
	 * Add campaign meta to order item.
	 *
	 * @param \WC_Order_Item_Product $item          Order item.
	 * @param string                 $cart_item_key Cart item key.
	 * @param array                  $values        Cart item values.
	 * @param \WC_Order              $order         Order object.
	 */
	public function add_order_item_meta( $item, $cart_item_key, $values, $order ) {
		if ( isset( $values['donorcore_donation_amount'] ) ) {
			$item->add_meta_data( '_donorcore_donation_amount', $values['donorcore_donation_amount'], true );
		}

		if ( isset( $values['donorcore_campaign_id'] ) ) {
			$item->add_meta_data( '_donorcore_campaign_id', $values['donorcore_campaign_id'], true );
		}
	}

	/**
	 * Record donation in custom table after payment.
	 *
	 * @param int $order_id Order ID.
	 */
	public function record_donation( $order_id ) {
		// Debug log removed for production

		
		$order = wc_get_order( $order_id );

		if ( ! $order ) {
			return;
		}

		// Prevent duplicate recording
		if ( $order->get_meta( '_donorcore_donation_recorded', true ) ) {
			return;
		}

		// **NEW: Payment method validation**
		// For offline payments (COD, BACS), only record when status is "Completed"
		// (i.e., after admin manually confirms payment received)
		$payment_method = $order->get_payment_method();
		$order_status = $order->get_status();
		
		if ( ! $this->is_online_payment_method( $payment_method ) ) {
			// This is an offline payment method
			if ( $order_status !== 'completed' ) {
				// Don't record yet - waiting for admin to confirm payment
				return;
			}
		}

		$donation_repo = new \DonorCore\Database\Donation_Log_Repository();
		$analytics_repo = new \DonorCore\Database\Donor_Analytics_Repository();
		$recorded = false;

		foreach ( $order->get_items() as $item ) {
			$product = $item->get_product();

			if ( ! $product ) {
				continue;
			}

			// Check for donation product or campaign-linked product
			$is_donation = 'donation' === $product->get_type();
			$campaign_id = $item->get_meta( '_donorcore_campaign_id', true );
			
			if ( ! $is_donation && ! $campaign_id ) {
				continue;
			}

			$amount = $item->get_meta( '_donorcore_donation_amount', true );

			if ( ! $amount ) {
				$amount = $item->get_total();
			}

			// Insert donation log.
			$donation_repo->insert(
				array(
					'order_id'    => $order_id,
					'campaign_id' => $campaign_id ? $campaign_id : 0,
					'donor_id'    => $order->get_user_id(),
					'amount'      => $amount,
					'currency'    => $order->get_currency(),
					'type'        => 'one-time',
					'gateway'     => $order->get_payment_method(),
				)
			);

			// Update donor analytics.
			$analytics_repo->record_donation(
				$order->get_billing_email(),
				$order->get_user_id(),
				$amount
			);

			// Clear campaign total cache.
			if ( $campaign_id ) {
				delete_transient( 'donorcore_campaign_total_' . $campaign_id );
			}

			$recorded = true;
		}

		// Mark as recorded
		if ( $recorded ) {
			$order->update_meta_data( '_donorcore_donation_recorded', 'yes' );
			$order->save();
		}
	}

	/**
	 * Capture payment token for recurring donations.
	 *
	 * @param int $order_id Order ID.
	 */
	public function capture_payment_token( $order_id ) {
		$order = wc_get_order( $order_id );

		// Check if order has recurring frequency.
		$has_recurring = false;
		foreach ( $order->get_items() as $item ) {
			$frequency = $item->get_meta( '_donorcore_recurring_frequency', true );
			if ( ! empty( $frequency ) && $frequency !== 'once' ) {
				$has_recurring = true;
				break;
			}
		}
		

		// Get payment tokens from order.
		$tokens = $order->get_payment_tokens();
		
		if ( empty( $tokens ) ) {
			// Try to get from customer (Stripe/PayPal save tokens here).
			$user_id = $order->get_user_id();
			if ( $user_id ) {
				$customer_tokens = \WC_Payment_Tokens::get_customer_tokens( $user_id );
				
				if ( ! empty( $customer_tokens ) ) {
					// Get the most recent token.
					$token = reset( $customer_tokens );
					$token_id = $token->get_id();
					
					// Save token ID to order meta.
					$order->update_meta_data( '_donorcore_payment_token_id', $token_id );
					$order->save();
				} 
			}
		} else {
			// Token already on order.
			$token_id = reset( $tokens );
			$order->update_meta_data( '_donorcore_payment_token_id', $token_id );
			$order->save();
		}
	}

	/**
	 * Disable default WooCommerce emails ONLY for donation orders.
	 * Regular products will still receive WooCommerce emails normally.
	 *
	 * @param bool   $enabled      Whether email is enabled.
	 * @param object $order        Order object.
	 * @param object $email_object Email object.
	 * @return bool
	 */
	public function disable_default_emails( $enabled, $order, $email_object ) {
		if ( ! $order ) {
			return $enabled;
		}
		
		$has_donation = false;
		$has_regular = false;
		
		// Check what's in the order
		foreach ( $order->get_items() as $item ) {
			$product = $item->get_product();
			
			// Check for donation product type
			if ( $product && 'donation' === $product->get_type() ) {
				$has_donation = true;
			} elseif ( $product ) {
				$has_regular = true;
			}
			
			// Check for campaign-linked products (also donations)
			if ( $item->get_meta( '_donorcore_campaign_id', true ) ) {
				$has_donation = true;
			}
		}
		
		// If order contains ANY donation, disable WooCommerce email
		// (Custom DonorCore receipt will be sent instead)
		if ( $has_donation ) {
			return false; // Disable WooCommerce email
		}
		
		// For pure regular product orders, keep WooCommerce emails
		return $enabled;
	}
	/**
	 * Set conditional order status based on payment method.
	 * 
	 * Online payments → Completed (tracked immediately)
	 * Offline payments → Processing (tracked only after admin confirms)
	 *
	 * @param int $order_id Order ID.
	 */
	public function set_conditional_order_status( $order_id ) {
		if ( ! $order_id ) {
			return;
		}
		$order = wc_get_order( $order_id );
		if ( ! $order ) {
			return;
		}
		// Only apply to donation orders
		if ( ! $this->is_donation_order( $order ) ) {
			return;
		}
		$payment_method = $order->get_payment_method();
		
		// Check if this is an online payment method
		if ( $this->is_online_payment_method( $payment_method ) ) {
			// Online payment → Set to Completed immediately
			if ( $order->get_status() !== 'completed' ) {
				$order->update_status( 'completed', __( 'Online donation payment confirmed.', 'donorcore-donations' ) );
			}
		} else {
			// Offline payment → Keep as Processing (wait for admin confirmation)
			if ( $order->get_status() !== 'processing' ) {
				$order->update_status( 'processing', __( 'Awaiting offline payment confirmation.', 'donorcore-donations' ) );
			}
		}
	}
	/**
	 * Disable shipping methods for donation-only carts.
	 *
	 * @param array $rates Shipping rates.
	 * @param array $package Shipping package.
	 * @return array
	 */
	public function disable_shipping_for_donations( $rates, $package ) {
		// Check if cart contains only donations
		if ( ! $this->cart_has_only_donations() ) {
			return $rates; // Mixed cart or no donations - keep shipping
		}
		// Remove all shipping methods for donation-only carts
		return array();
	}
	/**
	 * Remove taxes from donation products.
	 */
	public function remove_taxes_from_donations() {
		if ( ! WC()->cart ) {
			return;
		}
		foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
			if ( $this->is_donation_product( $cart_item['product_id'] ) ) {
				$cart_item['data']->set_tax_status( 'none' );
			}
		}
	}
	/**
	 * Set tax class to zero-rate for donation products.
	 *
	 * @param string     $tax_class Tax class.
	 * @param WC_Product $product Product object.
	 * @return string
	 */
	public function set_donation_tax_class( $tax_class, $product ) {
		if ( $this->is_donation_product( $product->get_id() ) ) {
			return 'zero-rate';
		}
		return $tax_class;
	}
	/**
	 * Check if payment method is online.
	 *
	 * @param string $payment_method Payment gateway ID.
	 * @return bool
	 */
	private function is_online_payment_method( $payment_method ) {
		$online_methods = array(
			'stripe',
			'stripe_cc',
			'stripe_sepa',
			'paypal',
			'paypal_express',
			'razorpay',
			'square',
			'authorize_net',
			'braintree',
			// Add more online payment methods as needed
		);
		return in_array( $payment_method, $online_methods, true );
	}
	/**
	 * Check if cart contains only donation products.
	 *
	 * @return bool
	 */
	private function cart_has_only_donations() {
		if ( ! WC()->cart || WC()->cart->is_empty() ) {
			return false;
		}
		foreach ( WC()->cart->get_cart() as $cart_item ) {
			if ( ! $this->is_donation_product( $cart_item['product_id'] ) ) {
				return false; // Found non-donation product
			}
		}
		return true; // All products are donations
	}
	/**
	 * Check if product is a donation.
	 *
	 * @param int $product_id Product ID.
	 * @return bool
	 */
	private function is_donation_product( $product_id ) {
		$product = wc_get_product( $product_id );
		if ( ! $product ) {
			return false;
		}
		// Check if product has donation meta or is in donation category
		$is_donation = get_post_meta( $product_id, '_donorcore_is_donation', true );
		
		if ( $is_donation ) {
			return true;
		}
		// Alternative: Check product category
		$categories = wp_get_post_terms( $product_id, 'product_cat', array( 'fields' => 'slugs' ) );
		return in_array( 'donations', $categories, true );
	}
	/**
	 * Check if order contains donation products.
	 *
	 * @param WC_Order $order Order object.
	 * @return bool
	 */
	private function is_donation_order( $order ) {
		foreach ( $order->get_items() as $item ) {
			if ( $item->get_meta( '_donorcore_campaign_id', true ) ) {
				return true; // Has donation campaign meta
			}
		}
		return false;
	}


}