<?php

declare(strict_types=1);

namespace App\Controllers\Api;

use Core\Database;

abstract class BaseApiController
{
    protected Database $db;

    public function __construct()
    {
        $this->db = Database::getInstance();
        header('Content-Type: application/json');
        header('Access-Control-Allow-Origin: *');
        header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS');
        header('Access-Control-Allow-Headers: Authorization, Content-Type');
        if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
            http_response_code(204); exit;
        }
    }

    protected function ok(mixed $data = null, string $message = ''): void
    {
        echo json_encode(['success' => true, 'data' => $data, 'message' => $message]);
        exit;
    }

    protected function fail(string $message, int $code = 400): void
    {
        http_response_code($code);
        echo json_encode(['success' => false, 'data' => null, 'message' => $message]);
        exit;
    }

    protected function body(): array
    {
        $raw = file_get_contents('php://input');
        return (array) json_decode($raw ?: '{}', true);
    }

    protected function post(string $key, mixed $default = ''): mixed
    {
        $body = $this->body();
        // try JSON body first, then $_POST
        return $body[$key] ?? $_POST[$key] ?? $default;
    }

    protected function get(string $key, mixed $default = ''): mixed
    {
        return $_GET[$key] ?? $default;
    }

    // ── Auth ─────────────────────────────────────────────────────────────────

    protected function bearerToken(): ?string
    {
        $hdr = $_SERVER['HTTP_AUTHORIZATION']
            ?? $_SERVER['REDIRECT_HTTP_AUTHORIZATION']
            ?? '';

        // Apache/mod_php often exposes the header only via getallheaders(),
        // especially after the front-controller rewrite to index.php.
        if ($hdr === '' && function_exists('getallheaders')) {
            foreach (getallheaders() as $k => $v) {
                if (strcasecmp($k, 'Authorization') === 0) { $hdr = $v; break; }
            }
        }
        if ($hdr === '' && function_exists('apache_request_headers')) {
            foreach (apache_request_headers() as $k => $v) {
                if (strcasecmp($k, 'Authorization') === 0) { $hdr = $v; break; }
            }
        }

        if (preg_match('/Bearer\s+(.+)/i', $hdr, $m)) return trim($m[1]);
        return null;
    }

    protected function authUser(): ?array
    {
        $token = $this->bearerToken();
        if (!$token) return null;
        return $this->db->fetchOne(
            "SELECT u.*, t.user_id AS _tid
               FROM api_tokens t
               JOIN users u ON u.id = t.user_id
              WHERE t.token = ? AND t.expires_at > NOW() AND u.is_active = 1",
            [$token]
        ) ?: null;
    }

    protected function requireAuth(): array
    {
        $user = $this->authUser();
        if (!$user) $this->fail('Unauthorised. Please login.', 401);
        return $user;
    }

    protected function customerId(array $user): int
    {
        $c = $this->db->fetchOne(
            "SELECT id FROM customers WHERE user_id = ?", [$user['id']]
        );
        return $c ? (int)$c['id'] : 0;
    }
}
