<?php

namespace App\Core;

/**
 * Handles generating and sending consistent API and HTML responses.
 */
class Response
{
    private int $statusCode = 200;
    private array $headers = [];

    public function setStatusCode(int $code): self
    {
        $this->statusCode = $code;
        return $this;
    }

    public function status(int $code): self
    {
        return $this->setStatusCode($code);
    }

    public function getStatusCode(): int
    {
        return $this->statusCode;
    }

    public function setHeader(string $name, string $value): self
    {
        $this->headers[$name] = $value;
        return $this;
    }

    /**
     * Send JSON response and terminate execution
     *
     * @param mixed $data
     * @param int $code
     * @return void
     */
    public function json($data, int $code = 200): void
    {
        $this->setStatusCode($code);
        $this->setHeader('Content-Type', 'application/json; charset=utf-8');
        
        // Setup CORS headers — restrict origin to the configured allowed domain
        $allowedOrigin = getenv('ALLOWED_ORIGIN') ?: '*';
        $this->setHeader('Access-Control-Allow-Origin', $allowedOrigin);
        $this->setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
        $this->setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization, X-Requested-With');
        $this->setHeader('Vary', 'Origin'); // Required when Access-Control-Allow-Origin is not *

        $this->sendHeaders();
        http_response_code($this->statusCode);

        echo json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
        exit;
    }

    /**
     * Send HTML response and terminate execution
     *
     * @param string $html
     * @param int $code
     * @return void
     */
    public function html(string $html, int $code = 200): void
    {
        $this->setStatusCode($code);
        $this->setHeader('Content-Type', 'text/html; charset=utf-8');
        
        $this->sendHeaders();
        http_response_code($this->statusCode);

        echo $html;
        exit;
    }

    /**
     * Send success JSON response
     */
    public function success(string $message, array $data = [], int $code = 200): void
    {
        $this->json([
            'status' => 'success',
            'message' => $message,
            'data' => $data
        ], $code);
    }

    /**
     * Send error JSON response
     */
    public function error(string $message, int $code = 400, array $errors = []): void
    {
        $response = [
            'status' => 'error',
            'message' => $message
        ];

        if (!empty($errors)) {
            $response['errors'] = $errors;
        }

        $this->json($response, $code);
    }

    public function sendHeaders(): void
    {
        if (headers_sent()) {
            return;
        }

        foreach ($this->headers as $name => $value) {
            header("{$name}: {$value}");
        }
    }
}
