<?php
/**
 * SalonPro X - HTTP Response Handler
 */

namespace core;

class Response
{
    private int $statusCode = 200;
    private array $headers = [];
    private mixed $body = null;

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

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

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

    public function setContentType(string $mimeType): self
    {
        return $this->setHeader('Content-Type', $mimeType);
    }

    public function json(mixed $data, int $statusCode = 200): void
    {
        $this->setStatusCode($statusCode);
        $this->setContentType('application/json; charset=utf-8');
        echo json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
        exit;
    }

    public function success(mixed $data = null, string $message = 'Success'): void
    {
        $this->json([
            'success' => true,
            'message' => $message,
            'data' => $data,
        ]);
    }

    public function error(string $message = 'Error', int $statusCode = 400, mixed $errors = null): void
    {
        $response = [
            'success' => false,
            'message' => $message,
        ];
        if ($errors !== null) {
            $response['errors'] = $errors;
        }
        $this->json($response, $statusCode);
    }

    public function redirect(string $url): void
    {
        $this->setHeader('Location', $url);
        exit;
    }

    public function back(): void
    {
        $referer = $_SERVER['HTTP_REFERER'] ?? APP_URL;
        $this->redirect($referer);
    }

    public function with(string $key, mixed $value): self
    {
        Session::flash($key, $value);
        return $this;
    }

    public function withAlert(string $type, string $message): self
    {
        Session::setAlert($type, $message);
        return $this;
    }

    public function withInput(): self
    {
        Session::flash('_old_input', $_POST);
        return $this;
    }

    public function withErrors(array $errors): self
    {
        Session::flash('_errors', $errors);
        return $this;
    }

    public function download(string $filePath, string $filename = ''): void
    {
        if (!file_exists($filePath)) {
            throw new \RuntimeException('File not found: ' . $filePath);
        }
        
        $filename = $filename ?: basename($filePath);
        $this->setContentType(mime_content_type($filePath) ?: 'application/octet-stream');
        $this->setHeader('Content-Disposition', 'attachment; filename="' . $filename . '"');
        $this->setHeader('Content-Length', (string)filesize($filePath));
        readfile($filePath);
        exit;
    }

    public function file(string $filePath): void
    {
        if (!file_exists($filePath)) {
            throw new \RuntimeException('File not found: ' . $filePath);
        }
        $this->setContentType(mime_content_type($filePath) ?: 'application/octet-stream');
        readfile($filePath);
        exit;
    }

    public function noCache(): self
    {
        $this->setHeader('Cache-Control', 'no-store, no-cache, must-revalidate, max-age=0');
        $this->setHeader('Pragma', 'no-cache');
        $this->setHeader('Expires', 'Thu, 01 Jan 1970 00:00:00 GMT');
        return $this;
    }
}
