<?php

namespace App\Services\Auth;

use App\Models\Configuration;
use App\Models\Role;
use App\Models\User;
use App\Models\UserRole;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Validator;
use PHPOpenSourceSaver\JWTAuth\Facades\JWTAuth;

/**
 * Handles direct public API registration requests that bypass the captcha flow.
 */
class ApiRegistrationService
{
    public function registerResponse(Request $request): JsonResponse
    {
        $requestData = $request->all();
        if ($request->isJson() && ($requestData === [] || $requestData === null)) {
            $decoded = json_decode((string) $request->getContent(), true);
            $requestData = is_array($decoded) ? $decoded : [];
        }

        $validator = Validator::make($requestData, [
            'firstname' => ['required', 'string', 'min:2', 'max:30'],
            'lastname' => ['required', 'string', 'min:2', 'max:30'],
            'email' => ['required', 'email'],
            'password' => ['required', 'string', 'min:8'],
            'cellphone' => ['required', 'string', 'min:10', 'max:20'],
            'gender' => ['nullable', 'string'],
            'address_street' => ['nullable', 'string'],
            'city' => ['nullable', 'string'],
            'state' => ['nullable', 'string'],
            'zip' => ['nullable', 'string'],
            'role' => ['nullable', 'string'],
        ]);

        if ($validator->fails()) {
            return response()->json([
                'status' => false,
                'message' => 'Validation failed',
                'errors' => $validator->errors()->toArray(),
            ], 422);
        }

        /** @var array<string, mixed> $data */
        $data = $validator->validated();

        if (User::query()->where('email', $data['email'])->exists()) {
            return response()->json([
                'status' => false,
                'message' => 'Email already registered',
            ], 422);
        }

        $schoolYear = Configuration::getConfig('school_year');
        $semester = Configuration::getConfig('semester');

        $userData = [
            'firstname' => $data['firstname'],
            'lastname' => $data['lastname'],
            'email' => $data['email'],
            'password' => pbkdf2_hash((string) $data['password']),
            'cellphone' => $data['cellphone'],
            'gender' => $data['gender'] ?? null,
            'address_street' => $data['address_street'] ?? '',
            'city' => $data['city'] ?? '',
            'state' => $data['state'] ?? '',
            'zip' => $data['zip'] ?? '',
            'school_year' => $schoolYear,
            'semester' => $semester ?? '',
            'status' => 'active',
            'is_verified' => 0,
            'accept_school_policy' => 0,
        ];

        try {
            $userId = null;
            $rolesForResponse = [];

            DB::transaction(function () use ($userData, $data, &$userId, &$rolesForResponse): void {
                $user = User::query()->create($userData);
                $userId = (int) $user->id;

                if (($data['role'] ?? '') === 'parent') {
                    $role = Role::query()->where('name', 'parent')->first();
                    if ($role) {
                        UserRole::query()->create([
                            'user_id' => $userId,
                            'role_id' => (int) $role->id,
                        ]);
                        $rolesForResponse = ['parent'];
                    }
                }
            });

            $user = User::query()->findOrFail($userId);
            $token = JWTAuth::fromUser($user);

            $fullName = trim((string) $user->firstname.' '.(string) $user->lastname);

            return response()->json([
                'status' => true,
                'message' => 'Registration successful. Please verify your email.',
                'token' => $token,
                'user' => [
                    'id' => $userId,
                    'name' => $fullName,
                    'email' => $userData['email'],
                    'roles' => $rolesForResponse,
                ],
            ], 201);
        } catch (\Throwable $e) {
            Log::error('Registration error: '.$e->getMessage());

            return response()->json([
                'status' => false,
                'message' => 'Registration failed. Please try again.',
            ], 500);
        }
    }
}
