<?php
/**
 * Firebase Sender for Automation Web Platform.
 * Handles Firebase Auth/FCM settings and test message sending.
 *
 * @package automation-web-platform
 */

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


/**
 * Class WAWP_Firebase_Sender
 *
 * @package automation-web-platform
 */
class WAWP_Firebase_Sender extends WAWP_Sender_Base {
	use WAWP_Settings_Handler;

	/**
	 * Singleton instance.
	 *
	 * @var WAWP_Firebase_Sender
	 */
	private static $instance = null;

	/**
	 * Get singleton instance.
	 *
	 * @return WAWP_Firebase_Sender
	 */
	public static function get_instance() {
		if ( null === self::$instance ) {
			self::$instance = new self();
		}

		return self::$instance;
	}

	/**
	 * Setup class properties.
	 */
	protected function setup_properties() {
		$this->nonce_action = 'wawp_firebase_nonce';
	}

	/**
	 * Get firebase accounts table name.
	 *
	 * @return string
	 */
	public static function get_accounts_table() {
		return WAWP()->db->get_firebase_accounts_table_name();
	}

	/**
	 * List all firebase accounts.
	 *
	 * @return array
	 */
	public static function list_accounts() {
		global $wpdb;
		$table = self::get_accounts_table();

		$cache_key = 'wawp_firebase_accounts';
		$results   = wp_cache_get( $cache_key, 'wawp_database' );

		if ( false === $results ) {
			$results = WAWP()->db->get_results_cached( $wpdb->prepare( 'SELECT * FROM %i ORDER BY id DESC', $table ), $cache_key, 'wawp_database', HOUR_IN_SECONDS );

			if ( empty( $results ) ) {
				// Fallback/Migration check.
				$old_settings = WAWP::instance()->get_wawp_setting( WAWP_Settings_Registry::FIREBASE_SETTINGS );
				if ( ! empty( $old_settings ) ) {
					self::get_instance()->save_account( 'Default Account', $old_settings, 1 );
					$results = WAWP()->db->get_results_cached( $wpdb->prepare( 'SELECT * FROM %i ORDER BY id DESC', $table ), $cache_key, 'wawp_database', HOUR_IN_SECONDS );
				}
			}
			wp_cache_set( $cache_key, $results, 'wawp_database', HOUR_IN_SECONDS );
		}

		$has_active            = false;
		$first_validated_index = -1;

		if ( $results ) {
			foreach ( $results as $idx => &$account ) {
				$account['config']    = WAWP::instance()->from_db( $account['config'] );
				$account['validated'] = (int) $account['validated'];
				$account['is_active'] = (int) $account['is_active'];

				if ( 1 === $account['is_active'] && 1 === $account['validated'] ) {
					$has_active = true;
				}

				if ( 1 === $account['validated'] && -1 === $first_validated_index ) {
					$first_validated_index = $idx;
				}
			}

			if ( ! $has_active && -1 !== $first_validated_index ) {
				$active_id = $results[ $first_validated_index ]['id'];

				WAWP()->db->update_row( 'firebase_accounts', array( 'is_active' => 0 ), array( 'is_active' => 1 ) );
				WAWP()->db->update_row( 'firebase_accounts', array( 'is_active' => 1 ), array( 'id' => $active_id ) );

				wp_cache_delete( 'wawp_firebase_accounts', 'wawp_database' );
				wp_cache_delete( 'wawp_firebase_active', 'wawp_database' );

				$results[ $first_validated_index ]['is_active'] = 1;

				// Sync legacy options.
				$active_config = $results[ $first_validated_index ]['config'];
				self::get_instance()->update_wawp_setting( WAWP_Settings_Registry::FIREBASE_SETTINGS, $active_config );
				self::get_instance()->update_wawp_setting( WAWP_Settings_Registry::FIREBASE_API_KEY, $active_config['apiKey'] ?? $active_config['api_key'] ?? '' );
			}
		}

		return $results;
	}

	/**
	 * Get the active firebase account.
	 *
	 * @return array
	 */
	public static function get_active_account() {
		global $wpdb;
		$table = self::get_accounts_table();

		$cache_key = 'wawp_firebase_active';
		$row       = wp_cache_get( $cache_key, 'wawp_database' );

		if ( false === $row ) {
			$results = WAWP()->db->get_results_cached( $wpdb->prepare( 'SELECT * FROM %i WHERE is_active = 1 LIMIT 1', $table ), $cache_key, 'wawp_database', HOUR_IN_SECONDS );
			$row     = ! empty( $results ) ? $results[0] : null;
			if ( ! $row ) {
				$accounts = self::list_accounts();
				$row      = ! empty( $accounts ) ? $accounts[0] : null;
			}
			wp_cache_set( $cache_key, $row, 'wawp_database', HOUR_IN_SECONDS );
		}

		if ( $row ) {
			$config = ( is_string( $row['config'] ) ) ? WAWP::instance()->from_db( $row['config'] ) : $row['config'];

			// Ensure all required camelCase keys are present for consumers.
			if ( ! empty( $config['api_key'] ) && empty( $config['apiKey'] ) ) {
				$config['apiKey'] = $config['api_key'];
			}
			if ( ! empty( $config['project_id'] ) && empty( $config['projectId'] ) ) {
				$config['projectId'] = $config['project_id'];
			}
			if ( ! empty( $config['auth_domain'] ) && empty( $config['authDomain'] ) ) {
				$config['authDomain'] = $config['auth_domain'];
			}
			if ( ! empty( $config['app_id'] ) && empty( $config['appId'] ) ) {
				$config['appId'] = $config['app_id'];
			}
			if ( ! empty( $config['storage_bucket'] ) && empty( $config['storageBucket'] ) ) {
				$config['storageBucket'] = $config['storage_bucket'];
			}
			if ( ! empty( $config['messaging_sender_id'] ) && empty( $config['messagingSenderId'] ) ) {
				$config['messagingSenderId'] = $config['messaging_sender_id'];
			}
			if ( ! empty( $config['measurement_id'] ) && empty( $config['measurementId'] ) ) {
				$config['measurementId'] = $config['measurement_id'];
			}

			return array_merge(
				(array) $config,
				array(
					'id'           => (int) $row['id'],
					'account_name' => $row['account_name'],
					'is_active'    => (int) $row['is_active'],
					'validated'    => (int) $row['validated'],
				)
			);
		}

		return array();
	}

	/**
	 * Save a firebase account.
	 *
	 * @param string $name   Account name.
	 * @param array  $config Account config.
	 * @param int    $active Is active.
	 * @param int    $id     Account ID (for updates).
	 * @return int
	 */
	public function save_account( $name, $config, $active = 1, $id = null ) {
		global $wpdb;
		$table = self::get_accounts_table();
		if ( $active ) {
			WAWP()->db->update_row( 'firebase_accounts', array( 'is_active' => 0 ), array( 'is_active' => 1 ) );
		}

		$data = array(
			'account_name' => $name,
			'config'       => wp_json_encode( $config ),
			'is_active'    => $active ? 1 : 0,
		);

		if ( $id ) {
			WAWP()->db->update_row( 'firebase_accounts', $data, array( 'id' => $id ) );
			$final_id = $id;
		} else {
			WAWP()->db->insert( 'firebase_accounts', $data );
			$final_id = $wpdb->insert_id;
		}

		wp_cache_delete( 'wawp_firebase_accounts', 'wawp_database' );
		wp_cache_delete( 'wawp_firebase_active', 'wawp_database' );

		// Legacy Updates (Only if active).
		if ( $active ) {
			$this->update_wawp_setting( WAWP_Settings_Registry::FIREBASE_SETTINGS, $config );
			$this->update_wawp_setting( WAWP_Settings_Registry::FIREBASE_API_KEY, $config['apiKey'] ?? $config['api_key'] ?? '' );
			$this->update_wawp_setting( WAWP_Settings_Registry::FIREBASE_ACTIVE, $config['active'] ?? 'on' );
		}

		return $final_id;
	}

	/**
	 * Delete a firebase account.
	 *
	 * @param int $id Account ID.
	 * @return array
	 */
	public function handle_delete_account( $id = 0 ) {
		$id = $id ? $id : (int) filter_input( INPUT_POST, 'id', FILTER_SANITIZE_NUMBER_INT );

		if ( ! $id ) {
			return array(
				'success' => false,
				'message' => 'Invalid ID',
			);
		}

		global $wpdb;
		$table = self::get_accounts_table();
		WAWP()->db->delete_row( 'firebase_accounts', array( 'id' => $id ) );
		wp_cache_delete( 'wawp_firebase_accounts', 'wawp_database' );
		wp_cache_delete( 'wawp_firebase_active', 'wawp_database' );

		return array(
			'success' => true,
			'message' => 'Account deleted',
		);
	}

	/**
	 * Toggle active status of an account.
	 *
	 * @param int $id Account ID.
	 * @return array
	 */
	public function handle_toggle_account( $id = 0 ) {
		$id = $id ? $id : (int) filter_input( INPUT_POST, 'id', FILTER_SANITIZE_NUMBER_INT );

		if ( ! $id ) {
			return array(
				'success' => false,
				'message' => 'Invalid ID',
			);
		}

		global $wpdb;
		$table = self::get_accounts_table();
		WAWP()->db->update_row( 'firebase_accounts', array( 'is_active' => 0 ), array( 'is_active' => 1 ) );
		WAWP()->db->update_row( 'firebase_accounts', array( 'is_active' => 1 ), array( 'id' => $id ) );
		wp_cache_delete( 'wawp_firebase_accounts', 'wawp_database' );
		wp_cache_delete( 'wawp_firebase_active', 'wawp_database' );

		// Sync legacy options.
		$active = self::get_active_account();
		$this->update_wawp_setting( WAWP_Settings_Registry::FIREBASE_SETTINGS, $active );
		$this->update_wawp_setting( WAWP_Settings_Registry::FIREBASE_API_KEY, $active['apiKey'] ?? '' );

		return array(
			'success' => true,
			'message' => 'Account activated',
		);
	}
	/**
	 * Validate a firebase account.
	 *
	 * @param int $id Account ID.
	 * @return array
	 */
	public function handle_validate_account( $id = 0 ) {
		$id = $id ? $id : (int) filter_input( INPUT_POST, 'id', FILTER_SANITIZE_NUMBER_INT );

		if ( ! $id ) {
			return array(
				'success' => false,
				'message' => 'Invalid ID',
			);
		}

		global $wpdb;
		$table = self::get_accounts_table();
		WAWP()->db->update_row( 'firebase_accounts', array( 'validated' => 1 ), array( 'id' => $id ) );
		wp_cache_delete( 'wawp_firebase_accounts', 'wawp_database' );
		wp_cache_delete( 'wawp_firebase_active', 'wawp_database' );

		return array(
			'success' => true,
			'message' => 'Account validated',
		);
	}

	/**
	 * Send a test message.
	 *
	 * @param string $phone Phone number.
	 * @throws \Exception If sending fails.
	 * @return array
	 */
	public function handle_send_test( $phone = '' ) {
		$phone = $phone ? $phone : (string) filter_input( INPUT_POST, 'phone', FILTER_DEFAULT );
		if ( empty( $phone ) ) {
			$phone = (string) filter_input( INPUT_POST, 'test_number', FILTER_DEFAULT );
		}

		if ( empty( $phone ) ) {
			return array(
				'success' => false,
				'message' => __( 'Phone number is required.', 'automation-web-platform' ),
			);
		}

		// If this is called from the frontend after a successful client-side send.
		if ( filter_input( INPUT_POST, 'client_success', FILTER_DEFAULT ) ) {

			$this->log_test_activity( $phone, 'Client-side verification initiated via SDK' );

			return array(
				'success' => true,
				'message' => __( 'Client-side test logged.', 'automation-web-platform' ),
			);
		}

		$active_acc = self::get_active_account();
		$api_key    = ! empty( $active_acc['apiKey'] ) ? $active_acc['apiKey'] : $this->get_wawp_setting( WAWP_Settings_Registry::FIREBASE_API_KEY );
		if ( empty( $api_key ) ) {
			return array(
				'success' => false,
				'message' => __( 'Firebase API Key is missing.', 'automation-web-platform' ),
			);
		}

		try {
			$url      = 'https://identitytoolkit.googleapis.com/v1/accounts:sendVerificationCode?key=' . $api_key;
			$response = wp_remote_post(
				$url,
				array(
					'timeout' => 15,
					'headers' => array( 'Content-Type' => 'application/json' ),
					'body'    => wp_json_encode( array( 'phoneNumber' => $phone ) ),
				)
			);

			if ( is_wp_error( $response ) ) {
				throw new \Exception( $response->get_error_message() );
			}

				$body_res   = wp_remote_retrieve_body( $response );
				$is_success = 200 === wp_remote_retrieve_response_code( $response );

				// Unified Log.
				$this->log_action(
					'success',
					'Firebase Test Message',
					array(
						'recipient' => $phone,
						'gateway'   => 'firebase',
					),
					'Admin Test Message'
				);

			if ( $is_success ) {
				return array(
					'success' => true,
					'message' => __( 'Firebase test message successful via Direct API.', 'automation-web-platform' ),
				);
			} else {
				$decoded = json_decode( $body_res, true );
				$err_msg = isset( $decoded['error']['message'] ) ? $decoded['error']['message'] : __( 'Unknown API error', 'automation-web-platform' );

				return array(
					'success' => false,
					// translators: %s: Error message from Firebase SDK.
					'message' => sprintf( __( 'Firebase SDK Error: %s', 'automation-web-platform' ), $err_msg ),
				);
			}
		} catch ( \Exception $e ) {
			return array(
				'success' => false,
				'message' => 'Firebase API Exception: ' . $e->getMessage(),
			);
		}
	}

	/**
	 * Log test activity.
	 *
	 * @param string $phone    Phone number.
	 * @param mixed  $log_data Log data.
	 */
	private function log_test_activity( $phone, $log_data ) {
		$this->log_action(
			'success',
			'Firebase Client-side Test',
			array(
				'recipient' => $phone,
				'gateway'   => 'firebase',
			),
			'Admin Test Message'
		);
	}

	/**
	 * Get React settings data.
	 *
	 * @return array
	 */
	public function get_react_settings_data() {
		return array(
			'allAccounts' => self::list_accounts(),
			'settings'    => self::get_active_account(),
			'nonces'      => array(
				'save'     => wp_create_nonce( 'wawp_nonce' ),
				'delete'   => wp_create_nonce( 'wawp_nonce' ),
				'toggle'   => wp_create_nonce( 'wawp_nonce' ),
				'validate' => wp_create_nonce( 'wawp_nonce' ),
				'test'     => wp_create_nonce( 'wawp_nonce' ),
			),
			'i18n'        => array(
				'firebaseSmsAuth'          => __( 'Firebase SMS Authentication', 'automation-web-platform' ),
				'firebaseSmsAuthDesc'      => __( 'Use Google Firebase to send SMS verification codes globally (Requires API Key).', 'automation-web-platform' ),
				'addAccount'               => __( 'Add Account', 'automation-web-platform' ),
				'firebaseAccounts'         => __( 'Firebase Accounts', 'automation-web-platform' ),
				'manageConfigs'            => __( 'Manage configurations and validation status', 'automation-web-platform' ),
				'defaultSender'            => __( 'Default Sender', 'automation-web-platform' ),
				'accountName'              => __( 'Account Name', 'automation-web-platform' ),
				'systemStatus'             => __( 'System Status', 'automation-web-platform' ),
				'actions'                  => __( 'Actions', 'automation-web-platform' ),
				'selected'                 => __( 'Selected', 'automation-web-platform' ),
				'setDefault'               => __( 'Set Default', 'automation-web-platform' ),
				'active'                   => __( 'Active', 'automation-web-platform' ),
				'pendingSetup'             => __( 'Pending Setup', 'automation-web-platform' ),
				'editAndTest'              => __( 'Edit & Test', 'automation-web-platform' ),
				'noAccountsConfigured'     => __( 'No accounts configured.', 'automation-web-platform' ),
				'editFirebaseAccount'      => __( 'Edit Firebase Account', 'automation-web-platform' ),
				'connectNewProject'        => __( 'Connect New Project', 'automation-web-platform' ),
				'updateProjectCredentials' => __( 'Update your project credentials and validate connection', 'automation-web-platform' ),
				'setupCredentials'         => __( 'Setup your Google Firebase credentials for OTP sending', 'automation-web-platform' ),
				'identity'                 => __( 'Identity', 'automation-web-platform' ),
				'accountFriendlyName'      => __( 'Account Friendly Name', 'automation-web-platform' ),
				'firebaseConfiguration'    => __( 'Firebase Configuration', 'automation-web-platform' ),
				'apiKey'                   => __( 'API Key (Web SDK)', 'automation-web-platform' ),
				'projectId'                => __( 'Project ID', 'automation-web-platform' ),
				'authDomain'               => __( 'Auth Domain', 'automation-web-platform' ),
				'appId'                    => __( 'App ID', 'automation-web-platform' ),
				'storageBucket'            => __( 'Storage Bucket', 'automation-web-platform' ),
				'messagingSenderId'        => __( 'Messaging Sender ID', 'automation-web-platform' ),
				'measurementId'            => __( 'Measurement ID', 'automation-web-platform' ),
				'accountValidationTest'    => __( 'Account Validation Test', 'automation-web-platform' ),
				'realTimeVerification'     => __( 'Real-time Verification', 'automation-web-platform' ),
				'validationTestDesc'       => __( 'Click the icon to send a test OTP. This must succeed to activate the "Active" status for this account.', 'automation-web-platform' ),
				'verify'                   => __( 'Verify', 'automation-web-platform' ),
				'changeNumberOrResend'     => __( 'Change number or resend', 'automation-web-platform' ),
				'close'                    => __( 'Close', 'automation-web-platform' ),
				'deleteConfirm'            => __( 'Are you sure you want to delete this account?', 'automation-web-platform' ),
				'accountDeleted'           => __( 'Account deleted', 'automation-web-platform' ),
				'errorDeleting'            => __( 'Error deleting', 'automation-web-platform' ),
				'errorToggling'            => __( 'Error toggling', 'automation-web-platform' ),
				'enterValidPhone'          => __( 'Enter valid phone number.', 'automation-web-platform' ),
				'missingApiKey'            => __( 'Missing API Key.', 'automation-web-platform' ),
				'smsSent'                  => __( 'SMS sent!', 'automation-web-platform' ),
				'enter6Digit'              => __( 'Enter 6-digit code.', 'automation-web-platform' ),
				'sessionExpired'           => __( 'Session expired.', 'automation-web-platform' ),
				'verified'                 => __( 'Verified!', 'automation-web-platform' ),
				'invalidCode'              => __( 'Invalid code: ', 'automation-web-platform' ),
				'newProject'               => __( 'New Project', 'automation-web-platform' ),
			),
		);
	}
}
