<?php

namespace App\Http\Controllers;

use App\Models\Attachment;
use App\Services\AttachmentService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Storage;
use Symfony\Component\HttpFoundation\StreamedResponse;

class AttachmentController extends Controller
{
    /**
     * Download an attachment.
     *
     * @param Request $request
     * @param int $attachmentId
     * @return StreamedResponse|\Illuminate\Http\RedirectResponse
     */
    public function download(Request $request, int $attachmentId)
    {
        try {
            // Find attachment
            $attachment = Attachment::findOrFail($attachmentId);

            // Check if user can download
            if (!AttachmentService::canDownload($attachment, Auth::user())) {
                abort(403, 'Unauthorized to download this attachment.');
            }

            // Check if file exists
            if (!$attachment->fileExists()) {
                abort(404, 'File not found.');
            }

            // Check virus scan status
            if (!$attachment->isSafe() && $attachment->virus_scanned) {
                abort(403, 'This file has been flagged as potentially dangerous and cannot be downloaded.');
            }

            // Increment download counter
            $attachment->incrementDownloadCount();

            // Stream the file
            return Storage::disk($attachment->storage_disk)->download(
                $attachment->storage_path,
                $attachment->original_filename,
                [
                    'Content-Type' => $attachment->mime_type,
                    'Content-Disposition' => 'attachment; filename="' . $attachment->original_filename . '"',
                ]
            );

        } catch (\Exception $e) {
            logger()->error("Attachment download failed: " . $e->getMessage());
            abort(500, 'Failed to download attachment.');
        }
    }

    /**
     * View/preview an attachment inline (for images, PDFs, etc.).
     *
     * @param Request $request
     * @param int $attachmentId
     * @return StreamedResponse|\Illuminate\Http\RedirectResponse
     */
    public function view(Request $request, int $attachmentId)
    {
        try {
            // Find attachment
            $attachment = Attachment::findOrFail($attachmentId);

            // Check if user can download/view
            if (!AttachmentService::canDownload($attachment, Auth::user())) {
                abort(403, 'Unauthorized to view this attachment.');
            }

            // Check if file exists
            if (!$attachment->fileExists()) {
                abort(404, 'File not found.');
            }

            // Check virus scan status
            if (!$attachment->isSafe() && $attachment->virus_scanned) {
                abort(403, 'This file has been flagged as potentially dangerous and cannot be viewed.');
            }

            // Only allow inline viewing for safe MIME types
            $safeInlineMimeTypes = [
                'image/jpeg',
                'image/png',
                'image/gif',
                'image/webp',
                'application/pdf',
                'text/plain',
            ];

            $disposition = in_array($attachment->mime_type, $safeInlineMimeTypes)
                ? 'inline'
                : 'attachment';

            // Stream the file
            return Storage::disk($attachment->storage_disk)->response(
                $attachment->storage_path,
                $attachment->original_filename,
                [
                    'Content-Type' => $attachment->mime_type,
                    'Content-Disposition' => $disposition . '; filename="' . $attachment->original_filename . '"',
                ]
            );

        } catch (\Exception $e) {
            logger()->error("Attachment view failed: " . $e->getMessage());
            abort(500, 'Failed to view attachment.');
        }
    }

    /**
     * Get thumbnail for an image attachment.
     *
     * @param Request $request
     * @param int $attachmentId
     * @return StreamedResponse|\Illuminate\Http\RedirectResponse
     */
    public function thumbnail(Request $request, int $attachmentId)
    {
        try {
            // Find attachment
            $attachment = Attachment::findOrFail($attachmentId);

            // Check if user can view
            if (!AttachmentService::canDownload($attachment, Auth::user())) {
                abort(403, 'Unauthorized to view this thumbnail.');
            }

            // Check if thumbnail exists
            if (!$attachment->thumbnail_path) {
                // If no thumbnail, redirect to original image (if it's an image)
                if ($attachment->isImage()) {
                    return $this->view($request, $attachmentId);
                }

                abort(404, 'Thumbnail not found.');
            }

            // Check if thumbnail file exists
            if (!Storage::disk($attachment->storage_disk)->exists($attachment->thumbnail_path)) {
                abort(404, 'Thumbnail file not found.');
            }

            // Stream the thumbnail
            return Storage::disk($attachment->storage_disk)->response(
                $attachment->thumbnail_path,
                'thumb_' . $attachment->original_filename,
                [
                    'Content-Type' => $attachment->mime_type,
                    'Content-Disposition' => 'inline',
                ]
            );

        } catch (\Exception $e) {
            logger()->error("Thumbnail view failed: " . $e->getMessage());
            abort(500, 'Failed to view thumbnail.');
        }
    }

    /**
     * Delete an attachment (soft delete).
     *
     * @param Request $request
     * @param int $attachmentId
     * @return \Illuminate\Http\JsonResponse
     */
    public function destroy(Request $request, int $attachmentId)
    {
        try {
            // Find attachment
            $attachment = Attachment::findOrFail($attachmentId);

            // Check authorization
            if (!AttachmentService::canDownload($attachment, Auth::user())) {
                return response()->json([
                    'success' => false,
                    'message' => 'Unauthorized to delete this attachment.',
                ], 403);
            }

            // Delete attachment
            $deleted = AttachmentService::delete($attachment);

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

            return response()->json([
                'success' => false,
                'message' => 'Failed to delete attachment.',
            ], 500);

        } catch (\Exception $e) {
            logger()->error("Attachment deletion failed: " . $e->getMessage());

            return response()->json([
                'success' => false,
                'message' => 'An error occurred while deleting the attachment.',
            ], 500);
        }
    }

    /**
     * Get attachment metadata (for AJAX requests).
     *
     * @param Request $request
     * @param int $attachmentId
     * @return \Illuminate\Http\JsonResponse
     */
    public function metadata(Request $request, int $attachmentId)
    {
        try {
            // Find attachment
            $attachment = Attachment::findOrFail($attachmentId);

            // Check if user can view
            if (!AttachmentService::canDownload($attachment, Auth::user())) {
                return response()->json([
                    'success' => false,
                    'message' => 'Unauthorized.',
                ], 403);
            }

            return response()->json([
                'success' => true,
                'data' => [
                    'id' => $attachment->id,
                    'filename' => $attachment->original_filename,
                    'size' => $attachment->size,
                    'formatted_size' => $attachment->formatted_size,
                    'mime_type' => $attachment->mime_type,
                    'extension' => $attachment->extension,
                    'is_image' => $attachment->isImage(),
                    'is_pdf' => $attachment->isPdf(),
                    'is_video' => $attachment->isVideo(),
                    'is_safe' => $attachment->isSafe(),
                    'virus_scanned' => $attachment->virus_scanned,
                    'download_count' => $attachment->download_count,
                    'created_at' => $attachment->created_at->toISOString(),
                    'download_url' => $attachment->getSignedDownloadUrl(),
                    'thumbnail_url' => $attachment->getThumbnailUrl(),
                ],
            ]);

        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to retrieve attachment metadata.',
            ], 500);
        }
    }
}
