<?php

namespace App\Http\Controllers;

use App\Models\AiDocument;
use App\Services\OllamaService;
use App\Services\RagService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Log;

class DocumentController extends Controller
{
    protected $rag;
    protected $ollama;

    public function __construct(RagService $rag, OllamaService $ollama)
    {
        $this->rag = $rag;
        $this->ollama = $ollama;
    }

    /**
     * Get all documents
     */
    public function index()
    {
        try {
            $documents = AiDocument::latest()->get();
            
            return response()->json([
                'success' => true,
                'documents' => $documents
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'error' => $e->getMessage()
            ], 500);
        }
    }

    /**
     * Upload and process document
     */
    public function upload(Request $request)
    {
        $request->validate([
            'title' => 'required|string|max:255',
            'file' => 'required|file|mimes:txt,pdf,docx|max:10240', // 10MB max
        ]);

        try {
            $file = $request->file('file');
            $filename = $file->getClientOriginalName();
            $fileType = $file->getClientMimeType();
            
            Log::info('Document upload started', [
                'filename' => $filename,
                'type' => $fileType,
                'size' => $file->getSize()
            ]);

            // Store file temporarily
            $path = $file->storeAs('temp', $filename);
            $fullPath = Storage::path($path);

            // Extract text
            $content = $this->rag->extractTextFromFile($fullPath, $fileType);

            Log::info('Text extracted', ['content_length' => strlen($content)]);

            // Process and index document
            $document = $this->rag->processDocument(
                $request->title,
                $content,
                $filename,
                $fileType
            );

            // Clean up temp file
            Storage::delete($path);

            Log::info('Document processed successfully', [
                'document_id' => $document->id,
                'chunks' => $document->chunk_count
            ]);

            return response()->json([
                'success' => true,
                'message' => 'Document uploaded and processed successfully',
                'document' => $document
            ]);

        } catch (\Exception $e) {
            Log::error('Document upload failed', [
                'error' => $e->getMessage(),
                'trace' => $e->getTraceAsString()
            ]);

            return response()->json([
                'success' => false,
                'error' => $e->getMessage()
            ], 500);
        }
    }

    /**
     * Ask question with document context (RAG)
     */
    public function askWithContext(Request $request)
    {
        ini_set('max_execution_time', 600);

        // Test RAG service
        $rag = app(\App\Services\RagService::class);
        $results = $rag->searchSimilar('Cion', 3);
        print_r($results);

        // If empty, check embeddings
        $chunk = \App\Models\AiDocumentChunk::first();
        if ($chunk) {
            echo "Has embedding: " . ($chunk->embedding ? "YES" : "NO") . "\n";
            if ($chunk->embedding) {
                echo "Embedding length: " . count($chunk->embedding) . "\n";
            }
        }

        $request->validate([
            'question' => 'required|string',
            'model' => 'nullable|string'
        ]);

        try {
            Log::info('Question received', [
                'question' => $request->question,
                'model' => $request->model
            ]);

            // Check if we have any documents
            $documentCount = AiDocument::count();
            
            if ($documentCount === 0) {
                Log::warning('No documents found, using direct generation');
                $answer = $this->ollama->generate($request->question, $request->model);
            } else {
                // Use RAG to answer with context
                $answer = $this->rag->answerWithContext(
                    $this->ollama,
                    $request->question,
                    $request->model
                );
            }

            Log::info('Answer generated', ['answer_length' => strlen($answer)]);

            return response()->json([
                'success' => true,
                'answer' => $answer,
                'used_documents' => $documentCount > 0
            ]);

        } catch (\Exception $e) {
            Log::error('Question answering failed', [
                'error' => $e->getMessage(),
                'trace' => $e->getTraceAsString()
            ]);

            return response()->json([
                'success' => false,
                'error' => $e->getMessage()
            ], 500);
        }
    }

    /**
     * Delete document
     */
    public function destroy($id)
    {
        try {
            $document = AiDocument::findOrFail($id);
            
            Log::info('Deleting document', ['document_id' => $id]);
            
            $document->delete(); // Cascades to chunks

            return response()->json([
                'success' => true,
                'message' => 'Document deleted successfully'
            ]);

        } catch (\Exception $e) {
            Log::error('Document deletion failed', [
                'error' => $e->getMessage()
            ]);

            return response()->json([
                'success' => false,
                'error' => $e->getMessage()
            ], 500);
        }
    }

    /**
     * Search similar content
     */
    public function search(Request $request)
    {
        $request->validate([
            'query' => 'required|string',
            'top_k' => 'nullable|integer|min:1|max:20'
        ]);

        try {
            $results = $this->rag->searchSimilar(
                $request->query,
                $request->top_k ?? 5
            );

            Log::info('Search completed', [
                'query' => $request->query,
                'results_count' => count($results)
            ]);

            return response()->json([
                'success' => true,
                'results' => $results
            ]);

        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'error' => $e->getMessage()
            ], 500);
        }
    }

    /**
     * Get document statistics
     */
    public function statistics()
    {
        try {
            $stats = $this->rag->getStatistics();

            return response()->json([
                'success' => true,
                'statistics' => $stats
            ]);

        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'error' => $e->getMessage()
            ], 500);
        }
    }

    /**
     * View document details
     */
    public function show($id)
    {
        try {
            $document = AiDocument::with('chunks')->findOrFail($id);

            return response()->json([
                'success' => true,
                'document' => $document
            ]);

        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'error' => $e->getMessage()
            ], 500);
        }
    }

    /**
     * Test embedding generation
     */
    public function testEmbedding(Request $request)
    {
        $request->validate([
            'text' => 'required|string'
        ]);

        try {
            $embedding = $this->rag->generateEmbedding($request->text);

            return response()->json([
                'success' => true,
                'embedding_length' => count($embedding ?? []),
                'has_embedding' => !is_null($embedding)
            ]);

        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'error' => $e->getMessage()
            ], 500);
        }
    }
}