<?php

namespace App\Http\Controllers;

use App\Jobs\SyncTaxonomyToTenants;
use App\Mail\NewModelRequestMail;
use App\Master\Models\ModelRequest;
use App\Master\Models\VehicleMake;
use App\Master\Models\VehicleModel;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Mail;

class ModelRequestController extends Controller
{
    public function store(Request $request): JsonResponse
    {
        $validated = $request->validate([
            'make_id' => 'required|exists:vehicle_makes,id',
            'model_name' => 'required|string|max:255',
            'vehicle_type' => 'nullable|string|max:50',
            'reason' => 'nullable|string|max:1000',
        ]);

        $user = $request->user();
        $tenant = tenancy()->tenant;

        $existingModel = VehicleModel::query()
            ->where('make_id', $validated['make_id'])
            ->where('name', $validated['model_name'])
            ->first();

        if ($existingModel) {
            return response()->json([
                'message' => 'A model with this name already exists for the selected make.',
            ], 422);
        }

        $existingRequest = ModelRequest::query()
            ->where('make_id', $validated['make_id'])
            ->where('model_name', $validated['model_name'])
            ->pending()
            ->first();

        if ($existingRequest) {
            return response()->json([
                'message' => 'A pending request for this model already exists.',
            ], 422);
        }

        $modelRequest = ModelRequest::create([
            'make_id' => $validated['make_id'],
            'model_name' => $validated['model_name'],
            'vehicle_type' => $validated['vehicle_type'] ?? null,
            'reason' => $validated['reason'] ?? null,
            'requested_by_email' => $user?->email ?? 'unknown',
            'requested_by_name' => $user?->name ?? 'Unknown User',
            'tenant_id' => $tenant?->id,
            'status' => 'pending',
        ]);

        $modelRequest->load('make');

        Mail::to(config('mail.developer_alerts'))
            ->send(new NewModelRequestMail($modelRequest));

        return response()->json([
            'message' => 'Your model request has been submitted successfully.',
            'request' => $modelRequest,
        ], 201);
    }

    public function index(Request $request): JsonResponse
    {
        $status = $request->input('filters');
        $perPage = $request->input('per_page', 25);
        $sortBy = $request->input('sort_by', 'created_at');
        $sortDirection = $request->input('sort_direction', 'desc');

        $data = ModelRequest::query()
            ->latest()
            ->with(['make', 'approvedByUser'])
            ->when($status && $status !== '', fn($query) => $query->where('status', $status))
            ->orderBy($sortBy === 'name' ? 'model_name' : $sortBy, $sortDirection)
            ->paginate($perPage)
            ->through(fn(ModelRequest $item) => [
                'id' => $item->id,
                'name' => $item->model_name,
                'description' => $item->make?->name ?? 'Unknown Make',
                'metaItems' => [
                    ucfirst($item->status),
                    $item->vehicle_type ?? '-',
                    $item->created_at?->format('d/m/Y H:i') ?? '-',
                ],
            ])
            ->toArray();

        return response()->json($data);
    }

    public function show(int $id): JsonResponse
    {
        $modelRequest = ModelRequest::query()
            ->with(['make', 'approvedByUser'])
            ->findOrFail($id);

        return response()->json($modelRequest);
    }

    public function approve(Request $request, int $id): JsonResponse
    {
        $validated = $request->validate([
            'admin_notes' => 'nullable|string|max:1000',
        ]);

        $modelRequest = ModelRequest::findOrFail($id);

        if (!$modelRequest->isPending()) {
            return response()->json([
                'message' => 'This request has already been processed.',
            ], 422);
        }

        $existingModel = VehicleModel::query()
            ->where('make_id', $modelRequest->make_id)
            ->where('name', $modelRequest->model_name)
            ->first();

        if ($existingModel) {
            $modelRequest->update([
                'status' => 'rejected',
                'approved_by' => $request->user()->id,
                'actioned_at' => now(),
                'admin_notes' => 'Model already exists in the system.',
            ]);

            return response()->json([
                'message' => 'A model with this name already exists for the selected make.',
            ], 422);
        }

        $vehicleModel = VehicleModel::create([
            'make_id' => $modelRequest->make_id,
            'name' => $modelRequest->model_name,
            'type' => $modelRequest->vehicle_type,
        ]);

        SyncTaxonomyToTenants::dispatch('model', $vehicleModel);

        $modelRequest->update([
            'status' => 'approved',
            'approved_by' => $request->user()->id,
            'actioned_at' => now(),
            'admin_notes' => $validated['admin_notes'] ?? null,
        ]);

        return response()->json([
            'message' => 'Model request approved and model created successfully.',
            'model' => $vehicleModel,
            'request' => $modelRequest->fresh(['make', 'approvedByUser']),
        ]);
    }

    public function reject(Request $request, int $id): JsonResponse
    {
        $validated = $request->validate([
            'admin_notes' => 'required|string|max:1000',
        ]);

        $modelRequest = ModelRequest::findOrFail($id);

        if (!$modelRequest->isPending()) {
            return response()->json([
                'message' => 'This request has already been processed.',
            ], 422);
        }

        $modelRequest->update([
            'status' => 'rejected',
            'approved_by' => $request->user()->id,
            'actioned_at' => now(),
            'admin_notes' => $validated['admin_notes'],
        ]);

        return response()->json([
            'message' => 'Model request has been rejected.',
            'request' => $modelRequest->fresh(['make', 'approvedByUser']),
        ]);
    }

    public function makes(): JsonResponse
    {
        $makes = VehicleMake::query()
            ->select(['id', 'name'])
            ->orderBy('name')
            ->get();

        return response()->json($makes);
    }
}
