<?php

namespace App\Http\Controllers\Api;

use App\Enums\FuelType;
use App\Http\Controllers\Controller;
use App\Models\User;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\Hash;
use Illuminate\Validation\Rule;
use Illuminate\Validation\Rules\Password;
use Illuminate\Validation\ValidationException;

final class UserController extends Controller
{
    public function preferences(Request $request): JsonResponse
    {
        return response()->json([
            'preferred_fuel_type' => $request->user()->preferred_fuel_type,
            'postcode' => $request->user()->postcode,
        ]);
    }

    public function updatePreferences(Request $request): JsonResponse
    {
        $validated = $request->validate([
            'preferred_fuel_type' => ['sometimes', Rule::in(array_column(FuelType::cases(), 'value'))],
            'postcode' => ['sometimes', 'string', 'max:8'],
        ]);

        $request->user()->update($validated);

        return response()->json([
            'preferred_fuel_type' => $request->user()->fresh()->preferred_fuel_type,
            'postcode' => $request->user()->fresh()->postcode,
        ]);
    }

    public function savedStations(Request $request): JsonResponse
    {
        $stations = $request->user()->savedStations()->get();

        return response()->json(['data' => $stations]);
    }

    public function saveStation(Request $request): JsonResponse
    {
        $validated = $request->validate([
            'station_id' => ['required', 'string', 'max:64'],
        ]);

        $request->user()->savedStations()->firstOrCreate([
            'station_id' => $validated['station_id'],
        ]);

        return response()->json(null, 201);
    }

    public function removeStation(Request $request, string $stationId): Response
    {
        $request->user()->savedStations()->where('station_id', $stationId)->delete();

        return response()->noContent();
    }

    public function updateProfile(Request $request): JsonResponse
    {
        $validated = $request->validate([
            'name' => ['required', 'string', 'max:255'],
            'email' => ['required', 'string', 'email', 'max:255', Rule::unique(User::class)->ignore($request->user()->id)],
        ]);

        $user = $request->user();
        $user->fill($validated);

        if ($user->isDirty('email')) {
            $user->email_verified_at = null;
        }

        $user->save();

        return response()->json($user->fresh());
    }

    public function updatePassword(Request $request): JsonResponse
    {
        $request->validate([
            'current_password' => ['required', 'string'],
            'password' => ['required', 'string', Password::defaults(), 'confirmed'],
        ]);

        if (! Hash::check($request->string('current_password'), $request->user()->password)) {
            throw ValidationException::withMessages([
                'current_password' => [__('The provided password does not match your current password.')],
            ]);
        }

        $request->user()->update(['password' => $request->string('password')]);

        return response()->json(['message' => 'Password updated.']);
    }

    public function deleteAccount(Request $request): Response
    {
        $request->validate(['password' => ['required', 'string']]);

        if (! Hash::check($request->string('password'), $request->user()->password)) {
            throw ValidationException::withMessages([
                'password' => [__('The provided password does not match your current password.')],
            ]);
        }

        $user = $request->user();
        $user->tokens()->delete();
        $user->delete();

        return response()->noContent();
    }
}
