Files
2026-09-01 07:49:48 -03:00

171 lines
5.5 KiB
PHP
Executable File

<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use App\Models\Subject;
use App\Models\UserInterest;
use App\Models\UserSubject;
use App\Services\AIService;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\View\View;
/**
* Manages user interests and AI-generated subject suggestions.
*/
class InterestController extends Controller
{
/**
* Display the user's interests and AI suggestions.
*/
public function index(): View
{
/** @var \App\Models\User $user */
$user = Auth::user();
$interests = $user->userInterests()->orderByDesc('created_at')->get();
$suggestions = session('suggestions', []);
return view('admin.interests.index', compact('interests', 'suggestions'));
}
/**
* Store a new user interest.
*/
public function store(Request $request): RedirectResponse
{
$validated = $request->validate([
'interest' => ['required', 'string', 'max:255'],
]);
/** @var \App\Models\User $user */
$user = Auth::user();
$user->userInterests()->create([
'interest' => $validated['interest'],
]);
return back()->with('success', __('Interest added successfully.'));
}
/**
* Remove the specified user interest.
*/
public function destroy(UserInterest $userInterest): RedirectResponse
{
$this->authorize('delete', $userInterest);
$userInterest->delete();
return back()->with('success', __('Interest removed successfully.'));
}
/**
* Generate AI subject suggestions based on user interests.
*/
public function generateSuggestions(Request $request): RedirectResponse
{
/** @var \App\Models\User $user */
$user = Auth::user();
$interests = $user->userInterests()->pluck('interest')->toArray();
if (empty($interests)) {
return back()->with('error', __('Add at least one interest before generating suggestions.'));
}
$interestsList = implode(', ', $interests);
$prompt = "Com base nos interesses do usuário: {$interestsList}. Sugira de 3 a 5 temas de assuntos de aprendizado que seriam relevantes para este usuário. Para cada tema, forneça: 1) name (formato: 'Aprendizado e Treinamento de [Tema]'), 2) description (máximo 1000 caracteres), 3) introduction (máximo 5000 caracteres). Retorne APENAS um array JSON válido (sem texto adicional, sem markdown, sem code blocks) com objetos contendo esses campos. Todo o conteúdo deve estar em Português do Brasil.";
/** @var \App\Services\AIService $ai */
$ai = app(AIService::class);
$result = $ai->generateInsight('Sugestões de assuntos', $prompt, ['language' => 'pt_BR']);
if (!$result['success']) {
return back()->with('error', __('Failed to generate suggestions: :error', ['error' => $result['error'] ?? __('Unknown error')]));
}
$suggestions = $this->extractJsonFromAiResponse($result['content']);
if (!$suggestions || !is_array($suggestions)) {
return back()->with('error', __('Failed to parse AI suggestions. Please try again.'));
}
return back()->with('suggestions', $suggestions)->with('success', __('Suggestions generated successfully.'));
}
/**
* Create a subject automatically from a suggestion.
*/
public function createSubjectFromSuggestion(Request $request): RedirectResponse
{
$request->validate([
'name' => ['required', 'string', 'max:255'],
'description' => ['nullable', 'string', 'max:1000'],
'introduction' => ['nullable', 'string', 'max:5000'],
]);
$existing = Subject::where('name', $request->name)->first();
if ($existing) {
return back()->with('error', __('A subject with this name already exists.'));
}
$subject = Subject::create([
'user_id' => Auth::id(),
'name' => $request->name,
'description' => $request->description,
'introduction' => $request->introduction,
'is_system' => false,
'is_active' => true,
]);
UserSubject::firstOrCreate(
[
'user_id' => Auth::id(),
'subject_id' => $subject->id,
],
[
'frequency' => 'daily',
'preferred_times' => ['09:00'],
'insight_language' => Auth::user()->locale ?? 'en',
'delivery_channels' => ['dashboard'],
'is_active' => true,
]
);
return back()->with('success', __('Subject created successfully.'));
}
/**
* Extract JSON from AI response, handling code blocks and plain text.
*/
private function extractJsonFromAiResponse(string $content): ?array
{
$content = trim($content);
if (str_starts_with($content, '```')) {
$content = preg_replace('/^```(?:json)?\s*/', '', $content);
$content = preg_replace('/\s*```$/', '', $content);
}
$data = json_decode($content, true);
if (json_last_error() === JSON_ERROR_NONE && is_array($data)) {
return $data;
}
if (preg_match('/\[.*\]/s', $content, $matches)) {
$data = json_decode($matches[0], true);
if (json_last_error() === JSON_ERROR_NONE && is_array($data)) {
return $data;
}
}
return null;
}
}