<?php
/**
 * UserSessionsTable — Tracked user login sessions.
 *
 * @package UltraguardPro\modules\loginlimiter\db
 * @since   6.5.0
 */

namespace UltraguardPro\modules\loginlimiter\db;

use UltraguardPro\db\BaseTable;

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

class UserSessionsTable extends BaseTable {

    protected $table_name  = 'ultraguard_user_sessions';
    protected $cache_group = 'ultraguard_user_sessions';

    public function get_defaults(): array {
        return [
            'id'            => 0,
            'user_id'       => 0,
            'session_token' => '',
            'ip_address'    => '',
            'user_agent'    => null,
            'is_active'     => 1,
            'last_active'   => '',
            'expires_at'    => '',
            'created_at'    => '',
        ];
    }

    protected function validate_data( $data ) {
        if ( empty( $data['user_id'] ) || empty( $data['session_token'] ) ) { return false; }
        return $data;
    }

    protected function sanitize_data( $data ): array {
        $out = [];
        foreach ( $data as $k => $v ) {
            $out[ $k ] = match ( $k ) {
                'user_id'   => absint( $v ),
                'is_active' => (int) (bool) $v,
                'user_agent'=> is_null( $v ) ? null : sanitize_textarea_field( (string) $v ),
                default     => is_string( $v ) ? sanitize_text_field( $v ) : $v,
            };
        }
        return $out;
    }

    protected function get_searchable_fields(): array {
        return [ 'ip_address', 'session_token' ];
    }

    // ── Domain methods ─────────────────────────────────────────────────────────

    /**
     * Revoke a single session by row ID.
     *
     * @param  int $id
     * @return bool
     */
    public function revoke( int $id ): bool {
        return $this->update( $id, [ 'is_active' => 0 ] );
    }

    /**
     * Revoke all active sessions for a given user.
     *
     * @param  int $user_id
     * @return bool
     */
    public function revoke_all_for_user( int $user_id ): bool {
        return (bool) $this->update_where( [ 'is_active' => 0 ], [ 'user_id' => $user_id ] );
    }

    /**
     * Get active sessions for a specific user.
     *
     * @param  int $user_id
     * @param  int $limit
     * @return array
     */
    public function get_active_for_user( int $user_id, int $limit = 50 ): array {
        return $this->get_by( [ 'user_id' => $user_id, 'is_active' => 1 ], $limit, 'last_active', 'DESC' );
    }

    /**
     * Prune expired sessions.
     *
     * @return int  Rows deleted.
     */
    public function cleanup_expired(): int {
        return $this->delete_where( [ 'expires_at <' => current_time( 'mysql', true ), 'is_active' => 0 ] );
    }
}
