<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Spatie\MediaLibrary\MediaCollections\Models\Media;
use App\Models\Store;
use App\Models\Brand;
use App\Models\Category;
use App\Models\Occasion;
use App\Models\CarouselSlide;
use App\Models\User;
use Illuminate\Support\Facades\Storage;
use Intervention\Image\Laravel\Facades\Image;

class MediaController extends Controller
{
    /**
     * Display media library
     */
    public function index(Request $request)
    {
        $query = Media::query();

        // Filter by collection type
        if ($request->filled('collection')) {
            $query->where('collection_name', $request->collection);
        }

        // Filter by model type
        if ($request->filled('model_type')) {
            $query->where('model_type', $request->model_type);
        }

        // Search by filename
        if ($request->filled('search')) {
            $search = $request->search;
            $query->where(function ($q) use ($search) {
                $q->where('name', 'like', "%{$search}%")
                  ->orWhere('file_name', 'like', "%{$search}%");
            });
        }

        // Filter by file type
        if ($request->filled('file_type')) {
            $fileType = $request->file_type;
            $query->where('mime_type', 'like', "{$fileType}/%");
        }

        // Sort
        $sortBy = $request->get('sort', 'created_at');
        $sortDirection = $request->get('direction', 'desc');
        $query->orderBy($sortBy, $sortDirection);

        $media = $query->paginate(24)->withQueryString();

        // Get filter options
        $collections = Media::distinct()->pluck('collection_name')->filter();
        
        // Get available models for dropdown
        $availableModels = [
            Store::class => 'المتاجر',
            Brand::class => 'البراندات', 
            Category::class => 'الفئات',
            Occasion::class => 'المناسبات',
            CarouselSlide::class => 'شرائح العرض',
        ];

        // Get model items for initial load
        $modelItems = [];
        foreach ($availableModels as $class => $label) {
            $modelItems[$class] = $class::select('id')->get()->mapWithKeys(function ($item) {
                if (method_exists($item, 'getName')) {
                    $name = $item->getName(1);
                } else {
                    $name = $item->name ?? "#{$item->id}";
                }
                return [$item->id => $name];
            });
        }

        // Calculate stats
        $stats = [
            'total_files' => Media::count(),
            'total_size' => $this->formatBytes(Media::sum('size')),
            'images' => Media::where('mime_type', 'like', 'image/%')->count(),
            'videos' => Media::where('mime_type', 'like', 'video/%')->count(),
        ];

        return view('admin.media.index', compact(
            'media', 
            'collections', 
            'availableModels',
            'modelItems',
            'stats'
        ));
    }

    /**
     * Show create form
     */
    public function create()
    {
        $availableModels = [
            Store::class => 'المتاجر',
            Brand::class => 'البراندات', 
            Category::class => 'الفئات',
            Occasion::class => 'المناسبات',
            CarouselSlide::class => 'شرائح العرض',
        ];

        // Get items for each model
        $modelItems = [];
        foreach ($availableModels as $class => $label) {
            $modelItems[$class] = $class::select('id')->get()->mapWithKeys(function ($item) {
                if (method_exists($item, 'getName')) {
                    $name = $item->getName(1);
                } else {
                    $name = $item->name ?? "#{$item->id}";
                }
                return [$item->id => $name];
            });
        }

        return view('admin.media.create', compact('availableModels', 'modelItems'));
    }

    /**
     * Upload new media files
     */
    public function upload(Request $request)
    {
        $request->validate([
            'files' => 'required|array',
            'files.*' => 'file|max:10240|mimes:jpeg,png,jpg,gif,webp,svg,pdf,doc,docx,mp4,avi,mov',
            'collection' => 'nullable|string',
            'model_type' => 'required|string',
            'model_id' => 'required|integer',
        ]);

        // Verify model exists
        $modelClass = $request->model_type;
        if (!class_exists($modelClass)) {
            return response()->json([
                'success' => false,
                'message' => 'نوع النموذج غير صحيح'
            ], 400);
        }

        $model = $modelClass::find($request->model_id);
        if (!$model) {
            return response()->json([
                'success' => false,
                'message' => 'العنصر المحدد غير موجود'
            ], 404);
        }

        $uploadedFiles = [];
        
        foreach ($request->file('files') as $file) {
            try {
                $originalName = $file->getClientOriginalName();
                $fileName = pathinfo($originalName, PATHINFO_FILENAME);
                $extension = $file->getClientOriginalExtension();
                $mimeType = $file->getMimeType();
                $fileSize = $file->getSize();

                // Generate unique filename
                $uniqueFileName = $fileName . '_' . time() . '_' . uniqid() . '.' . $extension;
                
                // Create directory path
                $directory = "media/{$model->getTable()}/{$model->id}";
                $path = $file->storeAs($directory, $uniqueFileName, 'public');

                // Process image if it's an image
                if (str_starts_with($mimeType, 'image/') && $extension !== 'svg') {
                    $this->processImage(storage_path("app/public/{$path}"));
                }

                // Create media record
                $media = Media::create([
                    'name' => $fileName,
                    'file_name' => $uniqueFileName,
                    'mime_type' => $mimeType,
                    'size' => $fileSize,
                    'collection_name' => $request->collection ?? 'default',
                    'model_type' => $modelClass,
                    'model_id' => $model->id,
                    'disk' => 'public',
                    'conversions_disk' => 'public',
                    'uuid' => \Illuminate\Support\Str::uuid(),
                    'custom_properties' => [
                        'path' => $path,
                        'original_name' => $originalName
                    ]
                ]);

                $uploadedFiles[] = [
                    'id' => $media->id,
                    'name' => $media->name,
                    'url' => asset('storage/' . $path),
                    'size' => $this->formatBytes($media->size),
                    'type' => $media->mime_type,
                ];

            } catch (\Exception $e) {
                \Log::error('Media upload failed: ' . $e->getMessage());
                return response()->json([
                    'success' => false,
                    'message' => 'خطأ في رفع الملف: ' . $e->getMessage()
                ], 500);
            }
        }

        return response()->json([
            'success' => true,
            'message' => 'تم رفع ' . count($uploadedFiles) . ' ملف بنجاح',
            'files' => $uploadedFiles
        ]);
    }

    /**
     * Show edit form
     */
    public function edit(Media $media)
    {
        $availableModels = [
            Store::class => 'المتاجر',
            Brand::class => 'البراندات', 
            Category::class => 'الفئات',
            Occasion::class => 'المناسبات',
            CarouselSlide::class => 'شرائح العرض',
        ];

        // Get items for each model
        $modelItems = [];
        foreach ($availableModels as $class => $label) {
            $modelItems[$class] = $class::select('id')->get()->mapWithKeys(function ($item) {
                if (method_exists($item, 'getName')) {
                    $name = $item->getName(1);
                } else {
                    $name = $item->name ?? "#{$item->id}";
                }
                return [$item->id => $name];
            });
        }

        return view('admin.media.edit', compact('media', 'availableModels', 'modelItems'));
    }

    /**
     * Update media
     */
    public function update(Request $request, Media $media)
    {
        $request->validate([
            'name' => 'required|string|max:255',
            'collection_name' => 'nullable|string|max:255',
            'model_type' => 'required|string',
            'model_id' => 'required|integer',
        ]);

        // Verify new model exists if changed
        if ($request->model_type !== $media->model_type || $request->model_id != $media->model_id) {
            $modelClass = $request->model_type;
            if (!class_exists($modelClass)) {
                return back()->withErrors(['model_type' => 'نوع النموذج غير صحيح']);
            }

            $model = $modelClass::find($request->model_id);
            if (!$model) {
                return back()->withErrors(['model_id' => 'العنصر المحدد غير موجود']);
            }
        }

        try {
            $media->update([
                'name' => $request->name,
                'collection_name' => $request->collection_name ?? 'default',
                'model_type' => $request->model_type,
                'model_id' => $request->model_id,
            ]);

            flash_success('تم تحديث الملف بنجاح');
            return redirect()->route('admin.media.index');

        } catch (\Exception $e) {
            flash_error('خطأ في تحديث الملف: ' . $e->getMessage());
            return back();
        }
    }

    /**
     * Delete media file
     */
    public function destroy(Media $media)
    {
        try {
            // Delete file from storage
            $customProperties = $media->custom_properties ?? [];
            $path = $customProperties['path'] ?? null;
            
            if ($path && Storage::disk('public')->exists($path)) {
                Storage::disk('public')->delete($path);
            }

            $media->delete();
            
            flash_success('تم حذف الملف بنجاح');
            return response()->json(['success' => true]);
            
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'خطأ في حذف الملف'
            ], 500);
        }
    }

    /**
     * Download media file
     */
    public function download(Media $media)
    {
        $customProperties = $media->custom_properties ?? [];
        $path = $customProperties['path'] ?? null;
        
        if ($path && Storage::disk('public')->exists($path)) {
            return response()->download(
                storage_path("app/public/{$path}"), 
                $customProperties['original_name'] ?? $media->file_name
            );
        }

        flash_error('الملف غير موجود');
        return redirect()->back();
    }

    /**
     * Bulk actions on media
     */
    public function bulkAction(Request $request)
    {
        $request->validate([
            'action' => 'required|in:delete,download',
            'selected' => 'required|array',
            'selected.*' => 'exists:media,id',
        ]);

        $mediaItems = Media::whereIn('id', $request->selected)->get();

        switch ($request->action) {
            case 'delete':
                $count = $mediaItems->count();
                foreach ($mediaItems as $media) {
                    // Delete file from storage
                    $customProperties = $media->custom_properties ?? [];
                    $path = $customProperties['path'] ?? null;
                    
                    if ($path && Storage::disk('public')->exists($path)) {
                        Storage::disk('public')->delete($path);
                    }
                    
                    $media->delete();
                }
                return response()->json([
                    'success' => true,
                    'message' => "تم حذف {$count} ملف بنجاح"
                ]);

            case 'download':
                return response()->json([
                    'success' => true,
                    'message' => 'سيتم تنزيل الملفات قريباً'
                ]);
        }
    }

/**
 * Get media URL with fallback methods
 */
private function getMediaUrl(Media $media)
{
    $customProperties = $media->custom_properties ?? [];
    
    // Method 1: Check custom properties path
    if (isset($customProperties['path']) && Storage::disk('public')->exists($customProperties['path'])) {
        return asset('storage/' . $customProperties['path']);
    }
    
    // Method 2: Try getUrl method if available
    try {
        if (method_exists($media, 'getUrl')) {
            $url = $media->getUrl();
            if ($url && $url !== '') {
                return $url;
            }
        }
    } catch (\Exception $e) {
        // Continue to next method
    }
    
    // Method 3: Try common paths
    $possiblePaths = [
        "media/{$media->getTable()}/{$media->model_id}/{$media->file_name}",
        "media/{$media->id}/{$media->file_name}",
        "media/{$media->file_name}",
        $media->file_name
    ];
    
    foreach ($possiblePaths as $path) {
        if (Storage::disk('public')->exists($path)) {
            return asset('storage/' . $path);
        }
    }
    
    return null;
}

/**
 * Get media details
 */
public function show(Media $media)
{
    $url = $this->getMediaUrl($media);
    
    return response()->json([
        'success' => true,
        'media' => [
            'id' => $media->id,
            'name' => $media->name,
            'file_name' => $media->file_name,
            'mime_type' => $media->mime_type,
            'size' => $this->formatBytes($media->size),
            'collection' => $media->collection_name,
            'url' => $url,
            'created_at' => $media->created_at->format('d/m/Y H:i'),
            'model_type' => $media->model_type ? class_basename($media->model_type) : null,
            'model_id' => $media->model_id,
        ]
    ]);
}

    /**
     * Get models for AJAX
     */
    public function getModelItems(Request $request)
    {
        $request->validate([
            'model_type' => 'required|string'
        ]);

        $modelClass = $request->model_type;
        
        if (!class_exists($modelClass)) {
            return response()->json(['success' => false, 'message' => 'نوع النموذج غير صحيح'], 400);
        }

        $items = $modelClass::select('id')->get()->mapWithKeys(function ($item) {
            if (method_exists($item, 'getName')) {
                $name = $item->getName(1);
            } else {
                $name = $item->name ?? "#{$item->id}";
            }
            return [$item->id => $name];
        });

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

    /**
     * Process and optimize image
     */
    private function processImage($filePath)
    {
        try {
            $image = Image::read($filePath);
            
            // Resize if too large (max 1920px width)
            if ($image->width() > 1920) {
                $image->scale(width: 1920);
            }
            
            // Optimize quality
            $image->encode(quality: 85);
            $image->save($filePath);
            
        } catch (\Exception $e) {
            \Log::warning('Image processing failed: ' . $e->getMessage());
        }
    }

    /**
     * Format bytes to human readable format
     */
    private function formatBytes($bytes, $precision = 2)
    {
        $units = ['B', 'KB', 'MB', 'GB', 'TB'];
        
        for ($i = 0; $bytes > 1024; $i++) {
            $bytes /= 1024;
        }
        
        return round($bytes, $precision) . ' ' . $units[$i];
    }

    /**
     * Get statistics for dashboard
     */
    public function getStats()
    {
        $stats = [
            'total_files' => Media::count(),
            'total_size' => $this->formatBytes(Media::sum('size')),
            'images' => Media::where('mime_type', 'like', 'image/%')->count(),
            'videos' => Media::where('mime_type', 'like', 'video/%')->count(),
            'documents' => Media::where('mime_type', 'like', 'application/%')->count(),
            'recent_uploads' => Media::where('created_at', '>=', now()->subDays(7))->count(),
        ];

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

    /**
     * Clean unused media files
     */
    public function cleanup(Request $request)
    {
        try {
            // Find media with invalid model references
            $orphanedMedia = Media::whereNotNull('model_type')
                ->whereNotNull('model_id')
                ->get()
                ->filter(function ($media) {
                    if (!class_exists($media->model_type)) {
                        return true;
                    }
                    
                    return !$media->model_type::where('id', $media->model_id)->exists();
                });

            $count = $orphanedMedia->count();
            
            if ($request->execute) {
                foreach ($orphanedMedia as $media) {
                    // Delete file from storage
                    $customProperties = $media->custom_properties ?? [];
                    $path = $customProperties['path'] ?? null;
                    
                    if ($path && Storage::disk('public')->exists($path)) {
                        Storage::disk('public')->delete($path);
                    }
                    
                    $media->delete();
                }
                
                return response()->json([
                    'success' => true,
                    'message' => "تم حذف {$count} ملف غير مستخدم"
                ]);
            }

            return response()->json([
                'success' => true,
                'message' => "تم العثور على {$count} ملف غير مستخدم",
                'count' => $count
            ]);

        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'خطأ في تنظيف الملفات: ' . $e->getMessage()
            ], 500);
        }
    }
}