<?php

namespace OtomaticAi\Jobs;

use ActionScheduler;
use ActionScheduler_Store;
use OtomaticAi\Models\Netlinking;
use OtomaticAi\Models\Publication;
use OtomaticAi\Models\SingleModeGeneration;
use OtomaticAi\Utils\Language;
use OtomaticAi\Utils\Scheduler;
use OtomaticAi\Vendors\Illuminate\Support\Arr;
use OtomaticAi\Vendors\Illuminate\Support\Str;

class ProcessFailedScheduleJob extends Job
{
    /**
     * Create a new job instance.
     */
    public function __construct() {}

    /**
     * Execute the job.
     */
    public function handle()
    {
        // get pending publications
        $publications = Publication::pending()
            ->get();

        foreach ($publications as $publication) {
            $actions = array_merge(
                array_keys(
                    Scheduler::get(
                        "publish_publication",
                        [$publication->id],
                        [
                            "status" => ActionScheduler_Store::STATUS_FAILED,
                            "date" => $publication->published_at,
                            "date_compare" => ">=",
                        ]
                    )
                ),
                array_keys(
                    ProcessPublicationStepJob::search(
                        [
                            "id" => $publication->id,
                            "model_class" => Publication::class,
                        ],
                        [
                            "status" => ActionScheduler_Store::STATUS_FAILED,
                            "date" => $publication->published_at,
                            "date_compare" => ">="
                        ]
                    )
                )
            );

            if (!empty($actions)) {
                // find log
                $actionIds = array_values($actions);
                $logger = ActionScheduler::logger();
                $logs = $logger->get_logs(Arr::last($actionIds));
                if (!empty($logs)) {
                    $log = Arr::last($logs);
                    $message = $log->get_message();
                    if (Str::startsWith($message, "action marked as failed after")) {
                        if (Language::findFromLocale()->key === 'fr') {
                            $message = "Le script de génération a été interrompu par votre serveur. Vous pouvez réduire la durée de génération en sélectionnant des paramètres plus courts ou contacter votre hébergeur pour augmenter les limites de votre serveur.";
                        } else {
                            $message = "The generation script was interrupted by your server. You can reduce the generation time by selecting shorter settings or contact your hosting provider to increase your server limits.";
                        }
                    }
                    $publication->addLog("Publication failed. " . $message, "_default", "error");
                } else {
                    $publication->addLog("Publication failed. Unknown error occurred.", "_default", "error");
                }

                // set publication to failed
                $publication->status = "failed";
                $publication->save();
            }
        }

        // get pending single mode generations
        $generations = SingleModeGeneration::pending()
            ->get();

        foreach ($generations as $generation) {
            $actions = array_merge(
                array_keys(
                    Scheduler::get(
                        "generate_single_mode",
                        [$generation->id],
                        [
                            "status" => ActionScheduler_Store::STATUS_FAILED,
                            "date" => $generation->generated_at,
                            "date_compare" => ">=",
                        ]
                    )
                ),
                array_keys(
                    ProcessPublicationStepJob::search(
                        [
                            "id" => $generation->id,
                            "model_class" => SingleModeGeneration::class,
                        ],
                        [
                            "status" => ActionScheduler_Store::STATUS_FAILED,
                            "date" => $generation->generated_at,
                            "date_compare" => ">="
                        ]
                    )
                )
            );

            if (!empty($actions)) {
                // find log
                $actionIds = array_values($actions);
                $logger = ActionScheduler::logger();
                $logs = $logger->get_logs(Arr::last($actionIds));
                if (!empty($logs)) {
                    $log = Arr::last($logs);
                    $generation->addLog("Generation failed. " . $log->get_message(), "_default", "error");
                } else {
                    $generation->addLog("Generation failed. Unknown error occurred.", "_default", "error");
                }

                // set publication to failed
                $generation->status = "failed";
                $generation->save();
            }
        }

        // get pending netlinkings
        $netlinkings = Netlinking::pending()
            ->get();

        foreach ($netlinkings as $netlinking) {
            $actions = array_merge(
                array_keys(
                    Scheduler::get(
                        "generate_netlinking",
                        [$netlinking->id],
                        [
                            "status" => ActionScheduler_Store::STATUS_FAILED,
                            "date" => $netlinking->created_at,
                            "date_compare" => ">=",
                        ]
                    )
                ),
                array_keys(ProcessPublicationStepJob::search(
                    [
                        "id" => $netlinking->id,
                        "model_class" => Netlinking::class,
                    ],
                    [
                        "status" => ActionScheduler_Store::STATUS_FAILED,
                        "date" => $netlinking->created_at,
                        "date_compare" => ">="
                    ]
                ))
            );

            if (!empty($actions)) {
                // find log
                $actionIds = array_values($actions);
                $logger = ActionScheduler::logger();
                $logs = $logger->get_logs(Arr::last($actionIds));
                if (!empty($logs)) {
                    $log = Arr::last($logs);
                    $netlinking->addLog("Netlinking failed. " . $log->get_message(), "_default", "error");
                } else {
                    $netlinking->addLog("Netlinking failed. Unknown error occurred.", "_default", "error");
                }

                // set netlinking to failed
                $netlinking->status = "failed";
                $netlinking->save();
            }
        }
    }
}
