<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Http\Requests\UploadAdminDocumentRequest;
use App\Models\AdminDocument;
use App\Models\AuditLog;
use App\Services\AdminDocumentService;
use App\Services\AuditService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;

class DocumentController extends Controller
{
    public function __construct(
        private readonly AdminDocumentService $documentService,
        private readonly AuditService $auditService,
    ) {}

    /**
     * Upload a new document.
     */
    public function store(UploadAdminDocumentRequest $request): JsonResponse
    {
        $document = $this->documentService->upload(
            $request->file('file'),
            $request->validated('name'),
            $request->validated('description'),
            $request->user(),
        );

        $this->auditService->success(
            AuditLog::ACTION_DOCUMENT_UPLOADED,
            AuditLog::ACTOR_ADMIN,
            $request->user()->id,
            $request->user()->email,
            'AdminDocument', $document->id,
            ['name' => $document->name, 'filename' => $document->original_filename, 'size' => $document->file_size],
            $request->ip(),
        );

        return response()->json([
            'success' => true,
            'message' => 'Document uploaded successfully.',
            'data'    => $this->formatDocument($document),
        ], 201);
    }

    /**
     * List all documents (paginated, searchable).
     */
    public function index(Request $request): JsonResponse
    {
        $perPage = min(max((int) $request->input('per_page', 15), 1), 100);
        $search  = $request->input('search');

        $documents = $this->documentService->list($perPage, $search);

        return response()->json([
            'success' => true,
            'data'    => collect($documents->items())->map(fn ($d) => $this->formatDocument($d)),
            'pagination' => [
                'current_page' => $documents->currentPage(),
                'last_page'    => $documents->lastPage(),
                'per_page'     => $documents->perPage(),
                'total'        => $documents->total(),
                'from'         => $documents->firstItem() ?? 0,
                'to'           => $documents->lastItem() ?? 0,
            ],
        ]);
    }

    /**
     * View a single document's metadata.
     */
    public function show(int $id, Request $request): JsonResponse
    {
        $document = $this->documentService->find($id);

        $this->auditService->success(
            AuditLog::ACTION_DOCUMENT_VIEWED,
            AuditLog::ACTOR_ADMIN,
            $request->user()->id,
            $request->user()->email,
            'AdminDocument', $document->id,
            ['name' => $document->name],
            $request->ip(),
        );

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

    /**
     * Force-download a document file.
     */
    public function download(int $id, Request $request)
    {
        $document = $this->documentService->find($id);

        if (! Storage::disk('kyc')->exists($document->file_path)) {
            return response()->json([
                'success' => false,
                'message' => 'File not found on storage.',
            ], 404);
        }

        $this->auditService->success(
            AuditLog::ACTION_DOCUMENT_DOWNLOADED,
            AuditLog::ACTOR_ADMIN,
            $request->user()->id,
            $request->user()->email,
            'AdminDocument', $document->id,
            ['name' => $document->name, 'filename' => $document->original_filename],
            $request->ip(),
        );

        $fileContent = Storage::disk('kyc')->get($document->file_path);

        return response()->streamDownload(
            function () use ($fileContent) { echo $fileContent; },
            $document->original_filename,
            ['Content-Type' => $document->mime_type],
        );
    }

    /**
     * Delete a document.
     */
    public function destroy(int $id, Request $request): JsonResponse
    {
        $document = $this->documentService->find($id);

        $this->auditService->success(
            AuditLog::ACTION_DOCUMENT_DELETED,
            AuditLog::ACTOR_ADMIN,
            $request->user()->id,
            $request->user()->email,
            'AdminDocument', $document->id,
            ['name' => $document->name, 'filename' => $document->original_filename],
            $request->ip(),
        );

        $this->documentService->delete($document);

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

    private function formatDocument(AdminDocument $document): array
    {
        return [
            'id'                => $document->id,
            'name'              => $document->name,
            'original_filename' => $document->original_filename,
            'extension'         => $document->extension,
            'mime_type'         => $document->mime_type,
            'file_size'         => $document->file_size,
            'file_size_formatted' => $document->file_size_formatted,
            'description'       => $document->description,
            'url'               => $document->url,
            'uploaded_by'       => $document->uploader ? [
                'id'    => $document->uploader->id,
                'name'  => $document->uploader->name,
                'email' => $document->uploader->email,
            ] : null,
            'uploaded_at'       => $document->created_at->toIso8601String(),
        ];
    }
}
