<?php
declare(strict_types=1);

namespace App\Controllers\Api;

use App\Models\Tenant;
use App\Models\User;
use Core\Controller;
use Core\DB;
use Core\Tool;

final class AuthController extends Controller
{
    public function middleware(): array
    {
        return [];
    }

    public function login(): void
    {
        if (($_SERVER['REQUEST_METHOD'] ?? '') !== 'POST') {
            $this->json(['error' => 'POST required'], 405);
        }
        $body = $this->input();
        $username = trim((string) ($body['username'] ?? ''));
        $password = (string) ($body['password'] ?? '');
        $tenantId = (int) ($body['tenant_id'] ?? 0);
        // Convenience for mobile: allow tenant subdomain instead of id.
        if ($tenantId <= 0 && !empty($body['tenant'])) {
            $t = DB::one('SELECT tenant_id FROM tenants WHERE subdomain = :s AND status = "active"', ['s' => $body['tenant']]);
            if ($t) $tenantId = (int) $t['tenant_id'];
        }

        if ($tenantId <= 0 || $username === '' || $password === '') {
            $this->json(['error' => 'tenant_id (or tenant), username, and password are required'], 422);
        }

        $tenant = Tenant::findById($tenantId);
        if (!$tenant || $tenant['status'] !== 'active') {
            $this->json(['error' => 'Tenant not found'], 404);
        }

        $user = User::verify($tenantId, $username, $password);
        if (!$user) $this->json(['error' => 'Invalid credentials'], 401);

        $raw = Tool::randomToken();
        $hash = Tool::hashToken($raw);
        $expires = date('Y-m-d H:i:s', time() + 60 * 60 * 24 * 30); // 30 days

        DB::insert('personal_access_tokens', [
            'tenant_id'   => $tenantId,
            'user_id'     => $user['user_id'],
            'token_hash'  => $hash,
            'name'        => (string) ($body['device_name'] ?? 'mobile'),
            'device_id'   => (string) ($body['device_id']   ?? '') ?: null,
            'platform'    => (string) ($body['platform']    ?? '') ?: null,
            'app_version' => (string) ($body['app_version'] ?? '') ?: null,
            'expires_at'  => $expires,
        ]);

        $this->json([
            'token'      => $raw,
            'expires_at' => $expires,
            'user' => [
                'user_id'   => (int) $user['user_id'],
                'tenant_id' => $tenantId,
                'username'  => $user['username'],
                'full_name' => trim(($user['f_name'] ?? '') . ' ' . ($user['l_name'] ?? '')),
                'email'     => $user['email'] ?? null,
                'role'      => $user['role'] ?? null,
                'role_code' => $user['role_code'] ?? null,
            ],
            'tenant' => [
                'tenant_id' => (int) $tenant['tenant_id'],
                'name'      => $tenant['name'],
                'subdomain' => $tenant['subdomain'],
            ],
        ]);
    }

    public function logout(): void
    {
        // Requires ApiToken middleware to have populated $_SESSION.
        // But since middleware is empty here, we require the token to be presented explicitly.
        $header = $_SERVER['HTTP_AUTHORIZATION'] ?? '';
        if (function_exists('getallheaders') && $header === '') {
            $all = getallheaders();
            $header = $all['Authorization'] ?? $all['authorization'] ?? '';
        }
        if (!preg_match('/Bearer\s+([A-Za-z0-9_\-\.]+)/i', $header, $m)) {
            $this->json(['error' => 'Missing bearer token'], 401);
        }
        $hash = Tool::hashToken($m[1]);
        DB::run(
            'UPDATE personal_access_tokens SET revoked_at = NOW() WHERE token_hash = :h AND revoked_at IS NULL',
            ['h' => $hash]
        );
        $this->json(['success' => true]);
    }

    public function me(): void
    {
        // Reuse ApiToken middleware for this one.
        (new \App\Middleware\ApiToken())->handle(['kind' => 'api', 'controller' => __CLASS__, 'action' => 'me']);
        $this->json(['user' => $_SESSION['user'] ?? null]);
    }
}
