<?php
/**
 * Session Manager class for handling chat sessions properly
 *
 * This class fixes the issues with session management:
 * 1. Logged-in users showing as Anonymous
 * 2. Each browser creating new sessions
 * 3. Agent messages not appearing in user chat
 *
 * @package Askany
 * @since 1.0.0
 */

namespace Askany;

/**
 * Session Manager class
 */
class SessionManager {
	/**
	 * Database instance.
	 *
	 * @var Database
	 */
	private $database;

	/**
	 * Constructor.
	 *
	 * @param Database $database Database instance.
	 */
	public function __construct( $database ) {
		$this->database = $database;
	}

	/**
	 * Get or create a proper session ID for the current user.
	 *
	 * @param string $provided_session_id Session ID provided by frontend.
	 * @return string The session ID to use.
	 */
	public function get_or_create_session_id( $provided_session_id = '' ) {
		$current_user_id = get_current_user_id();

		// Debug: Log what we received
		// error_log('SessionManager Debug: Provided session_id: ' . $provided_session_id);
		// error_log('SessionManager Debug: Current user ID: ' . $current_user_id);

		if ( $current_user_id ) {
			// Logged-in user: use consistent session ID
			$session_id = 'user_' . $current_user_id;

			// If they provided an anonymous session, merge it
			if ( ! empty($provided_session_id) && strpos($provided_session_id, 'anon_') === 0 ) {
				// error_log('SessionManager Debug: Merging anonymous session to user session');
				$this->merge_anonymous_session( $provided_session_id, $session_id, $current_user_id );
			}

			// error_log('SessionManager Debug: Returning user session_id: ' . $session_id);
			return $session_id;
		} else {
			// Anonymous user: ALWAYS use provided session if available
			if ( ! empty($provided_session_id) ) {
				// error_log('SessionManager Debug: Using provided anonymous session_id: ' . $provided_session_id);
				return $provided_session_id;
			} else {
				// This shouldn't happen with the new frontend logic, but fallback
				$fallback_session = 'anon_' . uniqid() . '_' . time();
				// error_log('SessionManager Debug: Creating fallback session_id: ' . $fallback_session);
				return $fallback_session;
			}
		}
	}

	/**
	 * Merge anonymous session with user session.
	 *
	 * @param string $anonymous_session_id The anonymous session ID.
	 * @param string $user_session_id The user session ID.
	 * @param int    $user_id The user ID.
	 */
	private function merge_anonymous_session( $anonymous_session_id, $user_session_id, $user_id ) {
		global $wpdb;

		$sessions_table = $wpdb->prefix . 'askany_chat_sessions';
		$messages_table = $wpdb->prefix . 'askany_chat_messages';

		// Check if anonymous session exists
		$anonymous_session = $wpdb->get_row($wpdb->prepare(
			"SELECT * FROM $sessions_table WHERE session_id = %s",
			$anonymous_session_id
		));

		if ( $anonymous_session ) {
			// Check if user session already exists
			$user_session = $wpdb->get_row($wpdb->prepare(
				"SELECT * FROM $sessions_table WHERE session_id = %s",
				$user_session_id
			));

			if ( $user_session ) {
				// Merge messages from anonymous session to user session
				$wpdb->update(
					$messages_table,
					array( 'session_id' => $user_session_id ),
					array( 'session_id' => $anonymous_session_id ),
					array( '%s' ),
					array( '%s' )
				);

				// Delete anonymous session
				$wpdb->delete(
					$sessions_table,
					array( 'session_id' => $anonymous_session_id ),
					array( '%s' )
				);
			} else {
				// Convert anonymous session to user session
				$wpdb->update(
					$sessions_table,
					array(
						'session_id' => $user_session_id,
						'user_id' => $user_id,
					),
					array( 'session_id' => $anonymous_session_id ),
					array( '%s', '%d' ),
					array( '%s' )
				);

				// Update messages
				$wpdb->update(
					$messages_table,
					array(
						'session_id' => $user_session_id,
						'sender_id' => $user_id,
					),
					array(
						'session_id' => $anonymous_session_id,
						'sender_type' => 'user',
					),
					array( '%s', '%d' ),
					array( '%s', '%s' )
				);
			}
		}
	}

	/**
	 * Create or update a chat session with proper user information.
	 *
	 * @param string $session_id The session ID.
	 * @param array  $user_data Optional user data.
	 * @return int|false The session database ID or false on failure.
	 */
	public function create_or_update_session( $session_id, $user_data = array() ) {
		global $wpdb;

		$sessions_table = $wpdb->prefix . 'askany_chat_sessions';
		$current_user_id = get_current_user_id();
		$user_ip = '';
		if (isset($_SERVER['REMOTE_ADDR'])) {
			$user_ip = sanitize_text_field(wp_unslash($_SERVER['REMOTE_ADDR']));
		}

		// Get user information
		$user_name = '';
		$user_email = '';

		if ( $current_user_id ) {
			$user = get_userdata( $current_user_id );
			if ( $user ) {
				$user_name = $user->display_name;
				$user_email = $user->user_email;
			}
		} else {
			// Use provided user data for anonymous users
			$user_name = $user_data['name'] ?? '';
			$user_email = $user_data['email'] ?? '';

			// If no user name provided, generate one from session ID
			if ( empty($user_name) && strpos($session_id, 'anon_') === 0 ) {
				// Extract a short ID from the session for display
				$session_parts = explode('_', $session_id);
				if ( count($session_parts) >= 2 ) {
					$short_id = substr($session_parts[1], 0, 6);
					$user_name = 'Anonymous_' . $short_id;
				} else {
					$user_name = 'Anonymous User';
				}
			}
		}

		// Check if session exists
		$existing = $wpdb->get_var($wpdb->prepare(
			"SELECT id FROM $sessions_table WHERE session_id = %s",
			$session_id
		));

		$session_data = array(
			'session_id' => $session_id,
			'user_id' => $current_user_id ?: null,
			'user_name' => $user_name,
			'user_email' => $user_email,
			'user_ip' => $user_ip,
			'status' => 'active',
			'is_ai_handled' => 1,
			'last_activity' => current_time('mysql'),
		);

		if ( $existing ) {
			// Update existing session
			$wpdb->update(
				$sessions_table,
				$session_data,
				array( 'id' => $existing ),
				array( '%s', '%d', '%s', '%s', '%s', '%s', '%d', '%s' ),
				array( '%d' )
			);
			return $existing;
		} else {
			// Create new session
			$session_data['created_at'] = current_time('mysql');
			$result = $wpdb->insert(
				$sessions_table,
				$session_data,
				array( '%s', '%d', '%s', '%s', '%s', '%s', '%d', '%s', '%s' )
			);
			return $result ? $wpdb->insert_id : false;
		}
	}

	/**
	 * Get session display name for admin interface.
	 *
	 * @param object $session The session object.
	 * @return string The display name.
	 */
	public function get_session_display_name( $session ) {
		if ( $session->user_id ) {
			// Logged-in user
			if ( $session->user_name ) {
				return $session->user_name;
			} else {
				$user = get_userdata( $session->user_id );
				return $user ? $user->display_name : 'User #' . $session->user_id;
			}
		} else {
			// Anonymous user
			if ( $session->user_name ) {
				return $session->user_name . ' (Guest)';
			} else {
				return 'Anonymous User';
			}
		}
	}
}
