<?php

namespace App\Http\Controllers\Admin;

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

/**
 * Class SliderController
 *
 * @package App\Http\Controllers
 */
class SliderController extends Controller
{
    const ITEM_PER_PAGE = 100;
    private $_pathFile;
    private $_pathTemp;
    private $_imageTellerPath;

    public function __construct()
    {
        $this->_pathFile = public_path('uploads/image/slider/');
        $this->_imageTellerPath = public_path('uploads/image/fortune/');
        $this->_pathTemp = storage_path('app/public/uploads/temp/image/');
    }

    public function index(Request $request)
    {
        $searchParams = $request->all();
        $list = Slider::notDeleted();
        $limit = Arr::get($searchParams, 'limit', static::ITEM_PER_PAGE);
        $keyword = Arr::get($searchParams, 'keyword', '');
        $status = Arr::get($searchParams, 'status', '');

        if (!empty($keyword)) {
            $list->where('name', 'LIKE', '%' . $keyword . '%');
        }
        if ($status != '') {
            $list->where('is_activated', $status);
        }
        $list->orderBy('id');

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

    public function all()
    {
        $list = Slider::select('id', 'name', 'slug')->notDeleted()->orderBy('id');

        return SliderResource::collection($list->get());
    }

    public function show($id = 0)
    {
        $slider = Slider::with('details')->notDeleted()->where('id', $id)->first();
        if (!isset($slider)) return response()->json(['errors' => 'Slider is not valid'], 403);

        return new SliderResource($slider);
    }

    public function store(Request $request)
    {
        $validator = Validator::make($request->all(), ['name' => ['required'], 'is_activated' => ['required']]);
        if ($validator->fails()) return response()->json(['errors' => $validator->errors()], 403);
        $params = $request->all();
        $slider = Slider::create([
            'name'           => $params['name'],
            'slug'           => Helper::slug($params['name']),
            'position'       => $params['position'],
            'autoplay'       => $params['autoplay'],
            'autoplaySpeed'  => $params['autoplaySpeed'],
            'speed'          => $params['speed'],
            'slidesToShow'   => $params['slidesToShow'],
            'slidesToScroll' => $params['slidesToScroll'],
            'infinite'       => $params['infinite'],
            'fade'           => $params['fade'],
            'dots'           => $params['dots'],
            'arrows'         => $params['arrows'],
            'pauseOnHover'   => $params['pauseOnHover'],
            'pauseOnFocus'   => $params['pauseOnFocus'],
            'is_activated'   => ($params['is_activated'] === true) ? 1 : 0,
            'created_at'     => date('Y-m-d H:i:s'),
            'updated_at'     => date('Y-m-d H:i:s')
        ]);

        $items = $params['details'];
        SliderDetail::where('slider_id', $slider->id)->delete();
        if (is_array($items) && count($items) > 0) {
            $insertData = [];
            foreach ($items as $item) {
                $fileName = $this->generateImage($item['status'], $item['file_name'], $item['url']);
                $arrUrl = $this->detectLinkType($item['link']);
                $insertData[] = [
                    'slider_id'       => $slider->id,
                    'name'            => $item['name'],
                    'title'           => $item['title'],
                    'description'     => $item['description'],
                    'is_line'         => ($item['is_line'] == true || $item['is_line'] == "true") ? 1 : 0,
                    'image'           => $fileName,
                    'origin_image'    => $fileName,
                    'link'            => $arrUrl['link'],
                    'type_link'       => $arrUrl['type'],
                    'color'           => $item['color'],
                    'stroke'          => $item['stroke'],
                    'border'          => $item['border'],
                    'overlay_size'    => $item['overlay_size'],
                    'overlay_opacity' => $item['overlay_opacity'],
                    'overlay_color'   => $item['overlay_color'],
                    'is_shadow'       => ($item['is_shadow'] == true || $item['is_shadow'] == "true") ? 1 : 0,
                    'is_blur'         => ($item['is_blur'] == true || $item['is_blur'] == "true") ? 1 : 0,
                    'created_at'      => date('Y-m-d H:i:s'),
                    'updated_at'      => date('Y-m-d H:i:s'),
                ];
            }
            if (count($insertData) > 0) SliderDetail::insert($insertData);
        }

        return new SliderResource($slider);
    }

    public function update($id = 0, Request $request)
    {
        $validator = Validator::make($request->all(), ['name' => ['required'], 'is_activated' => ['required']]);
        if ($validator->fails()) return response()->json(['errors' => $validator->errors()], 403);
        $slider = Slider::notDeleted()->where('id', $id)->first();
        if (!isset($slider)) return response()->json(['errors' => 'Slider is not valid'], 403);
        $params = $request->all();
        $slider->update([
            'name'           => $params['name'],
            'slug'           => Helper::slug($params['name']),
            'position'       => $params['position'],
            'autoplay'       => $params['autoplay'],
            'autoplaySpeed'  => $params['autoplaySpeed'],
            'speed'          => $params['speed'],
            'slidesToShow'   => $params['slidesToShow'],
            'slidesToScroll' => $params['slidesToScroll'],
            'infinite'       => $params['infinite'],
            'fade'           => $params['fade'],
            'dots'           => $params['dots'],
            'arrows'         => $params['arrows'],
            'pauseOnHover'   => $params['pauseOnHover'],
            'pauseOnFocus'   => $params['pauseOnFocus'],
            'is_activated'   => ($params['is_activated'] === true) ? 1 : 0,
            'updated_at'     => date('Y-m-d H:i:s')
        ]);

        $items = $params['details'];
        SliderDetail::where('slider_id', $slider->id)->delete();
        if (is_array($items) && count($items) > 0) {
            $insertData = [];
            foreach ($items as $item) {
                $fileName = $this->generateImage($item['status'], $item['file_name'], $item['url']);
                $arrUrl = $this->detectLinkType($item['link']);
                $insertData[] = [
                    'slider_id'       => $slider->id,
                    'name'            => $item['name'],
                    'title'           => $item['title'],
                    'description'     => $item['description'],
                    'is_line'         => ($item['is_line'] == true || $item['is_line'] == "true") ? 1 : 0,
                    'image'           => $fileName,
                    'origin_image'    => $fileName,
                    'link'            => $arrUrl['link'],
                    'type_link'       => $arrUrl['type'],
                    'color'           => $item['color'],
                    'stroke'          => $item['stroke'],
                    'border'          => $item['border'],
                    'overlay_size'    => $item['overlay_size'],
                    'overlay_opacity' => $item['overlay_opacity'],
                    'overlay_color'   => $item['overlay_color'],
                    'is_shadow'       => ($item['is_shadow'] == true || $item['is_shadow'] == "true") ? 1 : 0,
                    'is_blur'         => ($item['is_blur'] == true || $item['is_blur'] == "true") ? 1 : 0,
                    'created_at'      => date('Y-m-d H:i:s'),
                    'updated_at'      => date('Y-m-d H:i:s'),
                ];
            }
            if (count($insertData) > 0) SliderDetail::insert($insertData);
        }

        return response()->json(null, 204);
    }

    public function destroy($id = 0)
    {
        $slider = Slider::notDeleted()->where('id', $id)->first();
        if (!isset($slider)) response()->json(['error' => 'Ehhh! Can not delete this category'], 403);

        try {
            $slider->update(['is_deleted' => true]);
        } catch (\Exception $ex) {
            response()->json(['error' => $ex->getMessage()], 403);
        }

        return response()->json(null, 204);
    }

    public function destroyMultiple(Request $request)
    {
        $validator = Validator::make($request->all(), ['ids' => 'required']);
        if ($validator->fails()) return response()->json(['errors' => $validator->errors()], 403);
        $listIds = $request->get('ids', []);
        $sliderList = Slider::notDeleted()->whereIn('id', $listIds)->get();
        if ($sliderList->count() <= 0) response()->json(['error' => 'Slider is not valid.'], 403);
        try {
            Slider::notDeleted()->whereIn('id', $listIds)->update(['is_deleted' => true]);
        } catch (\Exception $ex) {
            response()->json(['error' => $ex->getMessage()], 403);
        }

        return response()->json(null, 204);
    }

    public function activateMultiple(Request $request)
    {
        $validator = Validator::make($request->all(), ['ids' => 'required']);
        if ($validator->fails()) return response()->json(['errors' => $validator->errors()], 403);
        $listIds = $request->get('ids', []);
        $sliderList = Slider::notDeleted()->whereIn('id', $listIds)->get();
        if ($sliderList->count() <= 0) response()->json(['error' => 'Slider is not valid.'], 403);
        try {
            Slider::notDeleted()->whereIn('id', $listIds)->update(['is_activated' => true]);
        } catch (\Exception $ex) {
            response()->json(['error' => $ex->getMessage()], 403);
        }

        return response()->json(null, 204);
    }

    public function deactivateMultiple(Request $request)
    {
        $validator = Validator::make($request->all(), ['ids' => 'required']);
        if ($validator->fails()) return response()->json(['errors' => $validator->errors()], 403);
        $listIds = $request->get('ids', []);
        $sliderList = Slider::notDeleted()->whereIn('id', $listIds)->get();
        if ($sliderList->count() <= 0) response()->json(['error' => 'Slider is not valid.'], 403);
        try {
            Slider::notDeleted()->whereIn('id', $listIds)->update(['is_activated' => false]);
        } catch (\Exception $ex) {
            response()->json(['error' => $ex->getMessage()], 403);
        }

        return response()->json(null, 204);
    }

    public function uploadImage(Request $request)
    {
        if (!$request->hasFile('image')) return response()->json(['status' => 'error', 'message' => 'Upload Fail.', 'file_name' => null], 403);
        $file = $request->file('image');
        $baseName = $file->getClientOriginalName();

        try {
            $fileName = md5($baseName . rand(1111, 9999) . date('YmdHis')) . '.' . $file->getClientOriginalExtension();
            $file->move($this->_pathFile, $fileName);
            //chmod($this->_pathFile . $fileName, 0777);
            return response()->json(['status' => 'success', 'message' => 'Upload Success.', 'file_name' => $fileName, 'baseName' => $baseName], 200);
        } catch (\Exception $exception) {
            logger("[Error] Upload file: " . $exception->getMessage());
            return response()->json(['status' => 'error', 'message' => 'Upload Fail.', 'file_name' => null, 'baseName' => $baseName], 403);
        }
    }

    private function generateImage($itemStatus, $fileName, $itemUrlContent) {
        try {
            if ($itemStatus != null && $itemStatus != "" && ($itemStatus == "edited" || $itemStatus == "choice")) {
                if ($itemStatus == "edited") {
                    $fileName = md5(date('YmdHis') . rand(1, 9999)) . '.jpg';
                    ImageCross::make($itemUrlContent)->orientate()->save($this->_pathFile . $fileName);
                } else {
                    ImageCross::make($this->_imageTellerPath . $fileName)->orientate()->save($this->_pathFile . $fileName);
                }
            }
            $this->generateThumb($fileName, 90, 50);
            $this->generateThumb($fileName, 172, 108);
            $this->generateThumb($fileName, 170, 230);
            $this->generateThumb($fileName, 325, 202);
        } catch (NotReadableException $exception) {
            logger("[Error] Image Cross: " . $exception->getMessage());
        } catch (\Exception $exception) {
            logger("[Error] Image Cross: " . $exception->getMessage());
        } finally {
            return $fileName;
        }
    }

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

    private function detectLinkType($link) {
        $type = 0;
        if ($link != "" && strpos($link, "https://") === false && strpos($link, "http://") === false) {
            $link = "/" . $link;
            $link = str_replace("//", "/", $link);
            $type = 1;
        }

        return ['link' => $link, 'type' => $type];
    }
}
