<?php

namespace App\Http\Controllers;

use App\Events\SaveDataEvent;
use App\Helpers\Helper;
use App\Http\Resources\Admin\MediaResource;
use App\Media;
use Illuminate\Http\Request;
use ImageCross;
use Intervention\Image\Exception\NotReadableException;


/**
 * Class MediaController
 *
 * @package App\Http\Controllers
 */
class MediaController extends Controller
{
    private $_filePath;
    private $_readingMode;

    public function __construct()
    {
        $this->_filePath = public_path('uploads/files/');
        $this->_readingMode = ['image/jpeg', 'image/jpg', 'image/png', 'image/webp', 'image/gif', 'video/mp4'];
    }

    public function file($file = '')
    {
        /*$file = "e4679ac0d2bdb98d9cb849f0b24fb72b_1905x480.jpg";
        $newName = str_replace(".jpg", ".webp", $file);
        $newName = str_replace(".jpeg", ".webp", $newName);
        $newName = str_replace(".gif", ".webp", $newName);
        ImageCross::make($this->_filePath . $file)->encode('webp', 90)->save($this->_filePath . $newName);
        return response()->file($this->_filePath . $newName, ['Content-Type' => 'image/webp']);*/

        $media = Media::where('file', $file)->first();
        if (!isset($media) || $media == null || !file_exists($this->_filePath . $media->file)) {
            header('HTTP/1.0 404 Not Found', true, 404);
            exit();
        }
        if (in_array($media->file_type, $this->_readingMode)) return response()->file($this->_filePath . $media->file, ['Content-Type' => $media->file_type]);

        return response()->download($this->_filePath . $media->file, $media->name, ['Content-Type' => $media->file_type]);
    }

    public function fileThumb($width = 0, $height = 0, $file = '')
    {
        $media = Media::where('file', $file)->first();
        if (!isset($media) || $media == null || !file_exists($this->_filePath . $media->file) || !in_array($media->file_type, $this->_readingMode)) {
            header('HTTP/1.0 404 Not Found', true, 404);
            exit();
        }

        $extKey = "276gaffab";
        $thumbName = str_replace($media->extension . $extKey, "", $media->file . $extKey) . "_" . $width . "x" . $height . $media->extension;
        if (!file_exists($this->_filePath . $thumbName)) {
            $imgCross = ImageCross::make($this->_filePath . $media->file)->orientate();
            if ($width !== 'auto' && $height != 'auto' && is_numeric($width) && is_numeric($height) && $width > 0 && $height > 0) {
                /*if ($media->width >= $media->height) {
                    $imgCross->resize($width, null, function ($constraint) {
                        $constraint->aspectRatio();
                        $constraint->upsize();
                    })->fit($width, $height, function ($constraint) {
                        $constraint->upsize();
                    })->save($this->_filePath . $thumbName);
                } else {
                    $imgCross->resize(null, $height, function ($constraint) {
                        $constraint->aspectRatio();
                        $constraint->upsize();
                    })->fit($width, $height, function ($constraint) {
                        $constraint->upsize();
                    })->save($this->_filePath . $thumbName);
                }*/
                $imgCross->fit($width, $height, function ($constraint) {
                    $constraint->upsize();
                })->save($this->_filePath . $thumbName);
            } else {
                if ($width == 'auto' && $height != 'auto' && is_numeric($height) && $height > 0) {
                    /*$imgCross->resize(null, $height, function ($constraint) {
                        $constraint->aspectRatio();
                        $constraint->upsize();
                    })->save($this->_filePath . $thumbName);*/
                    $imgCross->fit(null, $height, function ($constraint) {
                        $constraint->upsize();
                    })->save($this->_filePath . $thumbName);
                } else if ($height == 'auto' && $width != 'auto' && is_numeric($width) && $width > 0) {
                    /*$imgCross->resize($width, null, function ($constraint) {
                        $constraint->aspectRatio();
                        $constraint->upsize();
                    })->save($this->_filePath . $thumbName);*/
                    $imgCross->fit($width, null, function ($constraint) {
                        $constraint->upsize();
                    })->save($this->_filePath . $thumbName);
                } else {
                    $thumbName = $media->file;
                }
            }

            /*$background = ImageCross::canvas($width, $height);
            $image = ImageCross::make($this->_filePath . $media->file)->resize($width, $width, function ($c) {
                $c->aspectRatio();
                $c->upsize();
            });
            $background->insert($image, 'center');
            $background->save($this->_filePath . $thumbName);*/
            /*$img->resize(200, 200, function ($constraint) {
                $constraint->aspectRatio();
            });
            $img->resizeCanvas(200, 200, 'center', false, array(255, 255, 255, 0));*/
        }

        return response()->file($this->_filePath . $thumbName, ['Content-Type' => $media->file_type]);
    }

    public function download($file = '')
    {
        $media = Media::where('file', $file)->first();
        if (!isset($media) || $media == null || !file_exists($this->_filePath . $media->file)) {
            header('HTTP/1.0 404 Not Found', true, 404);
            exit();
        }

        return response()->download($this->_filePath . $media->file, $media->name, ['Content-Type' => $media->file_type]);
    }

    public function uploadFile(Request $request)
    {
        if (!$request->hasFile('file')) return response()->json(['status' => 'error', 'message' => 'Upload Fail.', 'file_name' => null], 403);
        $file = $request->file('file');
        $itemId = $request->get('itemId');
        $parentId = 0;
        $baseName = $file->getClientOriginalName();
        $imageMimeType = ['image/jpeg', 'image/png', 'image/jpg', 'image/gif', 'image/webp'];
        $data = ['status' => 'error', 'message' => 'Upload Fail.', 'file_name' => null, 'baseName' => $baseName, 'item' => null];
        $statusCode = 403;

        try {
            $extension = $file->getClientOriginalExtension();
            $fileType = $file->getMimeType();
            $fileSize = $this->formatBytes($file->getSize());

            do {
                $fileName = md5($baseName . rand(1111, 9999) . date('YmdHis')) . '.' . $extension;
                $checkFileName = Media::where('is_deleted', 0)->where('file', $fileName)->count();
            } while ($checkFileName > 0);
            $file->move($this->_filePath, $fileName);

            $extKey = "23232322";
            $countBaseName = 0;
            $checkName = Media::where('is_deleted', 0)->where('parent_id', $parentId)->where('name', $baseName)->count();
            $firstBaseName = str_replace("." . $extension . $extKey, "", $baseName . $extKey);
            while ($checkName > 0) {
                $countBaseName += 1;
                $baseName = $firstBaseName . " (" . $countBaseName . ")." . $extension;
                $checkName = Media::where('is_deleted', 0)->where('parent_id', $parentId)->where('name', $baseName)->count();
            }

            $slug = str_replace(")." . $extension . $extKey, "", $baseName . $extKey);
            $slug = str_replace("." . $extension . $extKey, "", $slug);
            $slug = str_replace(".", "", $slug);
            $slug = str_replace("(", "-", $slug);
            $slug = str_replace(")", "", $slug);
            $slug = Helper::slug($slug);
            $slug = str_replace("--", "-", $slug);
            $slug = str_replace("_", "-", $slug);

            $media = Media::create([
                'name'       => $baseName,
                'slug'       => $slug,
                'file'       => $fileName,
                'file_type'  => $fileType,
                'extension'  => "." . $extension,
                'size'       => $fileSize,
                'type'       => 1,
                'parent_id'  => $parentId,
                'created_at' => date('Y-m-d H:i:s'),
                'updated_at' => date('Y-m-d H:i:s')
            ]);
            if (in_array($fileType, $imageMimeType)) {
                try {
                    $imgCross = ImageCross::make($this->_filePath . $fileName)->orientate();
                    $media->update(['width' => $imgCross->width(), 'height' => $imgCross->height()]);
                } catch (NotReadableException $exception) {
                    logger("[Error] Image Cross: " . $exception->getMessage());
                } catch (\Exception $exception) {
                    logger("[Error] Image Cross: " . $exception->getMessage());
                }
            }

            $item = new MediaResource($media);
            $data = ['status' => 'success', 'message' => 'Upload Success.', 'file_name' => $fileName, 'baseName' => $baseName, 'item' => $item, 'itemId' => $itemId];
            $statusCode = 200;

            //event(new SaveDataEvent());
        } catch (\Exception $exception) {
            logger("[Error] Upload file: " . $exception->getMessage());
        } finally {
            return response()->json($data, $statusCode);
        }
    }

    private function formatBytes($bytes, $precision = 2)
    {
        $units = array('B', 'Kb', 'MB', 'GB', 'TB');
        $bytes = max($bytes, 0);
        $pow = floor(($bytes ? log($bytes) : 0) / log(1024));
        $pow = min($pow, count($units) - 1);
        $bytes /= pow(1024, $pow);
        //$bytes /= (1 << (10 * $pow));

        return round($bytes, $precision) . '' . $units[$pow];
    }
}
