<?php

namespace App\Modules\VehicleLabels\Http\Controllers;

use App\Http\Controllers\Controller;
use App\Jobs\RunLabelAssignmentForVehiclesJob;
use App\Modules\VehicleLabels\Http\Requests\StoreLabelRequest;
use App\Modules\VehicleLabels\Http\Requests\UpdateLabelRequest;
use App\Modules\VehicleLabels\Http\Resources\LabelList;
use App\Modules\VehicleLabels\Http\Resources\LabelView;
use App\Modules\VehicleLabels\LabelRepository;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Mtc\MercuryDataModels\Label;
use Mtc\MercuryDataModels\LabelRule;
use Mtc\MercuryDataModels\Vehicle;

class LabelController extends Controller
{
    public function index(Request $request): LabelList
    {
        return new LabelList(Label::query()
            ->when($request->input('filters') === 'active', fn ($query) => $query->where('active', 1))
            ->when(
                $request->input('filters') === 'inactive',
                fn ($query) => $query->whereNull('active')->orWhere('active', 0)
            )
            ->setSortBy($request->input('sort_by', 'id_desc'))
            ->when(
                $request->filled('search_term'),
                function ($query) use ($request) {
                    $query->where('name', 'like', '%' . $request->input('search_term') . '%');
                }
            )
            ->paginate());
    }

    public function show(Label $label): LabelView
    {
        return new LabelView($label);
    }

    public function store(StoreLabelRequest $request): LabelView
    {
        $label = Label::query()
            ->create($request->input());
        return new LabelView($label);
    }

    public function update(UpdateLabelRequest $request, Label $label): LabelView
    {
        $input = $request->input();
        if (isset($input['data']['automation_options'])) {
            unset($input['data']['automation_options']);
        }

        if (isset($input['data']['options'])) {
            unset($input['data']['options']);
        }

        if (array_key_exists('rules', $input['data'])) {
            foreach ($input['data']['rules'] as $key => $rule) {
                if (empty($rule['condition_value'])) {
                    LabelRule::query()->where('label_id', '=', $label->id)
                        ->where('condition_field', '=', $key)
                        ->delete();
                } else {
                    if ($rule['value_data_type'] == 'json') {
                        $rule['condition_value'] = json_encode($rule['condition_value']);
                    }

                    LabelRule::updateOrCreate(
                        [
                            'label_id' => $label->id,
                            'condition_field' => $key,
                        ],
                        [
                            'condition_value' => $rule['condition_value'],
                            'value_data_type' => $rule['value_data_type'],
                        ]
                    );
                }
            }
        }

        $label->update($input);
        return new LabelView($label);
    }

    public function destroy(Request $request, Label $label): LabelList
    {
        $label->delete();
        return $this->index($request);
    }

    public function remove(Label $label): LabelView
    {
        $label->vehicles()->detach();
        return new LabelView($label);
    }

    public function assign(Label $label): Response
    {
        $this->dispatch(new RunLabelAssignmentForVehiclesJob($label));
        return \response('ok');
    }

    public function testAgainstVehicle(Label $label, Vehicle $vehicle, LabelRepository $repository): JsonResponse
    {
        $results = $repository->testLabelAgainstVehicle($vehicle, $label);
        return response()->json($results);
    }
}
