<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\MediaFile;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Str;
use Illuminate\Http\JsonResponse;
use App\Http\Controllers\Controller;

class MediaController extends Controller
{
    /**
     * Upload a file
     */
    public function upload(Request $request): JsonResponse
    {
        $request->validate([
            'file' => 'required|file|max:50000', // 50MB max
            'uploadable_type' => 'nullable|string',
            'uploadable_id' => 'nullable|integer',
            'description' => 'nullable|string|max:255',
        ]);

        try {
            $file = $request->file('file');
            $originalName = $file->getClientOriginalName();
            $extension = $file->getClientOriginalExtension();
            $mimeType = $file->getMimeType();

            // Generate unique filename
            $filename = Str::uuid() . '.' . $extension;

            // Determine file type
            $fileType = $this->getFileType($mimeType);

            // Store file
            $path = $file->storeAs("uploads/{$fileType}s", $filename, 'public');

            // Get file metadata
            $metadata = $this->getFileMetadata($file, $fileType);

            // Create database record
            $mediaFile = MediaFile::create([
                'filename' => $filename,
                'original_name' => $originalName,
                'file_path' => $path,
                'file_type' => $fileType,
                'mime_type' => $mimeType,
                'file_size' => $file->getSize(),
                'uploaded_by' => Auth::id(),
                'uploadable_type' => $request->uploadable_type,
                'uploadable_id' => $request->uploadable_id,
                'description' => $request->description,
                'metadata' => $metadata,
                'is_public' => true,
            ]);

            return response()->json([
                'success' => true,
                'message' => 'File uploaded successfully',
                'file' => [
                    'id' => $mediaFile->id,
                    'filename' => $mediaFile->filename,
                    'original_name' => $mediaFile->original_name,
                    'url' => $mediaFile->url,
                    'type' => $mediaFile->file_type,
                    'size' => $mediaFile->formatted_size,
                    'icon' => $mediaFile->icon,
                ]
            ]);

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

    /**
     * Get file by ID
     */
    public function show(MediaFile $mediaFile)
    {
        // Check if user has permission to view this file
        if (!$mediaFile->is_public && $mediaFile->uploaded_by !== Auth::id()) {
            abort(403);
        }

        return response()->file(storage_path('app/public/' . $mediaFile->file_path));
    }

    /**
     * Delete a file
     */
    public function destroy(MediaFile $mediaFile): JsonResponse
    {
        // Check if user has permission to delete this file
        if ($mediaFile->uploaded_by !== Auth::id() && !Auth::user()->isAdmin()) {
            return response()->json([
                'success' => false,
                'message' => 'Unauthorized'
            ], 403);
        }

        try {
            // Delete file from storage
            Storage::disk('public')->delete($mediaFile->file_path);

            // Delete database record
            $mediaFile->delete();

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

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

    /**
     * Get files for a specific uploadable model
     */
    public function getFiles(Request $request): JsonResponse
    {
        $request->validate([
            'uploadable_type' => 'required|string',
            'uploadable_id' => 'required|integer',
        ]);

        $files = MediaFile::where('uploadable_type', $request->uploadable_type)
            ->where('uploadable_id', $request->uploadable_id)
            ->orderBy('created_at', 'desc')
            ->get()
            ->map(function ($file) {
                return [
                    'id' => $file->id,
                    'filename' => $file->filename,
                    'original_name' => $file->original_name,
                    'url' => $file->url,
                    'type' => $file->file_type,
                    'size' => $file->formatted_size,
                    'icon' => $file->icon,
                    'description' => $file->description,
                    'created_at' => $file->created_at->format('M d, Y'),
                ];
            });

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

    /**
     * Determine file type based on MIME type
     */
    private function getFileType(string $mimeType): string
    {
        if (str_starts_with($mimeType, 'image/')) {
            return 'image';
        } elseif (str_starts_with($mimeType, 'video/')) {
            return 'video';
        } elseif (str_starts_with($mimeType, 'audio/')) {
            return 'audio';
        } else {
            return 'document';
        }
    }

    /**
     * Get file metadata based on type
     */
    private function getFileMetadata($file, string $fileType): array
    {
        $metadata = [];

        if ($fileType === 'image') {
            $imageInfo = getimagesize($file->getPathname());
            if ($imageInfo) {
                $metadata['width'] = $imageInfo[0];
                $metadata['height'] = $imageInfo[1];
            }
        }

        return $metadata;
    }
}
