<?php

namespace App\Http\Controllers\Admin\Files;

use App\Models\File;
use App\Http\Controllers\Controller;
use App\Http\Requests\Admin\FileUploadRequest;
use App\Models\Setting;
use App\Services\Admin\Files\FilesService;
use Exception;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use Intervention\Image\ImageManager;
use Inertia\Inertia;
use Intervention\Image\Drivers\Gd\Driver;
use Intervention\Image\Encoders\WebpEncoder;
use Intervention\Image\Encoders\GifEncoder;

class FilesController extends Controller
{
    /**
     * Display a listing of the resource.
     */
    public function index(Request $request, FilesService $filesService)
    {
        /** @var \App\Models\User $user */
        $user = auth()->user();

        return Inertia::render('Admin/Files/List', [
            'files' => $filesService->getFiles($request, $user)
        ]);
    }

    /**
     * Show the form for creating a new resource.
     */
    public function create()
    {
        //
    }

    /**
     * Store a newly created resource in storage.
     */
    public function store(FileUploadRequest $request)
    {
        /** @var \App\Models\User $user */
        $user = auth()->user();

        // check folders
        try {
            $this->fixMediaFolders();
        } catch (Exception $e) {
        }

        $errors = [];

        $file = $request->file('file');
        $fileFormat = $file->getClientOriginalExtension();
        $fileType = null;

        switch ($fileFormat) {
            case "jpeg":
            case "jpg":
            case "png":
            case "webp":
            case "gif":
            case "svg":
                $fileType = "image";
                break;
            case "pdf":
                $fileType = "pdf";
                break;
            case "zip":
                $fileType = "zip";
                break;
            case "mp3":
                $fileType = "audio";
                break;
            case "mp4":
                $fileType = "video";
                break;
            default:
                return redirect()->back();
                break;
        }

        $fileName = 'file.' . time() . '.' . rand(10000, 99999) . '.' . $file->getClientOriginalExtension();
        $fileSize = floor($file->getSize() / 1000);
        $fileSaveAddressNoName = 'library/' . date('Y-m-d') . '/' . $user->id;
        $fileSaveAddress = $fileSaveAddressNoName . '/' . $fileName;
        $imageResolution = null;

        if ($fileType == "image") {
            try {
                $imageResolution = getimagesize($file)[0] . '×' . getimagesize($file)[1];
            } catch (Exception $e) {
            }

            $imageTemp = null;

            try {
                $manager = ImageManager::withDriver(new Driver());
                $imageTemp = $manager->read($file->path());
            } catch (Exception $e) {
                $errors[] = __('messages.image_driver_error');
            }

            if ($request->exists('cropImage') && $request->cropImage) {
                try {
                    if ($imageTemp->height() >= $imageTemp->width()) {
                        $imageTemp->cover($imageTemp->width(), $imageTemp->width());
                    } else {
                        $imageTemp->cover($imageTemp->height(), $imageTemp->height());
                    }
                } catch (Exception $e) {
                    $errors[] = __('messages.image_crop_error');
                }
            }

            if ($request->exists('addWatermark') && $request->addWatermark) {
                $watermark = Setting::where('key', 'watermark')->first();
                if ($watermark != null) {
                    $watermark = @unserialize($watermark->value);

                    if (!is_array($watermark) || !isset($watermark['id'], $watermark['url'])) {
                        return redirect()->back()->withErrors([__('messages.watermark_not_found')]);
                    }

                    $file = File::find($watermark['id']);
                    if ($file != null) {
                        $watermark = $watermark['url'];
                    } else {
                        return redirect()->back()->withErrors([__('messages.watermark_not_found')]);
                    }
                    try {
                        if ($imageTemp != null) {
                            $imageTemp->place(
                                public_path($watermark),
                                'bottom-right',
                                30,
                                30,
                                100
                            );
                        }
                    } catch (\Exception $e) {
                        $errors[] = __('messages.watermark_error');
                    }
                } else {
                    return redirect()->back()->withErrors([__('messages.watermark_not_found')]);
                }
            }

            // check temp image
            if ($imageTemp === null) {
                return redirect()->back()->withErrors([__('messages.image_driver_error')]);
            }

            // image variables
            try {
                $finalImageTemp = $imageTemp->encode(new WebpEncoder())->__toString();

                if ($fileFormat == 'gif') {
                    $fileFormat = 'gif';
                    $fileSaveAddressImage = $fileSaveAddressNoName . '/' . 'file.' . time() . '.' . rand(10000, 99999) . '.' . $fileFormat;
                    $finalImageTemp = $imageTemp->encode(new GifEncoder())->__toString();
                } else {
                    $fileFormat = 'webp';
                    $fileSaveAddressImage = $fileSaveAddressNoName . '/' . 'file.' . time() . '.' . rand(10000, 99999) . '.' . $fileFormat;
                    if ($request->exists('optimization') && $request->optimization) {
                        $optimizationPercent = 80;
                        $fileSize = strlen($imageTemp->encode(new WebpEncoder($optimizationPercent))->__toString()) / 1000;
                        $finalImageTemp = $imageTemp->encode(new WebpEncoder($optimizationPercent))->__toString();
                    }
                }
            } catch (\Exception $e) {
                return redirect()->back()->withErrors(['خطا: ' . $e->getMessage()]);
            }


            if ($imageTemp != null) {
                $uploadResult = Storage::disk('media')->put($fileSaveAddressImage, $finalImageTemp, 'public');
                if ($uploadResult) {
                    $user->files()->create([
                        'name' => $fileName,
                        'url' => '/media/' . $fileSaveAddressImage,
                        'description' => $request->exists('description') ? $request->description : null,
                        'extension' => $fileFormat,
                        'size' => $fileSize,
                        'resolution' => $imageResolution,
                        'type' => $fileType,
                    ]);

                    return redirect()->back()->with('message', [__('messages.image_uploaded')])->withErrors($errors);
                } else {
                    return redirect()->back()->withErrors([__('messages.unknown_error')]);
                }
            }
        }

        $uploadResult = '/media/' . $fileSaveAddress;
        Storage::disk('media')->put($fileSaveAddress, file_get_contents($file));

        if ($uploadResult) {
            $user->files()->create([
                'name' => $fileName,
                'url' => $uploadResult,
                'description' => $request->exists('description') ? $request->description : null,
                'extension' => $fileFormat,
                'size' => $fileSize,
                'resolution' => $imageResolution,
                'type' => $fileType,
            ]);

            return redirect()->back()->with('message', [__('messages.file_uploaded')]);
        }

        return redirect()->back()->withErrors([__('messages.unknown_error')]);
    }

    /**
     * Display the specified resource.
     */
    public function show(File $file)
    {
        //
    }

    /**
     * Show the form for editing the specified resource.
     */
    public function edit(File $file)
    {
        //
    }

    /**
     * Update the specified resource in storage.
     */
    public function update(Request $request, File $file)
    {
        $request->validate([
            'description' => 'required'
        ]);


        $file->update([
            'description' => $request->description
        ]);

        return redirect()->back()->with('message', [__('messages.file_updated')]);
    }

    /**
     * Remove the specified resource from storage.
     */
    public function destroy(File $file)
    {
        $user = auth()->user();
        if ($file->user_id == $user->id) {

            $url = $file->url;
            $relativePath = ltrim(str_replace('/media/', '', $url), '/');
            Storage::disk('media')->delete($relativePath);

            $file->delete();

            return redirect()->back()->with('message', [__('messages.file_deleted')]);
        }

        return redirect()->back()->withErrors([__('messages.file_is_not_valid_for_user')]);
    }

    /**
     * fix folders permission
     */
    private function fixMediaFolders()
    {
        $disk = Storage::disk('media');
        $rootPath = $disk->path(''); // مسیر root storage/app/media

        $this->checkFolders($rootPath);
    }

    /**
     * check folders permission
     */
    private function checkFolders($path)
    {
        // فقط پوشه‌ها
        $folders = glob($path . '/*', GLOB_ONLYDIR);

        foreach ($folders as $folder) {
            $perm = substr(sprintf('%o', fileperms($folder)), -3);

            // اگر پرمیشن غیر از 755 بود
            if ($perm !== '755') {
                @chmod($folder, 0755);
            }

            // بررسی پوشه‌های داخل این پوشه به صورت بازگشتی
            $this->checkFolders($folder);
        }
    }
}
