<?php

namespace App\Http\Controllers\Admin;

ini_set('post_max_size','1024M');
ini_set('upload_max_filesize','1024M');
use App\Http\Controllers\Controller;
use App\Models\DeliveryMan;
use Illuminate\Http\Request;
use Illuminate\Http\File;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;
use App\CentralLogics\FileManagerLogic;
use Brian2694\Toastr\Facades\Toastr;
use Madnest\Madzipper\Facades\Madzipper;

class FileManagerController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index($folder_path = "cHVibGlj")
    {
        $file = Storage::files(base64_decode($folder_path));
        $directories = Storage::directories(base64_decode($folder_path));

        $folders = FileManagerLogic::format_file_and_folders($directories, 'folder');
        $files = FileManagerLogic::format_file_and_folders($file, 'file');
        // dd($files);
        $data = array_merge($folders, $files);
        return view('admin-views.file-manager.index', compact('data', 'folder_path'));
    }


    public function upload(Request $request)
    {
        $request->validate([
            'images' => 'required_without:file',
            'file' => 'required_without:images',
            'path' => 'required',
          ]);
        if ($request->hasfile('images')) {
            $images = $request->file('images');

            foreach($images as $image) {
                $name = $image->getClientOriginalName();
                Storage::disk('local')->put($request->path.'/'. $name, file_get_contents($image));
            }
        }
        if ($request->hasfile('file')) {
            $file = $request->file('file');
            $name = $file->getClientOriginalName();

            Madzipper::make($file)->extractTo('storage/app/'.$request->path);
            // Storage::disk('local')->put($request->path.'/'. $name, file_get_contents($file));

        }
        Toastr::success(translate('messages.image_uploaded_successfully'));
        return back()->with('success', translate('messages.image_uploaded_successfully'));
    }




    public function download($file_name)
    {
        return Storage::download(base64_decode($file_name));
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function edit($id)
    {
        //
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, $id)
    {
        //
    }


    public function destroy($file_path)
    {
        Storage::disk('local')->delete(base64_decode($file_path));
        Toastr::success(translate('messages.image_deleted_successfully'));
        return back()->with('success', translate('messages.image_deleted_successfully'));
    }


    public function deleteImages(Request $request)
    {
        $type = $request->input('type');

        $map = [
            'delivery_men_pending_requests' => ['pending'],
            'delivery_men_denied_requests' => ['denied'],
        ];

        if ($type === 'delivery_men_cleanup_unused') {
            return $this->cleanupUnusedDeliveryManImages();
        }

        if (! isset($map[$type])) {
            return back()->with('error', 'نوع العملية غير معروف.');
        }

        $statuses = $map[$type];

        $deletedFilesCount = 0;
        $updatedRecordsCount = 0;
        $errors = [];

        DeliveryMan::whereIn('application_status', $statuses)
            ->where('application_status', '!=', 'approved')
            ->chunkById(100, function ($deliveryMen) use (&$deletedFilesCount, &$updatedRecordsCount, &$errors) {
                foreach ($deliveryMen as $dm) {
                    try {
                        if (!empty($dm->image)) {
                            $basename = $this->extractBasename($dm->image);
                            if ($basename) {
                                $path = 'delivery-man/' . $basename;
                                if (Storage::disk('public')->exists($path)) {
                                    if (Storage::disk('public')->delete($path)) {
                                        $deletedFilesCount++;
                                    }
                                }
                            }
                        }

                        if (!empty($dm->identity_image)) {
                            $imgs = json_decode($dm->identity_image, true);
                            if (!is_array($imgs)) {
                                if (is_string($dm->identity_image)) {
                                    $raw = trim($dm->identity_image);
                                    $raw = trim($raw, "[] \t\n\r\0\x0B\"");
                                    $imgs = $raw === '' ? [] : preg_split('/\s*,\s*/', $raw);
                                } else {
                                    $imgs = [];
                                }
                            }

                            foreach ($imgs as $img) {
                                if (empty($img)) continue;
                                $basename = $this->extractBasename($img);
                                if ($basename) {
                                    $path = 'delivery-man/' . $basename;
                                    if (Storage::disk('public')->exists($path)) {
                                        if (Storage::disk('public')->delete($path)) {
                                            $deletedFilesCount++;
                                        }
                                    }
                                }
                            }
                        }

                        //$dm->image = null;
                        //$dm->identity_image = null;
                        //$dm->save();

                        $updatedRecordsCount++;
                    } catch (\Throwable $e) {
                        Log::error('deleteImages error for DeliveryMan id=' . $dm->id . ': ' . $e->getMessage());
                        $errors[] = "id={$dm->id}: " . $e->getMessage();
                    }
                }
            });

        $message = "انتهت العملية. تم حذف {$deletedFilesCount} ملف/ملفات وتحديث {$updatedRecordsCount} سجل/سجلات.";
        Toastr::success($message);
        if (!empty($errors)) {
            $message .= " حدثت بعض الأخطاء (انظر اللوغ).";
            Toastr::error($message);
        }
        return back();
    }
    private function extractBasename($fileOrUrl)
    {
        if (empty($fileOrUrl)) return null;

        if (is_array($fileOrUrl) || is_object($fileOrUrl)) return null;

        $fileOrUrl = trim($fileOrUrl, "\"' ");

        $basename = basename($fileOrUrl);

        if (strpos($basename, '.') === false) return null;

        $basename = preg_replace('/[^A-Za-z0-9_\-\.]/', '', $basename);

        return $basename;
    }
    private function cleanupUnusedDeliveryManImages()
    {
        $disk = Storage::disk('public');
        $folder = 'delivery-man';

        $allFiles = $disk->files($folder);

        $referenced = [];

        DeliveryMan::select('id', 'image', 'identity_image')->chunkById(500, function ($deliveryMen) use (&$referenced) {
            foreach ($deliveryMen as $dm) {
                if (!empty($dm->image)) {
                    $b = $this->extractBasename($dm->image);
                    if ($b) $referenced[$b] = true;
                }

                if (!empty($dm->identity_image)) {
                    $imgs = $this->normalizeImageList($dm->identity_image);
                    foreach ($imgs as $img) {
                        $b = $this->extractBasename($img);
                        if ($b) $referenced[$b] = true;
                    }
                }
            }
        });

        $toDelete = [];
        foreach ($allFiles as $filePath) {
            $basename = basename($filePath);
            if (!isset($referenced[$basename])) {
                $toDelete[] = $filePath;
            }
        }

        $deleted = 0;
        $errors = [];
        foreach ($toDelete as $file) {
            try {
                if ($disk->exists($file)) {
                    if ($disk->delete($file)) {
                        $deleted++;
                    }
                }
            } catch (\Throwable $e) {
                Log::error("cleanupUnusedDeliveryManImages: error deleting {$file}: " . $e->getMessage());
                $errors[] = "{$file}: " . $e->getMessage();
            }
        }

        $message = "تنظيف المجلد انتهى. تم حذف {$deleted} ملف/ملفات غير مستخدمة من '{$folder}'.";
        if (!empty($errors)) {
            $message .= " بعض الأخطاء حدثت (راجع اللوغ).";
        }

        Toastr::success($message);
        return back();
    }

    /**
     * يعيد مصفوفة من أسماء الصور من حقل identity_image سواء كان مخزن كـ JSON أو كـ سلسلة.
     */
    private function normalizeImageList($identityField)
    {
        // إن كان JSON array
        $imgs = json_decode($identityField, true);
        if (is_array($imgs)) {
            return array_values($imgs);
        }

        // إن كان سلسلة محتوية على صيغة ["a.jpg","b.jpg"] أو "a.jpg,b.jpg"
        if (is_string($identityField)) {
            $raw = trim($identityField);
            // إزالة أقواس ومزدوجات إن وُجدت
            $raw = trim($raw, "[] \t\n\r\0\x0B\"");
            if ($raw === '') return [];
            // إذا كانت تحتوي على '","' فافصل على ذلك
            if (strpos($raw, '","') !== false) {
                $parts = preg_split('/"\s*,\s*"/', $raw);
            } else {
                $parts = preg_split('/\s*,\s*/', $raw);
            }
            return array_map(function($p){ return trim($p, "\"' "); }, $parts);
        }

        return [];
    }
}
