<?php

declare(strict_types=1);

namespace App\Helpers;

use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;

class WebsiteStatus
{
    private Client $client;

    public function __construct(Client $client = null)
    {
        $this->client = $client ?? new Client();
    }
    
    /**
     * Check if the website at the specified URL is up.
     *
     * @param string $url The URL of the website to check.
     * @return bool True if the website is up, false otherwise.
     */
    public function isUp(string $url): bool
    {
        try {
            $response = $this->sendRequest($url);
            return $response['httpCode'] >= 200 && $response['httpCode'] < 300;
        } catch (RequestException $e) {
            return false;
        }
    }

    /**
     * Check if the website at the specified URL has visible content.
     *
     * @param string $url The URL of the website to check.
     * @return string "visible" if the website has visible content, or "blank" if the website has no visible content.
     */
    public function checkContent(string $url): string
    {
        try {
            $response = $this->sendRequest($url);
            return trim($response['data']) === "" ? "blank" : "visible";
        } catch (RequestException $e) {
            return "blank";
        }
    }

    /**
     * Check the status and content of the website at the specified URL.
     *
     * @param string $url The URL of the website to check.
     * @return array An array containing the status and content of the website.
     */
    public function checkAll(string $url): array
    {
        $status = $this->isUp($url) ? "up" : "down";
        $content = $status === "up" ? $this->checkContent($url) : "n/a";

        return [
            "status" => $status,
            "content" => $content,
        ];
    }

    /**
     * Send an HTTP request to the specified URL and return the response data and HTTP status code.
     *
     * @param string $url The URL to send the request to.
     * @return array An array containing the response data and HTTP status code.
     * @throws RequestException
     */
    private function sendRequest(string $url): array
    {
        $response = $this->client->request('GET', $url, [
            'timeout' => 5,
        ]);
        return [
            'data' => $response->getBody()->getContents(),
            'httpCode' => $response->getStatusCode(),
        ];
    }
}