<?php
declare(strict_types=1);

namespace App\Middleware;

use Core\Middleware;
use Core\Session;

/**
 * Populates $_SESSION['tenant_id'] on every request so downstream queries can
 * scope by tenant. This is the ONE and ONLY place that resolves "which tenant
 * is this request for" — the rest of the app reads $_SESSION['tenant_id'].
 *
 * Resolution order (first non-null wins):
 *   1. TENANT_MODE=header — read from Host subdomain (e.g. orchid.orchview2.local)
 *   2. Logged-in user's tenant_id (Session::user()['tenant_id'])
 *   3. TENANT_DEFAULT_ID from .env (dev fallback)
 *
 * When we're ready to move from single-URL + dropdown to per-tenant subdomains,
 * flip TENANT_MODE=header in .env — no other code changes.
 *
 * On API requests, ApiToken middleware runs first and sets Session::user(), so
 * by the time TenantScope runs the tenant_id from the token is available.
 */
final class TenantScope implements Middleware
{
    public function handle(array $context): void
    {
        $mode = (string) env('TENANT_MODE', 'column');
        $tenantId = null;

        if ($mode === 'header') {
            $tenantId = self::resolveFromHost();
        }

        if ($tenantId === null) {
            $user = Session::user();
            if (!empty($user['tenant_id'])) {
                $tenantId = (int) $user['tenant_id'];
            }
        }

        if ($tenantId === null) {
            $default = env('TENANT_DEFAULT_ID', null);
            if ($default !== null && $default !== '') {
                $tenantId = (int) $default;
            }
        }

        if ($tenantId === null || $tenantId <= 0) {
            if (($context['kind'] ?? 'web') === 'api') {
                json_response(['error' => 'Tenant not resolved'], 400);
            }
            Session::flash('login_error', 'Company not resolved. Contact admin.');
            redirect('/Login');
        }

        $_SESSION['tenant_id'] = $tenantId;
    }

    /**
     * Extract tenant from Host subdomain. Example:
     *   orchid.orchview2.local  → look up tenants.subdomain = 'orchid'
     * Returns null if no match — caller falls back to next resolution step.
     */
    private static function resolveFromHost(): ?int
    {
        $host = strtolower((string) ($_SERVER['HTTP_HOST'] ?? ''));
        if ($host === '') {
            return null;
        }
        $host = explode(':', $host)[0];
        $parts = explode('.', $host);
        if (count($parts) < 3) {
            return null;
        }
        $subdomain = $parts[0];
        if (in_array($subdomain, ['www', 'localhost'], true)) {
            return null;
        }

        try {
            $row = \Core\DB::one(
                'SELECT tenant_id FROM tenants WHERE subdomain = :s AND status = :st LIMIT 1',
                ['s' => $subdomain, 'st' => 'active']
            );
        } catch (\Throwable $e) {
            error_log('TenantScope host lookup failed: ' . $e->getMessage());
            return null;
        }
        return $row ? (int) $row['tenant_id'] : null;
    }
}
