<?php

namespace App\Http\Controllers\Admin;

use App\Events\SaveDataEvent;
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);
		$keyword = Arr::get($searchParams, 'keyword', '');
		
		$list = Media::notDeleted()->where('parent_id', $parentId);
		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);
		event(new SaveDataEvent());
		
		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' => 'File type not allowed.', 'file_name' => null], 403);
		$file = $request->file('file');
		$parent = trim($request->get('parent'));
		if (($parent == null || $parent == "" || $parent == "null") && $request->has("folder") && $request->get("folder") != null && $request->get("folder") != "" && $request->get("folder") != "null") {
			$folder = Media::where('is_deleted', false)
				->where('type', 0)
				->where('name', trim($request->get("folder")))
				->where('parent_id', 0)
				->first();
			if (!isset($folder) || $folder == null) {
				$folder = Media::create([
					'name'       => trim($request->get("folder")),
					'slug'       => Helper::slug($request->get("folder")),
					'file'       => md5(rand(1000, 100000) . $request->get("folder") . date("YmdHis")),
					'type'       => 0,
					'parent_id'  => 0,
					'created_at' => date('Y-m-d H:i:s'),
					'updated_at' => date('Y-m-d H:i:s')
				]);
			}
			$parent = $folder->id;
		}
		$parentId = ($parent != null && $parent != '' && $parent != 'null' && !empty($parent)) ? $parent : 0;
		$baseName = $file->getClientOriginalName();
		$imageMimeType = [
			'image/jpeg',
			'image/jpg',
			'image/png',
			'image/gif',
			'image/webp',
			'application/pdf',
			'application/msword',
			'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
			'application/vnd.ms-excel',
			'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
			'application/vnd.ms-powerpoint',
			'application/vnd.openxmlformats-officedocument.presentationml.presentation',
			'text/plain'
		];
		
		try {
			$fileType = $file->getMimeType();
			$extension = $file->getClientOriginalExtension();
			$fileSize = $this->formatBytes($file->getSize());
			
			if (!in_array($fileType, $imageMimeType)) {
				return response()->json(['status' => 'error', 'message' => 'File type not allowed.', 'file_name' => null, 'baseName' => $baseName, 'item' => null], 403);
			}
			
			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);
			
			$media = Media::create([
				'name'       => $baseName,
				'slug'       => Helper::slug(str_replace("." . $extension, "", $baseName)),
				'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')
			]);
			
			$item = new MediaResource($media);
			
			return response()->json([
				'status'    => 'success',
				'message'   => 'Upload Success.',
				'file_name' => $fileName,
				'baseName'  => $baseName,
				'item'      => $item
			], 200);
		} catch (\Exception $exception) {
			logger("[Error] Upload file: " . $exception->getMessage());
			return response()->json(['status' => 'error', 'message' => 'Upload failed.', 'file_name' => null, 'baseName' => $baseName, 'item' => null], 403);
		}
	}
	
	private function formatBytes($bytes, $precision = 2)
	{
		$units = ['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);
		}
	}
}
