<?php

namespace App\Http\Controllers\Concerns;

use Illuminate\Http\Exceptions\HttpResponseException;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Redirect;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\ViewErrorBag;

trait ValidatesHtmx
{
    protected function validateHtmx(Request $request, array $rules, array $options = []): array
    {
        $bag = $options['bag'] ?? 'default';

        $validator = Validator::make(
            $request->all(),
            $rules,
            $options['messages'] ?? [],
            $options['attributes'] ?? [],
        );

        if ($validator->passes()) {
            return $validator->validated();
        }

        // single-message toast by default
        $toast = $options['toast_message']
            ?? $validator->errors()->first()
            ?? __('Please correct any errors and try again.');
        $type = $options['toast_type'] ?? 'error';

        // allow disabling toast
        $toastEnabled = $options['toast'] ?? true;

        if ($request->header('HX-Request')) {
            $request->session()->flashInput($request->input());

            $errors = new ViewErrorBag();
            $errors->put($bag, $validator->errors());

            $view = $options['htmx_view'] ?? null;
            if (!$view) {
                throw new HttpResponseException(response('', 422));
            }

            $data = array_merge($options['htmx_data'] ?? [], [
                'errors' => $errors,
            ]);

            $response = response()->view($view, $data, 422);

            if ($toastEnabled) {
                $response->header('HX-Trigger', json_encode([
                    'toast' => [
                        'message' => $toast,
                        'type'    => $type,
                    ],
                ]));
            }

            throw new HttpResponseException($response);
        }

        $redirect = $options['redirect'] ?? null;
        $response = $redirect ? Redirect::route($redirect) : Redirect::back();

        if ($toastEnabled) {
            $response->with('toast', [
                'message' => $toast,
                'type'    => $type,
            ]);
        }

        throw new HttpResponseException(
            $response->withErrors($validator, $bag)->withInput()
        );
    }
}
