<?php

namespace App\Http\Controllers;

use App\Http\Requests\ProxyValuationRequest;
use App\Http\Requests\ValuationRequest;
use App\Http\Resources\ValuationList;
use App\Http\Resources\ValuationResource;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\Auth;
use Illuminate\Validation\ValidationException;
use Mtc\MercuryDataModels\VehicleValuation;
use Mtc\VehicleValuation\Facades\Valuation;

class ValuationController extends Controller
{
    public function __construct()
    {
        $this->middleware([
            'permission:view-valuations',
        ])->except('proxyRequest');
    }

    public function index(Request $request)
    {
        $query = VehicleValuation::query()
            ->setSortBy($request->input('sort_by', 'id_desc'))
            ->when(
                $request->filled('search_term'),
                fn($query) => $query->where(fn($searchQuery) => $searchQuery
                    ->where('registration', 'like', $request->input('search_term') . '%')
                    ->orWhere('make', 'like', $request->input('search_term') . '%')
                    ->orWhere('model', 'like', $request->input('search_term') . '%')
                    ->orWhere('derivative', 'like', $request->input('search_term') . '%'))
            )
            ->setFilters($request->input('filters', []));

        collect($request->input('selections'))
            ->each(function ($selection) use ($query) {
                match ($selection['type']) {
                    'created_at_min' => $query->where('created_at', '>=', $selection['id']),
                    'created_at_max' => $query->where('created_at', '<=', $selection['id']),
                    default => $query
                };
            });

        return new ValuationList($query->paginate($request->input('per_page', 15)));
    }

    public function store(ValuationRequest $request)
    {
        if (Valuation::hasEnabledDriver() !== true) {
            return response([
                'message' => 'No valuation service is enabled'
            ], 422);
        }
        try {
            $valuation = Valuation::get($request->input('registration_number'), $request->input('mileage'));
            if ($valuation->wasRecentlyCreated) {
                $valuation->update([
                    'user_id' => Auth::id(),
                ]);
            }
            return new ValuationResource($valuation);
        } catch (\Exception $exception) {
            throw ValidationException::withMessages([$exception->getMessage()]);
        }
    }

    public function show(VehicleValuation $valuation)
    {
        return new ValuationResource($valuation);
    }

    public function futureValue(Request $request, VehicleValuation $valuation): ValuationResource|Response
    {
        if (Valuation::hasEnabledDriver() !== true || Valuation::hasFutureValuations() !== true) {
            return response([
                'message' => 'Unable to create future valuation'
            ], 422);
        }
        try {
            $mileage = $request->input('mileage', 0) !== 'null' ? $request->input('mileage', 0) : 0;
            $data = $valuation->data ?? [];
            $data['future_value'] = array_merge(
                $data['future-value'] ?? [],
                Valuation::getFutureValuation($valuation, $mileage, $request->input('condition', 'GOOD'))
            );
            $valuation->data = $data;
            $valuation->save();
            return new ValuationResource($valuation);
        } catch (\Exception $exception) {
            throw ValidationException::withMessages([$exception->getMessage()]);
        }
    }

    public function proxyRequest(ProxyValuationRequest $request): Response
    {
        if (Valuation::hasEnabledDriver() !== true) {
            return response([
                'message' => 'No valuation service is enabled'
            ], 422);
        }
        try {
            Valuation::get($request->input('registration_number'), $request->input('mileage'));
            return \response(['status' => 'ok']);
        } catch (\Exception $exception) {
            throw ValidationException::withMessages([$exception->getMessage()]);
        }
    }
}
