<?php

namespace App\Http\Controllers\User;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Http;

/**
 * User-facing AI support bot. Same server-side proxy pattern as the admin
 * assistant: the API key never reaches the browser. The bot answers common
 * platform questions; when it can't (or the issue needs account
 * investigation) it emits an [OPEN_TICKET] marker so the UI can steer the
 * user to the ticket form.
 */
class SupportBotController extends Controller
{
    private const ENDPOINTS = [
        'openrouter' => 'https://openrouter.ai/api/v1/chat/completions',
        'nvidia' => 'https://integrate.api.nvidia.com/v1/chat/completions',
    ];

    public function chat(Request $request)
    {
        if (!site_bool('ai_support_bot_enabled', false)) {
            return response()->json(['error' => 'The support assistant is currently unavailable. Please open a ticket instead.'], 403);
        }

        $data = $request->validate([
            'messages' => ['required', 'array', 'min:1', 'max:20'],
            'messages.*.role' => ['required', 'in:user,assistant'],
            'messages.*.content' => ['required', 'string', 'max:2000'],
        ]);

        $provider = site_setting('ai_provider', 'openrouter');
        $endpoint = self::ENDPOINTS[$provider] ?? self::ENDPOINTS['openrouter'];
        $apiKey = trim((string) site_setting('ai_api_key', ''));
        $model = trim((string) site_setting('ai_model', ''));

        if ($apiKey === '' || $model === '') {
            return response()->json(['error' => 'The support assistant is not configured yet. Please open a ticket instead.', 'suggest_ticket' => true], 422);
        }

        try {
            $response = Http::withToken($apiKey)
                ->timeout(45)
                ->withHeaders($provider === 'openrouter' ? [
                    'HTTP-Referer' => config('app.url'),
                    'X-Title' => brand_name().' Support',
                ] : [])
                ->post($endpoint, [
                    'model' => $model,
                    'messages' => array_merge(
                        [['role' => 'system', 'content' => $this->systemPrompt($request)]],
                        array_map(fn ($m) => ['role' => $m['role'], 'content' => $m['content']], $data['messages'])
                    ),
                    'temperature' => 0.3,
                    'max_tokens' => 600,
                ]);
        } catch (\Throwable $exception) {
            return response()->json(['error' => 'The assistant could not be reached. Please open a ticket instead.', 'suggest_ticket' => true], 502);
        }

        $reply = $response->successful() ? $response->json('choices.0.message.content') : null;

        if (!is_string($reply) || trim($reply) === '') {
            return response()->json(['error' => 'The assistant could not answer right now. Please open a ticket instead.', 'suggest_ticket' => true], 502);
        }

        $suggestTicket = str_contains($reply, '[OPEN_TICKET]');
        $reply = trim(str_replace('[OPEN_TICKET]', '', $reply));

        return response()->json([
            'reply' => $reply,
            'suggest_ticket' => $suggestTicket,
        ]);
    }

    /**
     * Only platform knowledge and the asking user's own aggregate numbers —
     * no other users' data and no business revenue internals.
     */
    private function systemPrompt(Request $request): string
    {
        $user = $request->user();
        $pointsName = site_setting('points_name', 'coins');

        $context = [
            'points_name' => $pointsName,
            'conversion' => '100 '.$pointsName.' = $1 USD',
            'your_balance' => (float) $user->current_points,
            'your_pending_withdrawals' => $user->withdrawals()->where('status', 'pending')->count(),
            'referral_commission_percent' => (float) site_setting('referral_commission_percent', 5),
        ];

        return 'You are the friendly support assistant for '.brand_name().', a rewards platform where members earn '
            .$pointsName.' by completing offers and surveys and redeem them for cash and gift cards. '
            .'Answer common questions: how earning works, offer credit timing (provider postbacks can take minutes to days), '
            .'withdrawals (reviewed by staff, usually within 24-72 hours), referrals, levels, and account settings. '
            .'Context for this member: '.json_encode($context).'. '
            .'Be concise (2-4 sentences). You cannot see individual offers, transactions, or other users. '
            .'If the question needs account investigation (missing credit for a specific offer, a rejected/delayed payment, '
            .'a ban or verification problem) or you are not confident in the answer, say a human should look at it '
            .'and append the exact token [OPEN_TICKET] at the end of your reply.';
    }
}
