<?php

namespace App\Jobs;

use App\Models\Activity;
use App\Models\Contract;
use App\Models\FieldJob;
use App\Models\FieldJobSetting;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\DB;

class EndFieldJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    public function __construct(
        public int $activityId,
        public ?int $contractId = null,
        public array $config = []
    ) {}

    public function handle(): void
    {
        $activity = Activity::query()->find($this->activityId);

        // Determine target contract ID
        $contractId = $this->contractId;
        if (! $contractId && $activity) {
            $contractId = $activity->contract_id;
        }
        if (! $contractId) {
            \Log::warning('EndFieldJob: missing contract id', ['activity_id' => $this->activityId]);

            return;
        }

        // Use latest FieldJobSetting as the source of action/decision/segments
        $setting = FieldJobSetting::query()->latest('id')->first();

        $triggeredByEvent = (bool) $activity; // this job is invoked from a decision event when an Activity exists

        DB::transaction(function () use ($contractId, $setting, $triggeredByEvent): void {
            // Find active field job for this contract
            $job = FieldJob::query()
                ->where('contract_id', $contractId)
                ->whereNull('completed_at')
                ->whereNull('cancelled_at')
                ->latest('id')
                ->first();

            if ($job) {
                // Complete the job (updated hook moves segment appropriately)
                $job->completed_at = now();
                $job->save();

                // Optionally log a completion activity.
                // By default, we SKIP creating an extra activity when triggered by a decision event (to avoid duplicates).
                // To force creation from an event, set config['create_activity_from_event'] = true on the decision event.
                // For non-event triggers, set config['create_activity'] = true to allow creation.
                $shouldCreateActivity = $triggeredByEvent
                    ? (bool) ($this->config['create_activity_from_event'] ?? false)
                    : (bool) ($this->config['create_activity'] ?? false);

                if ($shouldCreateActivity) {
                    $job->loadMissing('contract');
                    $actionId = optional($job->setting)->action_id ?? optional($setting)->action_id;
                    $decisionId = optional($job->setting)->complete_decision_id ?? optional($setting)->complete_decision_id;
                    if ($actionId && $decisionId && $job->contract) {
                        Activity::create([
                            'due_date' => null,
                            'amount' => null,
                            'note' => 'Terensko opravilo zaključeno',
                            'action_id' => $actionId,
                            'decision_id' => $decisionId,
                            'client_case_id' => $job->contract->client_case_id,
                            'contract_id' => $job->contract_id,
                        ]);
                    }
                }
            } else {
                // No active job: still move contract to the configured return segment if available
                if ($setting && $setting->return_segment_id) {
                    $tmp = new FieldJob;
                    $tmp->contract_id = $contractId;
                    $tmp->moveContractToSegment($setting->return_segment_id);
                }
            }
        });

        \Log::info('EndFieldJob executed', [
            'activity_id' => $this->activityId,
            'contract_id' => $contractId,
            'config' => $this->config,
        ]);
    }
}
