<?php

namespace App\Core;

require_once __DIR__ . '/TenantPolicy.php';

/**
 * إدارة سياق المختبر (Tenant) في نظام Multi-Tenant
 */
class Tenant
{
    private static ?int $currentId = null;
    private static ?array $settings = null;

    /** @var bool نطاق فرعي يشير لمختبر غير موجود أو موقوف — لا يُستخدم الافتراضي 1 */
    private static $subdomainRejected = false;

    public static function setId(int $id): void
    {
        self::$currentId = $id;
        self::$settings = null;
    }

    public static function isSubdomainRejected(): bool
    {
        return self::$subdomainRejected;
    }

    public static function id(): int
    {
        if (self::$currentId !== null) {
            return self::$currentId;
        }
        return (int)($_SESSION['tenant_id'] ?? 1);
    }

    /**
     * إزالة جلسة مستخدم المختبر عند إبطال المختبر أو الاشتراك
     */
    private static function clearLabUserSession(): void
    {
        $keys = [
            'user_id', 'user_name', 'role_id', 'tenant_id', 'user_branch_id', 'permissions',
            'last_activity', 'unified_logged_in', 'unified_available_portals',
            'unified_active_portal', 'unified_doctor_context', 'unified_principal_name',
        ];
        foreach ($keys as $k) {
            unset($_SESSION[$k]);
        }
    }

    public static function resolve(\PDO $db): int
    {
        self::$subdomainRejected = false;

        if (self::$currentId !== null) {
            return self::$currentId;
        }

        $subdomain = self::extractSubdomain();

        // أولوية للنطاق الفرعي: لا نسقط إلى المختبر 1 إذا كان الاسم غير صالح
        if ($subdomain !== null && $subdomain !== '') {
            try {
                $stmt = $db->prepare('SELECT id, status FROM tenants WHERE slug = ? LIMIT 1');
                $stmt->execute([$subdomain]);
                $row = $stmt->fetch();
                if (!$row) {
                    self::$subdomainRejected = true;
                    self::$currentId = 0;
                    return 0;
                }
                if (!in_array($row['status'], ['active', 'trial'], true)) {
                    self::$subdomainRejected = true;
                    self::$currentId = 0;
                    return 0;
                }
                $tid = (int)$row['id'];
                if (!TenantPolicy::subscriptionAllowsAccess($db, $tid)) {
                    self::$subdomainRejected = true;
                    self::$currentId = 0;
                    return 0;
                }
                self::setId($tid);
                $_SESSION['tenant_id'] = $tid;
                return $tid;
            } catch (\Throwable $e) {
                self::$subdomainRejected = true;
                self::$currentId = 0;
                return 0;
            }
        }

        // بدون نطاق فرعي: الجلسة أو الافتراضي
        if (isset($_SESSION['tenant_id'])) {
            $tid = (int)$_SESSION['tenant_id'];
            if ($tid > 0 && !TenantPolicy::labAccessAllowed($db, $tid)) {
                self::clearLabUserSession();
                $_SESSION['login_error'] = 'تم إيقاف المختبر أو انتهى الاشتراك. راجع الإدارة.';
                $tid = 1;
                $_SESSION['tenant_id'] = 1;
            }
            self::$currentId = $tid;
            return $tid;
        }

        self::$currentId = 1;
        $_SESSION['tenant_id'] = 1;
        return 1;
    }

    private static function extractSubdomain(): ?string
    {
        $host = $_SERVER['HTTP_HOST'] ?? '';
        $parts = explode('.', $host);
        if (count($parts) >= 3 && $parts[0] !== 'www' && strlen($parts[0]) > 1) {
            return strtolower($parts[0]);
        }
        return null;
    }

    public static function getSettings(\PDO $db): array
    {
        if (self::$settings !== null) {
            return self::$settings;
        }
        $tid = self::id();
        if ($tid <= 0) {
            $tid = 1;
        }
        $settings = [
            'lab_name' => 'مختبر تحاليل',
            'lab_phone' => '',
            'lab_address' => '',
            'logo_url' => '',
            'primary_color' => '#0d9488',
        ];
        try {
            $stmt = $db->prepare('SELECT setting_key, setting_value FROM settings WHERE tenant_id = ? AND setting_key IN ("lab_name","lab_phone","lab_address")');
            $stmt->execute([$tid]);
            foreach ($stmt->fetchAll() as $r) {
                $settings[$r['setting_key']] = (string)$r['setting_value'];
            }
            $stmt = $db->prepare('SELECT logo_url, primary_color FROM tenants WHERE id = ?');
            $stmt->execute([$tid]);
            $t = $stmt->fetch();
            if ($t) {
                $settings['logo_url'] = (string)($t['logo_url'] ?? '');
                $settings['primary_color'] = (string)($t['primary_color'] ?? '#0d9488');
            }
        } catch (\Throwable $e) {
        }
        self::$settings = $settings;
        return $settings;
    }

    /**
     * جداول معروفة بعمود tenant_id — أي اسم جدول غير مدرج قد يحتاج شرطاً يدوياً في الاستعلام.
     */
    public static function whereClause(string $table): string
    {
        $cols = [
            'users', 'patients', 'doctors', 'branches', 'tests', 'test_categories', 'inventory_items',
            'lab_orders', 'settings', 'devices', 'device_tests', 'audit_log', 'blocked_ips',
        ];
        if (in_array($table, $cols, true)) {
            return " $table.tenant_id = " . self::id();
        }
        try {
            $config = @require __DIR__ . '/../../config/config.php';
            if (!empty($config['debug'])) {
                @error_log('Tenant::whereClause: unknown table "' . $table . '" — add tenant filter manually or extend Tenant::whereClause list.');
            }
        } catch (\Throwable $e) {
        }
        return " 1=1 ";
    }
}
