<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\AiPromptLog;
use App\Services\AiAssistantService;
use Illuminate\Http\Client\RequestException;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\RateLimiter;

class AiAssistantController extends Controller
{
    private const DAILY_LIMIT = 50;

    public function __construct(protected AiAssistantService $assistant)
    {
        $this->middleware(function ($request, $next) {
            abort_unless($request->user()?->hasAnyRole(['Super Admin', 'Admin']), 403);

            return $next($request);
        });
    }

    public function index(Request $request)
    {
        return view('admin.ai-assistant.index', [
            'used' => RateLimiter::attempts($this->limitKey($request)),
            'limit' => self::DAILY_LIMIT,
            'configured' => filled(config('services.openai.key')),
            'recent' => AiPromptLog::where('user_id', $request->user()->id)->latest()->limit(10)->get(),
        ]);
    }

    public function chat(Request $request)
    {
        $data = $request->validate(['message' => ['required', 'string', 'max:2000']]);
        $key = $this->limitKey($request);
        if (RateLimiter::tooManyAttempts($key, self::DAILY_LIMIT)) {
            return response()->json(['message' => __('ai.daily_limit', ['limit' => self::DAILY_LIMIT]), 'remaining' => 0], 429);
        }
        RateLimiter::hit($key, max(1, now()->diffInSeconds(now()->endOfDay())));
        $log = AiPromptLog::create(['user_id' => $request->user()->id, 'prompt' => 'sha256:'.hash('sha256', $data['message']), 'status' => 'processing', 'usage_date' => today()]);

        try {
            $command = $this->assistant->understand($data['message']);
            $result = $this->assistant->run($command, $request->user()->id);
            $log->update(['intent' => $command['intent'], 'status' => isset($result['confirmation_token']) ? 'confirmation_required' : 'completed', 'metadata' => ['has_confirmation' => isset($result['confirmation_token'])]]);

            return response()->json(array_merge($result, ['remaining' => max(0, self::DAILY_LIMIT - RateLimiter::attempts($key))]));
        } catch (RequestException $exception) {
            RateLimiter::decrement($key);
            $errorCode = $exception->response->json('error.code');
            $message = $exception->response->status() === 429
                ? ($errorCode === 'insufficient_quota' ? __('ai.provider_quota') : __('ai.provider_rate'))
                : __('ai.provider_failed');
            $log->update(['status' => 'provider_failed', 'metadata' => ['http_status' => $exception->response->status(), 'error_code' => $errorCode]]);

            return response()->json(['message' => $message, 'remaining' => max(0, self::DAILY_LIMIT - RateLimiter::attempts($key))], 503);
        } catch (\Throwable $exception) {
            report($exception);
            $log->update(['status' => 'failed', 'metadata' => ['error_type' => class_basename($exception)]]);

            return response()->json(['message' => $exception->getMessage(), 'remaining' => max(0, self::DAILY_LIMIT - RateLimiter::attempts($key))], 422);
        }
    }

    public function confirm(Request $request)
    {
        $data = $request->validate(['token' => ['required', 'string', 'size:48']]);
        try {
            return response()->json($this->assistant->confirm($data['token'], $request->user()->id));
        } catch (\Throwable $exception) {
            report($exception);

            return response()->json(['message' => $exception->getMessage()], 422);
        }
    }

    private function limitKey(Request $request): string
    {
        return 'ai-prompts:'.$request->user()->id.':'.today()->format('Y-m-d');
    }
}
