<?php

declare(strict_types=1);

namespace App\Http\Controllers\Customer;

use App\Domain\Ai\Services\AiManager;
use App\Domain\Ai\Services\PanelContextBuilder;
use App\Http\Controllers\Controller;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Symfony\Component\HttpFoundation\StreamedResponse;

class AiAssistantController extends Controller
{
    public function __construct(
        private readonly AiManager $ai,
        private readonly PanelContextBuilder $contextBuilder,
    ) {}

    public function chat(Request $request): JsonResponse
    {
        $validated = $request->validate([
            'message' => ['required', 'string', 'max:5000'],
            'conversation_id' => ['nullable', 'integer'],
        ]);

        $user = $request->user();

        // Token budget enforcement
        $dailyUsed = DB::table('ai_conversations')
            ->where('user_id', $user->id)
            ->where('created_at', '>', now()->startOfDay())
            ->sum('tokens_used');

        $budget = (int) config('services.ai.token_budget_per_user_per_day', 50000);

        if ($dailyUsed >= $budget) {
            return response()->json([
                'text' => "Bugünkü AI token kotanız doldu ({$budget} token). Yarın sıfırlanacak.",
                'budget_exceeded' => true,
            ], 429);
        }

        // Build conversation history
        $messages = [
            ['role' => 'system', 'content' => $this->contextBuilder->buildSystemPrompt($user)],
        ];

        if ($conversationId = ($validated['conversation_id'] ?? null)) {
            $history = DB::table('ai_conversations')
                ->where('id', '<=', $conversationId)
                ->where('user_id', $user->id)
                ->orderBy('id')
                ->limit(10)
                ->get();

            foreach ($history as $h) {
                $messages[] = ['role' => 'user', 'content' => $h->message];
                $messages[] = ['role' => 'assistant', 'content' => $h->response];
            }
        }

        $messages[] = ['role' => 'user', 'content' => $validated['message']];

        try {
            $provider = $this->ai->provider();
            $response = $provider->chat($messages);
        } catch (\Throwable $e) {
            Log::error('AI chat error', ['error' => $e->getMessage(), 'user_id' => $user->id]);

            return response()->json([
                'text' => 'AI servisinde geçici bir sorun oluştu. Lütfen daha sonra tekrar deneyin.',
                'error' => true,
            ], 500);
        }

        // Parse [GO:/path:label] suggestions
        $suggestedActions = $this->parseSuggestedActions($response['text']);
        $cleanText = preg_replace('/\[GO:[^\]]+\]/', '', $response['text']);
        $cleanText = trim($cleanText ?? '');

        // Persist conversation
        $convId = DB::table('ai_conversations')->insertGetId([
            'user_id' => $user->id,
            'message' => $validated['message'],
            'response' => $cleanText,
            'tokens_used' => $response['tokens_used'],
            'provider' => $provider->name(),
            'model' => $response['model'],
            'created_at' => now(),
            'updated_at' => now(),
        ]);

        return response()->json([
            'conversation_id' => $convId,
            'text' => $cleanText,
            'suggested_actions' => $suggestedActions,
            'tokens_used' => $response['tokens_used'],
            'provider' => $provider->name(),
            'model' => $response['model'],
        ]);
    }

    public function stream(Request $request): StreamedResponse
    {
        $validated = $request->validate([
            'message' => ['required', 'string', 'max:5000'],
        ]);

        $user = $request->user();
        $messages = [
            ['role' => 'system', 'content' => $this->contextBuilder->buildSystemPrompt($user)],
            ['role' => 'user', 'content' => $validated['message']],
        ];

        $provider = $this->ai->provider();

        return response()->stream(function () use ($provider, $messages) {
            try {
                foreach ($provider->chatStream($messages) as $chunk) {
                    echo 'data: '.json_encode(['chunk' => $chunk])."\n\n";

                    if (function_exists('ob_flush')) {
                        @ob_flush();
                    }

                    flush();
                }

                echo "data: [DONE]\n\n";
            } catch (\Throwable $e) {
                echo 'data: '.json_encode(['error' => $e->getMessage()])."\n\n";
            }
        }, 200, [
            'Content-Type' => 'text/event-stream',
            'Cache-Control' => 'no-cache',
            'X-Accel-Buffering' => 'no',
        ]);
    }

    public function history(Request $request): JsonResponse
    {
        $items = DB::table('ai_conversations')
            ->where('user_id', $request->user()->id)
            ->orderByDesc('id')
            ->limit(50)
            ->get();

        return response()->json(['data' => $items]);
    }

    public function clear(Request $request): JsonResponse
    {
        DB::table('ai_conversations')->where('user_id', $request->user()->id)->delete();

        return response()->json(['cleared' => true]);
    }

    /** @return array<int, array{label: string, href: string}> */
    private function parseSuggestedActions(string $text): array
    {
        preg_match_all('/\[GO:([^:]+):([^\]]+)\]/', $text, $matches, PREG_SET_ORDER);

        $actions = [];

        foreach ($matches as $m) {
            $actions[] = ['label' => $m[2], 'href' => $m[1]];
        }

        return $actions;
    }
}
