<?php

declare(strict_types=1);

namespace App\Http\Controllers\API\V1;

use App\Http\Controllers\Controller;
use App\Http\Requests\AssistantChatRequest;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

/**
 * AI Assistant Controller
 *
 * APIs for interacting with the AI shopping assistant powered by Prism with tool calling.
 * The assistant can search products, compare options, find deals, and provide recommendations.
 */
class AssistantController extends Controller
{
    public function __construct(
        private \App\Services\AiAssistant\AiAssistantService $assistant
    ) {}

    /**
     * Chat with AI Assistant
     *
     * Send a message to the AI shopping assistant. The assistant uses tool calling to
     * search products, compare options, find deals, and provide intelligent recommendations.
     *
     * @authenticated
     *
     * @bodyParam message string required The user's message to the AI assistant. Max 5000 characters. Example: What are the best deals today?
     * @bodyParam conversation_id string optional ULID of existing conversation to continue. Example: 01ARZ3NDEKTSV4RRFFQ69G5FAV
     *
     * @response 200 {
     *   "success": true,
     *   "data": {
     *     "response": "Here are some great deals available right now...",
     *     "conversation_id": "01ARZ3NDEKTSV4RRFFQ69G5FAV"
     *   },
     *   "metadata": {
     *     "provider": "deepseek",
     *     "tools_used": ["find_deals"]
     *   }
     * }
     */
    public function chat(AssistantChatRequest $request): JsonResponse
    {
        $user = Auth::user();
        $conversationId = $request->input('conversation_id');

        try {
            $result = $this->assistant->chat(
                message: $request->input('message'),
                conversationUlid: $conversationId,
                user: $user
            );

            return response()->json([
                'success' => true,
                'data' => [
                    'response' => $result['content'],
                    'conversation_id' => $result['conversation_id'],
                ],
                'metadata' => [
                    'provider' => $result['provider'],
                    'tools_used' => $result['tools_used'] ?? [],
                ],
            ], 200);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'An error occurred while processing your request.',
                'error' => config('app.debug') ? $e->getMessage() : null,
            ], 500);
        }
    }

    /**
     * Stream AI Response (SSE)
     *
     * Send a message and receive a streaming response using Server-Sent Events (SSE).
     * The AI response is streamed in real-time as chunks, with tool calls and results
     * sent as separate events.
     *
     * @authenticated
     *
     * @bodyParam message string required The user's message to the AI assistant. Max 5000 characters.
     * @bodyParam conversation_id string optional ULID of existing conversation to continue.
     *
     * @response 200 {
     *   "type": "content",
     *   "content": "Here"
     * }
     */
    public function stream(Request $request): \Symfony\Component\HttpFoundation\StreamedResponse
    {
        $request->validate([
            'message' => 'required|string|max:5000',
            'conversation_id' => 'nullable|string',
        ]);

        $user = Auth::user();
        $conversationId = $request->input('conversation_id');

        return $this->assistant->stream(
            message: $request->input('message'),
            conversationUlid: $conversationId,
            user: $user
        );
    }

    /**
     * List Conversations
     *
     * Get all conversations for the authenticated user, sorted by last message time.
     *
     * @authenticated
     *
     * @response 200 {
     *   "success": true,
     *   "data": {
     *     "conversations": [
     *       {
     *         "id": "01ARZ3NDEKTSV4RRFFQ69G5FAV",
     *         "title": "What are the best deals",
     *         "last_message_at": "2026-02-03T10:30:00.000000Z",
     *         "message_count": 5
     *       }
     *     ],
     *     "total": 1
     *   }
     * }
     */
    public function conversations(): JsonResponse
    {
        $user = Auth::user();

        try {
            $conversations = $this->assistant->getConversations($user);

            return response()->json([
                'success' => true,
                'data' => [
                    'conversations' => $conversations,
                    'total' => count($conversations),
                ],
            ], 200);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to retrieve conversations.',
                'error' => config('app.debug') ? $e->getMessage() : null,
            ], 500);
        }
    }

    /**
     * Get Conversation Messages
     *
     * Get all messages in a specific conversation by ULID.
     *
     * @authenticated
     *
     * @urlParam ulid string required The ULID of the conversation. Example: 01ARZ3NDEKTSV4RRFFQ69G5FAV
     *
     * @response 200 {
     *   "success": true,
     *   "data": {
     *     "conversation_id": "01ARZ3NDEKTSV4RRFFQ69G5FAV",
     *     "messages": [
     *       {
     *         "id": 1,
     *         "role": "user",
     *         "content": "What are the best deals?",
     *         "created_at": "2026-02-03T10:30:00.000000Z"
     *       }
     *     ],
     *     "total": 2
     *   }
     * }
     */
    public function conversation(string $ulid): JsonResponse
    {
        try {
            $messages = $this->assistant->getConversationMessages($ulid);

            return response()->json([
                'success' => true,
                'data' => [
                    'conversation_id' => $ulid,
                    'messages' => $messages,
                    'total' => count($messages),
                ],
            ], 200);
        } catch (\Illuminate\Database\Eloquent\ModelNotFoundException $e) {
            return response()->json([
                'success' => false,
                'message' => 'Conversation not found.',
            ], 404);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to retrieve conversation.',
                'error' => config('app.debug') ? $e->getMessage() : null,
            ], 500);
        }
    }

    /**
     * Delete Conversation
     *
     * Permanently delete a conversation and all its messages.
     *
     * @authenticated
     *
     * @urlParam ulid string required The ULID of the conversation to delete.
     *
     * @response 200 {
     *   "success": true,
     *   "message": "Conversation deleted successfully."
     * }
     */
    public function deleteConversation(string $ulid): JsonResponse
    {
        try {
            $this->assistant->deleteConversation($ulid);

            return response()->json([
                'success' => true,
                'message' => 'Conversation deleted successfully.',
            ], 200);
        } catch (\Illuminate\Database\Eloquent\ModelNotFoundException $e) {
            return response()->json([
                'success' => false,
                'message' => 'Conversation not found.',
            ], 404);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to delete conversation.',
                'error' => config('app.debug') ? $e->getMessage() : null,
            ], 500);
        }
    }

    /**
     * Get Chat History
     *
     * Get message history for a specific conversation (alias for GET /assistant/conversations/{ulid}).
     *
     * @authenticated
     *
     * @queryParam conversation_id string required The ULID of the conversation.
     *
     * @response 200 {
     *   "success": true,
     *   "data": {
     *     "history": [...],
     *     "total": 10
     *   }
     * }
     */
    public function getHistory(Request $request): JsonResponse
    {
        $conversationId = $request->query('conversation_id');

        if (! $conversationId) {
            return response()->json([
                'success' => false,
                'message' => 'conversation_id is required.',
            ], 400);
        }

        try {
            $messages = $this->assistant->getConversationMessages($conversationId);

            return response()->json([
                'success' => true,
                'data' => [
                    'history' => $messages,
                    'total' => count($messages),
                ],
            ], 200);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to retrieve chat history.',
                'error' => config('app.debug') ? $e->getMessage() : null,
            ], 500);
        }
    }

    /**
     * Clear Chat History
     *
     * Delete a conversation by ID (alias for DELETE /assistant/conversations/{ulid}).
     *
     * @authenticated
     *
     * @bodyParam conversation_id string required The ULID of the conversation to delete.
     *
     * @response 200 {
     *   "success": true,
     *   "message": "Conversation deleted successfully."
     * }
     */
    public function clearHistory(Request $request): JsonResponse
    {
        $conversationId = $request->input('conversation_id');

        if (! $conversationId) {
            return response()->json([
                'success' => false,
                'message' => 'conversation_id is required.',
            ], 400);
        }

        try {
            $this->assistant->deleteConversation($conversationId);

            return response()->json([
                'success' => true,
                'message' => 'Conversation deleted successfully.',
            ], 200);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to delete conversation.',
                'error' => config('app.debug') ? $e->getMessage() : null,
            ], 500);
        }
    }

    /**
     * Get Follow-up Suggestions
     *
     * Get suggested follow-up questions to help users explore further.
     *
     * @response 200 {
     *   "success": true,
     *   "data": {
     *     "suggestions": [
     *       "Find products under [price]",
     *       "What are the best deals today?"
     *     ],
     *     "count": 8
     *   }
     * }
     */
    public function getSuggestions(): JsonResponse
    {
        $suggestions = [
            'Find products under [price]',
            'What are the best deals today?',
            'Recommend products in [category]',
            'Compare products [id1], [id2], [id3]',
            'Tell me about product [id]',
            'Show me trending products',
            'Find products with discounts above 20%',
            'Show me the highest-rated products',
        ];

        return response()->json([
            'success' => true,
            'data' => [
                'suggestions' => $suggestions,
                'count' => count($suggestions),
            ],
        ], 200);
    }
}
