<?php
/**
 * User Manager Class.
 *
 * @package automation-web-platform
 */

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

/**
 * WAWP_User_Manager Class
 * Handles user-specific data operations and synchronization.
 */
class WAWP_User_Manager {
	use WAWP_Phone_Helper_Trait;

	/**
	 * Get the user info table name.
	 *
	 * @return string
	 */
	public function get_table_name() {
		return WAWP()->db->tables['user_info'];
	}

	/**
	 * Insert user information into the custom table.
	 *
	 * @param int    $user_id    User ID.
	 * @param string $first_name First name.
	 * @param string $last_name  Last name.
	 * @param string $email      Email address.
	 * @param string $phone      Phone number.
	 * @param string $password   Password.
	 * @return int|bool
	 */
	public function insert_user_info( $user_id, $first_name, $last_name, $email, $phone, $password ) {
		$data = array(
			'first_name' => sanitize_text_field( $first_name ),
			'last_name'  => sanitize_text_field( $last_name ),
			'email'      => sanitize_email( $email ),
			'phone'      => self::get_digits_only( $phone ),
			'password'   => $password,
		);

		wp_cache_delete( 'wawp_user_info_' . (int) $user_id, 'wawp_users' );
		wp_cache_delete( 'wawp_user_phone_' . (int) $user_id, 'wawp_users' );

		// Check if the user already has a profile row in user_info.
		$existing = $this->get_user_info( $user_id );
		if ( $existing ) {
			$data['updated_at'] = current_time( 'mysql' );
			return WAWP()->db->update_row( 'user_info', $data, array( 'user_id' => (int) $user_id ) );
		} else {
			$data['user_id']    = (int) $user_id;
			$data['created_at'] = current_time( 'mysql' );
			return WAWP()->db->insert( 'user_info', $data );
		}
	}

	/**
	 * Get user information from the custom table.
	 *
	 * @param int $user_id User ID.
	 * @return object|null
	 */
	public function get_user_info( $user_id ) {
		$cache_key = 'wawp_user_info_' . (int) $user_id;
		$row       = wp_cache_get( $cache_key, 'wawp_users' );

		if ( false === $row ) {
			global $wpdb;
			$query = $wpdb->prepare( 'SELECT * FROM %i WHERE user_id = %d', $this->get_table_name(), $user_id );
			$row   = WAWP()->db->get_results_cached( $query, $cache_key, 'wawp_users', 300 );
		}

		if ( is_array( $row ) ) {
			$row = ! empty( $row ) ? (object) ( isset( $row[0] ) ? $row[0] : $row ) : null;
		}

		return $row;
	}

	/**
	 * Update or insert user profile data.
	 *
	 * @param int    $user_id    User ID.
	 * @param string $first_name First name.
	 * @param string $last_name  Last name.
	 * @param string $email      Email address.
	 * @param string $phone      Phone number.
	 * @param string $password   Password.
	 * @return int|bool
	 */
	public function upsert_user_profile( $user_id, $first_name, $last_name, $email, $phone = '', $password = '' ) {
		$data = array(
			'first_name' => sanitize_text_field( $first_name ),
			'last_name'  => sanitize_text_field( $last_name ),
			'email'      => sanitize_email( $email ),
		);

		if ( ! empty( $phone ) ) {
			$data['phone'] = self::get_digits_only( $phone );
		}

		if ( ! empty( $password ) ) {
			$data['password'] = $password;
		}

		wp_cache_delete( 'wawp_user_info_' . (int) $user_id, 'wawp_users' );
		wp_cache_delete( 'wawp_user_phone_' . (int) $user_id, 'wawp_users' );

		// Check if the user already has a profile row in user_info.
		$existing = $this->get_user_info( $user_id );
		if ( $existing ) {
			$data['updated_at'] = current_time( 'mysql' );
			return WAWP()->db->update_row( 'user_info', $data, array( 'user_id' => (int) $user_id ) );
		} else {
			$data['user_id']    = (int) $user_id;
			$data['created_at'] = current_time( 'mysql' );
			return WAWP()->db->insert( 'user_info', $data );
		}
	}

	/**
	 * Update user phone number.
	 *
	 * @param int    $user_id User ID.
	 * @param string $phone   Phone number.
	 * @return int|bool
	 */
	public function update_user_phone( $user_id, $phone ) {
		wp_cache_delete( 'wawp_user_info_' . (int) $user_id, 'wawp_users' );
		wp_cache_delete( 'wawp_user_phone_' . (int) $user_id, 'wawp_users' );

		return WAWP()->db->update_row(
			'user_info',
			array(
				'phone'      => self::get_digits_only( $phone ),
				'updated_at' => current_time( 'mysql' ),
			),
			array( 'user_id' => $user_id )
		);
	}

	/**
	 * Update user verification status.
	 *
	 * @param int    $user_id User ID.
	 * @param string $method  Verification method.
	 * @param bool   $status  Verification status.
	 */
	public function update_user_verification( $user_id, $method, $status ) {
		// Firebase SMS and WhatsApp are both phone-based verification, sharing the same DB columns.
		if ( 'firebase' === $method ) {
			$method = 'whatsapp';
		}
		$col          = ( 'email' === $method ) ? 'otp_verification_email' : 'otp_verification_whatsapp';
		$verified_col = ( 'email' === $method ) ? 'email_verified' : 'whatsapp_verified';
		wp_cache_delete( 'wawp_user_info_' . (int) $user_id, 'wawp_users' );
		wp_cache_delete( "wawp_user_verify_{$user_id}_{$method}", 'wawp_users' );

		// Check if user row exists in user_info table.
		$info = $this->get_user_info( $user_id );
		if ( ! $info ) {
			$user = get_userdata( $user_id );
			if ( $user ) {
				$first_name = $user->first_name;
				$last_name  = $user->last_name;
				$email      = $user->user_email;
				$phone      = get_user_meta( $user_id, 'billing_phone', true );
				if ( empty( $phone ) ) {
					$phone = get_user_meta( $user_id, 'phone', true );
				}
				$this->upsert_user_profile( $user_id, $first_name, $last_name, $email, $phone );
			}
		}

		WAWP()->db->update_row(
			'user_info',
			array(
				$col          => $status ? 1 : 0,
				$verified_col => $status ? 'Verified' : 'Not Verified',
			),
			array( 'user_id' => $user_id )
		);
	}

	/**
	 * Get user verification status.
	 *
	 * @param int    $user_id User ID.
	 * @param string $method  Verification method.
	 * @return bool
	 */
	public function get_verification_status( $user_id, $method = 'whatsapp' ) {
		if ( 'firebase' === $method ) {
			$method = 'whatsapp';
		}
		$cache_key = "wawp_user_verify_{$user_id}_{$method}";
		$status    = wp_cache_get( $cache_key, 'wawp_users' );

		if ( false !== $status ) {
			return (bool) $status;
		}

		global $wpdb;
		$col    = ( 'email' === $method ) ? 'otp_verification_email' : 'otp_verification_whatsapp';
		$query  = $wpdb->prepare( 'SELECT %i FROM %i WHERE user_id = %d', $col, $this->get_table_name(), $user_id );
		$status = (bool) WAWP()->db->get_var( $query );

		wp_cache_set( $cache_key, $status, 'wawp_users', 300 );

		return $status;
	}

	/**
	 * Get the phone number for a user from custom table or user meta.
	 *
	 * @param int $user_id User ID.
	 * @return string
	 */
	public function get_user_phone( $user_id ) {
		if ( ! $user_id ) {
			return '';
		}
		global $wpdb;
		$query = $wpdb->prepare( 'SELECT phone FROM %i WHERE user_id = %d', $this->get_table_name(), $user_id );
		$phone = WAWP()->db->get_var( $query );
		return ! empty( $phone ) ? $phone : '';
	}
	/**
	 * Check if a phone number is already taken by another user.
	 *
	 * @param string $phone The phone number to check.
	 * @param int    $exclude_user_id Optional. User ID to exclude from the check.
	 * @return int|null User ID if taken, null otherwise.
	 */
	public function is_phone_taken( $phone, $exclude_user_id = 0 ) {
		$phone     = self::get_digits_only( $phone );
		$cache_key = 'wawp_phone_taken_' . md5( $phone . '_' . $exclude_user_id );
		$user_id   = wp_cache_get( $cache_key, 'wawp_users' );

		if ( false !== $user_id ) {
			return $user_id ? (int) $user_id : null;
		}

		global $wpdb;
		if ( $exclude_user_id > 0 ) {
			$query = $wpdb->prepare( 'SELECT user_id FROM %i WHERE phone = %s AND user_id != %d LIMIT 1', $this->get_table_name(), $phone, $exclude_user_id );
		} else {
			$query = $wpdb->prepare( 'SELECT user_id FROM %i WHERE phone = %s LIMIT 1', $this->get_table_name(), $phone );
		}

		$user_id = WAWP()->db->get_var( $query );

		wp_cache_set( $cache_key, $user_id ? (int) $user_id : 0, 'wawp_users', 300 );

		return $user_id ? (int) $user_id : null;
	}

	/**
	 * Get user by phone number.
	 *
	 * @param string $phone Phone number.
	 * @return WP_User|null
	 */
	public function get_user_by_phone( $phone ) {
		$user_id = $this->is_phone_taken( $phone );
		if ( $user_id ) {
			return get_userdata( $user_id );
		}

		// Fallback to meta search if not in custom table.
		$digits = self::get_digits_only( $phone );
		if ( empty( $digits ) ) {
			return null;
		}

		global $wpdb;
		$user_ids = WAWP()->db->get_col_cached(
			$wpdb->prepare(
				"SELECT user_id FROM %i WHERE (meta_key = %s OR meta_key = 'billing_phone') AND (meta_value = %s OR meta_value = %s) LIMIT 1",
				$wpdb->usermeta,
				WAWP_Settings_Registry::USER_PHONE_META_KEY,
				$digits,
				'+' . $digits
			),
			'user_meta_phone_' . $digits,
			'wawp_users',
			300
		);

		return ! empty( $user_ids ) ? get_userdata( $user_ids[0] ) : null;
	}
	/**
	 * Delete user info from the custom table.
	 *
	 * @param int $user_id User ID.
	 * @return int|bool Number of rows deleted or false on failure.
	 */
	public function delete_user_info( $user_id ) {
		wp_cache_delete( 'wawp_user_info_' . (int) $user_id, 'wawp_users' );
		wp_cache_delete( 'wawp_user_phone_' . (int) $user_id, 'wawp_users' );

		return WAWP()->db->delete_row( 'user_info', array( 'user_id' => $user_id ) );
	}
}
