<?php

namespace App\Http\Controllers;

use App\Services\GeminiService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

class ChatbotController extends Controller
{
    private const MESSAGE_MAX_LENGTH = 4000;

    private const HISTORY_TEXT_MAX_LENGTH = 20000;

    private const HISTORY_MAX_ENTRIES = 200;

    private const HISTORY_TOTAL_MAX_LENGTH = 40000;

    public function __construct(
        private readonly GeminiService $geminiService,
    ) {}

    public function message(Request $request): JsonResponse
    {
        $this->applyHistoryWindow($request);

        $validated = $request->validate([
            'message'        => ['required', 'string', 'max:' . self::MESSAGE_MAX_LENGTH],
            'history'        => ['sometimes', 'array', 'max:' . self::HISTORY_MAX_ENTRIES],
            'history.*.role' => ['required_with:history', 'string', 'in:user,model'],
            'history.*.text' => ['required_with:history', 'string', 'max:' . self::HISTORY_TEXT_MAX_LENGTH],
        ]);

        $user = Auth::user();

        $reply = $this->geminiService->sendMessage(
            message:  data_get($validated, 'message'),
            userType: $user->type,
            history:  data_get($validated, 'history', []),
        );

        return $this->successResponse(payload: ['reply' => $reply]);
    }

    //

    private function applyHistoryWindow(Request $request): void
    {
        $history = $request->input('history');

        if (! is_array($history)) {
            return;
        }

        $window = [];
        $total  = 0;

        foreach (array_reverse($history) as $entry) {
            $text   = data_get($entry, 'text');
            $length = is_string($text) ? mb_strlen($text) : 0;

            $exceedsEntries = count($window) >= self::HISTORY_MAX_ENTRIES;
            $exceedsLength  = $window !== [] && $total + $length > self::HISTORY_TOTAL_MAX_LENGTH;

            if ($exceedsEntries || $exceedsLength) {
                break;
            }

            $window[] = $entry;
            $total += $length;
        }

        $request->merge(['history' => array_reverse($window)]);
    }
}
