<?php
/**
 * File: Ecre_Flag_Manager.php
 *
 * Flag Management Service for Echo Rewards - Centralized flag update logic.
 *
 * @package ECRE
 * @since   1.0.0
 */

namespace ECRE;

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

if ( ! class_exists( 'ECRE\Ecre_Flag_Manager' ) ) {

	/**
	 * Echo Rewards Flag Management Service.
	 *
	 * Centralizes the logic for updating custom_rewards and custom_referrals flags
	 * in the ecre_referrers table to ensure consistency across the system.
	 *
	 * @since 1.0.0
	 */
	class Ecre_Flag_Manager {

		/**
		 * Database instance for database operations.
		 *
		 * @var Ecre_Database
		 */
		private $database;

		/**
		 * Constructor.
		 *
		 * @since 1.0.0
		 */
		public function __construct() {
			$this->database = new Ecre_Database();
		}

		/**
		 * Update the custom_rewards flag for a user based on their custom reward settings.
		 *
		 * @since 1.0.0
		 *
		 * @param int  $user_id            The user ID to update the flag for.
		 * @param bool $has_custom_rewards Whether the user has custom reward settings.
		 *
		 * @return bool True on success, false on failure.
		 */
		public function update_custom_rewards_flag( $user_id, $has_custom_rewards ) {
			if ( ! $user_id || ! is_numeric( $user_id ) ) {
				return false;
			}

			try {
				// Ensure referrer record exists.
				$this->database->ensure_referrer_record_exists( $user_id );

				// Get current flag status.
				$current_flags = $this->get_flag_status( $user_id );
				if ( false === $current_flags ) {
					return false;
				}

				// Update only if the flag value has changed.
				$new_custom_rewards = $has_custom_rewards ? 1 : 0;
				if ( $current_flags['custom_rewards'] !== $new_custom_rewards ) {
					$result = $this->database->update_referrer_flags(
						$user_id,
						$new_custom_rewards,
						$current_flags['custom_referrals']
					);
					return $result;
				}

				return true; // No update needed, consider it successful.
			} catch ( Exception $e ) {
				return false;
			}
		}

		/**
		 * Update the custom_referrals flag for a user based on their custom referral settings.
		 *
		 * @since 1.0.0
		 *
		 * @param int  $user_id             The user ID to update the flag for.
		 * @param bool $has_custom_referrals Whether the user has custom referral settings.
		 *
		 * @return bool True on success, false on failure.
		 */
		public function update_custom_referrals_flag( $user_id, $has_custom_referrals ) {
			if ( ! $user_id || ! is_numeric( $user_id ) ) {
				return false;
			}

			try {
				// Ensure referrer record exists.
				$this->database->ensure_referrer_record_exists( $user_id );

				// Get current flag status.
				$current_flags = $this->get_flag_status( $user_id );
				if ( false === $current_flags ) {
					return false;
				}

				// Update only if the flag value has changed.
				$new_custom_referrals = $has_custom_referrals ? 1 : 0;
				if ( $current_flags['custom_referrals'] !== $new_custom_referrals ) {
					$result = $this->database->update_referrer_flags(
						$user_id,
						$current_flags['custom_rewards'],
						$new_custom_referrals
					);

					return $result;
				}

				return true; // No update needed, consider it successful.
			} catch ( Exception $e ) {
				return false;
			}
		}

		/**
		 * Validate and update both flags for a user based on their actual custom settings.
		 *
		 * This method checks the user's actual custom settings and updates both flags accordingly.
		 *
		 * @since 1.0.0
		 *
		 * @param int $user_id The user ID to validate and update flags for.
		 *
		 * @return bool True on success, false on failure.
		 */
		public function validate_and_update_flags( $user_id ) {
			if ( ! $user_id || ! is_numeric( $user_id ) ) {
				return false;
			}

			try {
				// Get actual custom settings for the user.
				$custom_settings = $this->database->get_user_custom_settings( $user_id );

				// Determine if user has custom reward settings.
				$has_custom_rewards = $this->has_custom_reward_settings( $custom_settings );

				// Determine if user has custom referral settings.
				$has_custom_referrals = $this->has_custom_referral_settings( $custom_settings );

				// Update both flags.
				$rewards_result   = $this->update_custom_rewards_flag( $user_id, $has_custom_rewards );
				$referrals_result = $this->update_custom_referrals_flag( $user_id, $has_custom_referrals );

				return $rewards_result && $referrals_result;
			} catch ( Exception $e ) {
				return false;
			}
		}

		/**
		 * Get the current flag status for a user.
		 *
		 * @since 1.0.0
		 *
		 * @param int $user_id The user ID to get flag status for.
		 *
		 * @return array|false Array with 'custom_rewards' and 'custom_referrals' keys, or false on failure.
		 */
		public function get_flag_status( $user_id ) {
			if ( ! $user_id || ! is_numeric( $user_id ) ) {
				return false;
			}

			global $wpdb;

			$referrer = $wpdb->get_row(
				$wpdb->prepare(
					"SELECT custom_rewards, custom_referrals FROM {$wpdb->prefix}ecre_referrers WHERE user_id = %d",
					$user_id
				),
				ARRAY_A
			);

			if ( ! $referrer ) {
				// Return default values if no record exists.
				return array(
					'custom_rewards'   => 0,
					'custom_referrals' => 0,
				);
			}

			return array(
				'custom_rewards'   => intval( $referrer['custom_rewards'] ),
				'custom_referrals' => intval( $referrer['custom_referrals'] ),
			);
		}

		/**
		 * Check if a user has custom reward settings.
		 *
		 * @since 1.0.0
		 *
		 * @param array $custom_settings Array of custom settings for the user.
		 *
		 * @return bool True if user has custom reward settings, false otherwise.
		 */
		private function has_custom_reward_settings( $custom_settings ) {
			if ( empty( $custom_settings ) || ! is_array( $custom_settings ) ) {
				return false;
			}

			// Define reward settings keys.
			$reward_settings_keys = array(
				'rewardPoint',
				'redeemPoint',
				'redeemLimit',
				'enableRedeemLimit',
				'redeemDiscount',
				'rewardType',
				'rewardDiscount',
				'rewardDiscountCapping',
				'enableRewardExpiry',
				'rewardCouponValidity',
				'enableRewardCouponUsageLimit',
				'rewardCouponUsageLimit',
				'rewardMinimumPurchaseAmount',
			);

			// Check if any reward settings exist.
			foreach ( $reward_settings_keys as $key ) {
				if ( array_key_exists( $key, $custom_settings ) ) {
					return true;
				}
			}

			return false;
		}

		/**
		 * Check if a user has custom referral settings.
		 *
		 * @since 1.0.0
		 *
		 * @param array $custom_settings Array of custom settings for the user.
		 *
		 * @return bool True if user has custom referral settings, false otherwise.
		 */
		private function has_custom_referral_settings( $custom_settings ) {
			if ( empty( $custom_settings ) || ! is_array( $custom_settings ) ) {
				return false;
			}

			// Define referral settings keys.
			$referral_settings_keys = array(
				'referralDiscount',
				'referralDiscountCapping',
				'enableReferralLimit',
				'referralMonthlyLimit',
				'referralMinimumPurchaseAmount',
			);

			// Check if any referral settings exist.
			foreach ( $referral_settings_keys as $key ) {
				if ( array_key_exists( $key, $custom_settings ) ) {
					return true;
				}
			}

			return false;
		}

		/**
		 * Update flags based on saved settings data.
		 *
		 * This method analyzes the settings being saved and updates the appropriate flags.
		 *
		 * @since 1.0.0
		 *
		 * @param int   $user_id         The user ID to update flags for.
		 * @param array $saved_settings  Array of settings that were saved.
		 * @param bool  $is_referral_coupon_update Whether this is a referral coupon update.
		 *
		 * @return bool True on success, false on failure.
		 */
		public function update_flags_from_saved_settings( $user_id, $saved_settings, $is_referral_coupon_update = false ) {
			if ( ! $user_id || ! is_numeric( $user_id ) ) {
				return false;
			}

			try {
				// Determine if reward settings were saved.
				$has_reward_settings = $this->has_custom_reward_settings( $saved_settings );

				// Determine if referral settings were saved.
				$has_referral_settings = $this->has_custom_referral_settings( $saved_settings ) || $is_referral_coupon_update;

				$success = true;

				// Update custom_rewards flag if reward settings were saved.
				if ( $has_reward_settings ) {
					$success = $this->update_custom_rewards_flag( $user_id, true ) && $success;
				}

				// Update custom_referrals flag if referral settings were saved.
				if ( $has_referral_settings ) {
					$success = $this->update_custom_referrals_flag( $user_id, true ) && $success;
				}

				return $success;
			} catch ( Exception $e ) {
				return false;
			}
		}
	}
}
