<?php

namespace App\ScheduledTasks\Actions;

use App\ExportMapRepository;
use App\Models\ExportMap;
use App\ScheduledTasks\ActionResult;
use App\ScheduledTasks\Contracts\TaskAction;
use App\ScheduledTasks\TaskRunContext;
use Illuminate\Validation\Rule;

class RunExportMapAction implements TaskAction
{
    public function key(): string
    {
        return 'export-map';
    }

    public function label(): string
    {
        return __('scheduled_tasks.actions.export-map');
    }

    public function available(): bool
    {
        return true;
    }

    public function userSelectable(): bool
    {
        return true;
    }

    public function configFields(): array
    {
        return [
            [
                'key' => 'export_map_id',
                'type' => 'select',
                'label' => __('scheduled_tasks.fields.export_map'),
                'options' => ExportMap::query()
                    ->where('schedule_enabled', false)
                    ->orderBy('name')
                    ->get(['id', 'name'])
                    ->map(fn (ExportMap $map) => ['id' => $map->id, 'name' => $map->name])
                    ->toArray(),
            ],
        ];
    }

    public function rules(array $config): array
    {
        return [
            'export_map_id' => [
                'required',
                'integer',
                // Coexistence guard, save side: a map owned by the legacy scheduler
                // cannot also be scheduled by a task. Use 0, not false: the query-builder
                // binds a bool false as '' which matches nothing on some drivers.
                Rule::exists('export_maps', 'id')->where('schedule_enabled', 0),
            ],
        ];
    }

    public function execute(array $config, TaskRunContext $context): ActionResult
    {
        $exportMap = ExportMap::query()->find($config['export_map_id'] ?? null);

        if (!$exportMap) {
            return ActionResult::failed('Export map no longer exists');
        }

        // Coexistence guard: a map still owned by the legacy scheduler must never
        // be delivered twice. The save-side guard prevents this; the runtime check
        // covers maps whose legacy schedule was enabled afterwards.
        if ($exportMap->schedule_enabled) {
            return ActionResult::failed(
                "Export map \"{$exportMap->name}\" is scheduled by the legacy export-map scheduler"
            );
        }

        app(ExportMapRepository::class)->run($exportMap);

        return ActionResult::completed(
            "Export map \"{$exportMap->name}\" run",
            ['export_map_id' => $exportMap->id, 'export_map' => $exportMap->name]
        );
    }

    public function queue(): string
    {
        return 'export';
    }
}
