<?php

namespace App\Filters;

use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
use CodeIgniter\Filters\FilterInterface;
use CodeIgniter\Config\Services;

class ApiKey implements FilterInterface
{
    private $rateLimit = 100; // Maksimum 100 request dalam 1 jam

    public function before(RequestInterface $request, $arguments = null)
    {
        $apiKey = $request->getHeaderLine('X-API-KEY');

        if (empty($apiKey) || !$this->isValidApiKey($apiKey)) {
            return Services::response()
                ->setJSON(['error' => 'Unauthorized'])
                ->setStatusCode(401);
        }

        if (!$this->isRateLimitValid($apiKey)) {
            return Services::response()
                ->setJSON(['error' => 'Rate limit exceeded'])
                ->setStatusCode(429);
        }

        $this->logRequest($apiKey, $request->getUri()->getPath(), $request->getIPAddress());
    }

    public function after(RequestInterface $request, ResponseInterface $response, $arguments = null)
    {
        // Tidak ada tindakan setelah response
    }

    private function isValidApiKey(string $apiKey): bool
    {
        $db = \Config\Database::connect();
        $query = $db->table('api_keys')->where('apikey', $apiKey)->get();
        return $query->getNumRows() > 0;
    }

    private function isRateLimitValid(string $apiKey): bool
    {
        $db = \Config\Database::connect();
        $usageTable = $db->table('api_usage');
        $usage = $usageTable->where('apikey', $apiKey)->get()->getRow();

        $currentTime = time();
        $oneHourAgo = $currentTime - 3600;

        if ($usage) {
            $lastRequestTime = strtotime($usage->last_request);
            if ($lastRequestTime > $oneHourAgo && $usage->request_count >= $this->rateLimit) {
                return false;
            }

            // Perbarui penggunaan API
            $usageTable->where('apikey', $apiKey)->update([
                'request_count' => ($lastRequestTime > $oneHourAgo) ? $usage->request_count + 1 : 1,
                'last_request' => date('Y-m-d H:i:s', $currentTime),
            ]);
        } else {
            // Tambahkan entri baru
            $usageTable->insert([
                'apikey' => $apiKey,
                'request_count' => 1,
                'last_request' => date('Y-m-d H:i:s', $currentTime),
            ]);
        }

        return true;
    }

    private function logRequest(string $apiKey, string $endpoint, string $ipAddress)
    {
        $db = \Config\Database::connect();
        $db->table('api_logs')->insert([
            'apikey' => $apiKey,
            'endpoint' => $endpoint,
            'ip_address' => $ipAddress,
        ]);
    }
}
