<?php

declare(strict_types=1);

namespace Instinctor\Core\Auth;

/**
 * WordPress authentication driver.
 *
 * Thin wrapper over WordPress core auth functions.
 * Zero behavior change for WP installs.
 */

if (!defined('ABSPATH')) exit;
class WordPressDriver implements DriverInterface
{
    // Option A (2026-07-05, WP.org compliance): store CUSTOMERS are the plugin's
    // OWN accounts (instinctor_users + instinctor_auth session), never WordPress
    // users. So when no WP user is logged in, resolve the plugin's own customer
    // session. The WP site's admin/users still resolve through the WP calls
    // first, so wp-admin and capability checks (can()/isAdmin()) are untouched.
    // Returns null when the standalone auth classes are not in this build -
    // callers treat that as "no customer session" (guest). A build that drops
    // Auth/Session StandaloneDriver must degrade, never fatal: the 2.1.02 zip
    // shipped without them and every guest Auth::user() call 500'd.
    private static function customerSession(): ?StandaloneDriver
    {
        static $d = null;
        if ($d === null) {
            $d = class_exists(StandaloneDriver::class) ? new StandaloneDriver() : false;
        }
        return $d ?: null;
    }

    public function user(): ?object
    {
        if (function_exists('wp_get_current_user')) {
            $user = wp_get_current_user();
            if ($user && $user->ID > 0) return $user;
        }
        $cs = self::customerSession();
        return $cs ? $cs->user() : null;
    }

    public function userId(): int
    {
        $wpId = function_exists('get_current_user_id') ? (int) get_current_user_id() : 0;
        if ($wpId > 0) return $wpId;
        $cs = self::customerSession();
        return $cs ? $cs->userId() : 0;
    }

    public function check(): bool
    {
        if (function_exists('is_user_logged_in') && is_user_logged_in()) return true;
        $cs = self::customerSession();
        return $cs ? $cs->check() : false;
    }

    public function can(string $capability, mixed ...$args): bool
    {
        if (!function_exists('current_user_can')) {
            return false;
        }
        return (bool) current_user_can($capability, ...$args);
    }

    public function isAdmin(): bool
    {
        return $this->can('manage_options');
    }

    // Option A (2026-07-05): the plugin's OWN users (customers + team) log in
    // against instinctor_users and get an instinctor_auth session — no wp_signon
    // / wp_set_auth_cookie. Delegated to the plugin's StandaloneDriver so the
    // login side matches the resolution side above. The WP site admin's wp-admin
    // login is WordPress core and entirely separate; capability checks
    // (can()/isAdmin()) still hit current_user_can for that WP session.
    public function login(string $email, string $password, bool $remember = false): bool
    {
        $cs = self::customerSession();
        return $cs ? $cs->login($email, $password, $remember) : false;
    }

    public function loginAs(int $userId, bool $remember = false): bool
    {
        $cs = self::customerSession();
        return $cs ? $cs->loginAs($userId, $remember) : false;
    }

    public function logout(): void
    {
        $cs = self::customerSession();
        if ($cs) $cs->logout();
    }
}
