<?php

namespace App\Browser\Jobs\Instagram;

use App\Browser\BrowserJob;
use App\Browser\JobDebugScreenshot;
use App\Models\JobRun;
use App\Notification\Notifications\JobDebugNotification;
use App\Notification\Providers\AllNotification;
use Facebook\WebDriver\WebDriverBy;
use Illuminate\Contracts\Queue\ShouldBeUniqueUntilProcessing;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
use Laravel\Dusk\Browser;
use App\Services\AIPrompt\OpenAPIPrompt;

abstract class InstagramAbstractJob extends BrowserJob implements ShouldBeUniqueUntilProcessing
{
    // === CONFIGURATION ===
    protected Collection $jobInfos;
    protected JobRun $jobRun;
    protected OpenAPIPrompt $openAPIPrompt;

    public function __construct($jobId, OpenAPIPrompt $openAPIPrompt = null)
    {
        parent::__construct($jobId);

        $this->openAPIPrompt = $openAPIPrompt ?? app(OpenAPIPrompt::class);
    }

    protected function clickNext(Browser $browser) {
        $nextButton = $browser->driver->findElement(WebDriverBy::xpath('//div[contains(text(), "Next") or contains(text(), "Share")]'));
        $nextButton->click();
        sleep(2);
    }

    protected function putOriginalResolution(Browser $browser)
    {
        try {
            $chooseResolutionButton = $browser->driver->findElement(WebDriverBy::xpath('//button[./div/*[local-name() = "svg"][@aria-label="Select crop"]]'));
            $chooseResolutionButton->click();
            sleep(2);
            // Choos "original" resolution
            $originalResolutionButton = $browser->driver->findElement(WebDriverBy::xpath('//div[./div/div/span[contains(text(), "Original")]]'));
            $originalResolutionButton->click();
            sleep(2);
        } catch (\Exception $e) {
            Log::error("Failed to set original resolution: " . $e->getMessage());
            $browser->screenshot(JobDebugScreenshot::getFileName($this->jobId));
            AllNotification::send(new JobDebugNotification($this->jobId, "Failed to set \"original\" resolution: " . $e->getMessage()));
        }
    }

    protected function signin(Browser $browser)
    {
        // Verify if already signed in so we can skip
        try {
            $browser->waitForText("Search", 1);
        } catch (\Exception $e) {
            Log::debug("Not already signed in, continue with the signin process");
            // Not already signed in, continue with the signin process
        }

        try {
            $browser->waitForText("Log in", 10, true);
            sleep(3);
            $emailButton = $browser->driver->findElement(WebDriverBy::xpath('//input[contains(@aria-label, "email")]'));
            $emailButton->click();
            $emailButton->sendKeys($this->jobInfos->get("instagram_repost_account_username"));
            sleep(3);
            $passwordButton = $browser->driver->findElement(WebDriverBy::xpath('//input[contains(@aria-label, "Password")]'));
            $passwordButton->click();
            $passwordButton->sendKeys($this->jobInfos->get("instagram_repost_account_password") . "\n");
            sleep(5);
        } catch (\Exception $e) {
            // Probably no need to signin
        }
        try {
            $browser->waitForText("Search", 15, true);
            $this->removePopups($browser);
        } catch (\Exception $e) {
            // Incorrect password
            try {
                $browser->waitForText("Sorry, your password was incorrect. Please double-check your password.", 1, true);
                Log::error("Instagram login failed: Incorrect password.");
                $browser->screenshot(JobDebugScreenshot::getFileName($this->jobId));
                AllNotification::send(new JobDebugNotification($this->jobId, "Instagram login failed: Incorrect password."));
                // Stop the job run
                throw new \Exception("Instagram login failed: Incorrect password.");
            } catch (\Exception $e) {
                // Not the expected error, continue
            }

            Log::error("Failed to sign in: " . $e->getMessage());
            $browser->screenshot(JobDebugScreenshot::getFileName($this->jobId));
            AllNotification::send(new JobDebugNotification($this->jobId, "Failed to sign in: " . $e->getMessage()));
            // Stop the job run
            throw $e;
        }
    }

    protected function removePopups(Browser $browser)
    {
        $popupsTypes = [
            ['//button[contains(text(), "Allow all cookies")]'], // Allow all cookies
            ['//button[contains(text(), "Not Now")]', ["Popup Not Now clicked"]], // Not now
            ['//button[contains(text(), "OK")]', ["Popup Ok clicked"]], // OK
        ];

        foreach ($popupsTypes as $popup) {
            try {
                $button = $browser->driver->findElement(WebDriverBy::xpath($popup[0]));
                if ($button === null) {
                    continue; // No button found, continue to the next popup
                }
                if (isset($popup[1])) {
                    $browser->screenshot(JobDebugScreenshot::getFileName($this->jobId));
                    AllNotification::send(new JobDebugNotification($this->jobId, $popup[1][0]));
                }
                $button->click();
                sleep(2);
                return; // Exit after clicking the first popup found
            } catch (\Exception $e) {
                // Porbably no popup found, continue
            }
        }
    }
}
