<?php

namespace App\Services;

use Spatie\Browsershot\Browsershot;
use App\Models\Website;
use Illuminate\Support\Facades\Storage;
use Exception;

class ScreenshotService
{
    /**
     * Capture screenshot for a website and save it.
     *
     * Uses networkidle2 (≤2 open connections) instead of networkidle0 so that
     * real-world sites with persistent analytics/trackers don't time out.
     * Falls back to domcontentloaded if that still fails.
     *
     * @param Website $website
     * @return string Screenshot path relative to public storage
     */
    public function capture(Website $website): string
    {
        $timestamp = now()->format('Y-m-d_H-i-s');
        $filename  = 'screenshots/' . $website->id . '_' . $timestamp . '.jpg';
        $fullPath  = storage_path('app/public/' . $filename);

        // Ensure directory exists
        if (!Storage::disk('public')->exists('screenshots')) {
            Storage::disk('public')->makeDirectory('screenshots');
        }

        try {
            // Primary attempt: networkidle2 — tolerates up to 2 open connections
            // (ads, trackers, websockets) which is enough for a visual screenshot.
            $this->buildBrowsershot($website->url, 'networkidle2')
                ->save($fullPath);
        } catch (Exception $e) {
            // Fallback: domcontentloaded — captures as soon as the DOM is ready.
            // Sufficient for a screenshot even if third-party scripts are still loading.
            $this->buildBrowsershot($website->url, 'domcontentloaded')
                ->save($fullPath);
        }

        return $filename;
    }

    /**
     * Build a Browsershot instance with shared settings.
     */
    private function buildBrowsershot(string $url, string $waitUntil): Browsershot
    {
        return Browsershot::url($url)
            ->noSandbox()                          // required on most Linux/Mac servers
            ->windowSize(1920, 1080)
            ->setScreenshotType('jpeg', 80)
            ->timeout(120)                         // allow up to 2 minutes per attempt
            ->setOption('waitUntil', $waitUntil);  // networkidle2 or domcontentloaded
    }
}
