<?php
namespace App\Core;

/**
 * Authentication for external customer-portal contacts. Deliberately
 * separate from Auth (internal users) — see FR-SUP-062, NFR-10, NFR-14.
 */
class PortalAuth
{
    private static ?array $contact = null;

    public static function boot(): void
    {
        Session::start(
            Config::get('session.portal_cookie', 'std_portal_sess'),
            (int)Config::get('session.portal_idle_timeout_minutes', 30)
        );
    }

    public static function attempt(string $email, string $password): bool
    {
        $contact = Database::one(
            'SELECT c.*, cu.name AS customer_name FROM contacts c
             JOIN customers cu ON cu.id = c.customer_id
             WHERE c.email = :email AND c.portal_access = 1 AND c.is_active = 1',
            ['email' => $email]
        );
        if (!$contact || empty($contact['password_hash']) || !password_verify($password, $contact['password_hash'])) {
            return false;
        }
        Session::regenerate();
        $_SESSION['contact_id'] = (int)$contact['id'];
        Database::run('UPDATE contacts SET last_login_at = NOW() WHERE id = :id', ['id' => $contact['id']]);
        self::$contact = $contact;
        return true;
    }

    public static function logout(): void
    {
        Session::destroy();
        self::$contact = null;
    }

    public static function check(): bool
    {
        return !empty($_SESSION['contact_id']);
    }

    public static function contact(): ?array
    {
        if (self::$contact !== null) return self::$contact;
        if (empty($_SESSION['contact_id'])) return null;
        self::$contact = Database::one(
            'SELECT c.*, cu.name AS customer_name FROM contacts c
             JOIN customers cu ON cu.id = c.customer_id WHERE c.id = :id',
            ['id' => $_SESSION['contact_id']]
        );
        return self::$contact;
    }

    public static function id(): ?int
    {
        return isset($_SESSION['contact_id']) ? (int)$_SESSION['contact_id'] : null;
    }

    public static function requireLogin(): callable
    {
        return function () {
            self::boot();
            if (!self::check()) {
                header('Location: ' . Request::basePath() . '/portal/login');
                return false;
            }
            return true;
        };
    }
}
