<?php

namespace App\Http\Controllers\Admin;

use App\Helpers\Helper;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Arr;
use App\Media;
use App\Http\Resources\Admin\MediaResource;
use Intervention\Image\Exception\NotReadableException;
use Validator;
use ImageCross;

/**
 * Class MediaController
 *
 * @package App\Http\Controllers
 */
class MediaController extends Controller
{
    const ITEM_PER_PAGE = 20;
    private $_filePath;

    public function __construct()
    {
        $this->_filePath = public_path('uploads/files/');
    }

    public function index(Request $request)
    {
        $searchParams = $request->all();
        $limit = Arr::get($searchParams, 'limit', static::ITEM_PER_PAGE);
        $parentId = Arr::get($searchParams, 'parent_id', 0);
        $fileType = Arr::get($searchParams, 'file_type', '');
        $keyword = Arr::get($searchParams, 'keyword', '');

        $list = Media::notDeleted()->where('parent_id', $parentId);
        if ($fileType != null && $fileType != '' && $fileType == 'image') {
            $fileType = ['image/jpeg', 'image/jpg', 'image/png', 'image/gif', 'image/webp'];
            $list->where(function ($query) use ($fileType) {
                $query->whereNull('file_type')
                    ->orWhere('file_type', '')
                    ->orWhereIn('file_type', $fileType);
            });
        }

        if ($keyword != null && $keyword != "") $list->where('name', 'LIKE', '%' . $keyword . '%');
        $list->orderBy('type')->orderBy('created_at');

        return MediaResource::collection($list->paginate($limit));
    }

    public function show($id = 0)
    {

    }

    public function store(Request $request)
    {
        $validator = Validator::make($request->all(), ['name' => ['required']]);
        if ($validator->fails()) return response()->json(['status' => 'error', 'errors' => $validator->errors(), 'message' => $validator->errors()], 403);
        $params = $request->all();
        $name = trim($params['name']);
        $parentId = trim($params['parent_id']);
        $parentId = ($parentId != null && $parentId != '') ? $parentId : 0;

        if ($parentId != 0 && $parentId != '0') {
            $checkParent = Media::where('is_deleted', 0)->where('type', 0)->where('id', $parentId)->count();
            if ($checkParent <= 0) return response()->json(['status' => 'error', 'message' => 'Parent folder not found.'], 200);
        }

        $checkName = Media::where('is_deleted', 0)->where('type', 0)->where('parent_id', $parentId)->where('name', $name)->count();
        if ($checkName > 0) return response()->json(['status' => 'error', 'message' => 'A folder with that name already exists.'], 200);

        $slug = str_replace(".", "", $name);
        $slug = Helper::slug($slug);
        $slug = str_replace("--", "-", $slug);
        $slug = str_replace("_", "-", $slug);
        $fileName = md5($name . rand(1111, 9999) . rand(1111, 9999) . date('YmdHis'));

        $media = Media::create([
            'name'       => $name,
            'slug'       => $slug,
            'file'       => $fileName,
            'type'       => 0,
            'parent_id'  => $parentId,
            'created_at' => date('Y-m-d H:i:s'),
            'updated_at' => date('Y-m-d H:i:s')
        ]);

        $item = new MediaResource($media);

        return response()->json(['status' => 'success', 'message' => 'Success', 'item' => $item], 200);
    }

    public function update($id = 0, Request $request)
    {

    }

    public function destroy($id = 0)
    {

    }

    public function destroyMultiple(Request $request)
    {

    }

    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');
        $parentId = trim($request->get('parent'));
        $parentId = ($parentId != null && $parentId != '') ? $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 = "223344";
            $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];
            $statusCode = 200;
        } 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];
    }

    private function generateThumb($fileName, $width, $height)
    {
        /*if (file_exists($this->_filePath . $fileName) && !file_exists($this->_filePath . "thumb_{$width}x{$height}/" . $fileName)) {
            $imgCross = ImageCross::make($this->_filePath . $fileName)->orientate();
            $imgCross->fit($width, $height, function ($constraint) {
                $constraint->upsize();
            })->save($this->_filePath . "thumb_{$width}x{$height}/" . $fileName);
        }*/

        if (file_exists($this->_filePath . $fileName)) {
            $imgCross = ImageCross::make($this->_filePath . $fileName)->orientate();
            $imgCross->fit($width, $height, function ($constraint) {
                $constraint->upsize();
            })->save($this->_filePath . "new_" . $fileName);
        }
    }
}
