<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Http\Resources\Admin\AreaResourceList;
use Illuminate\Http\Request;
use Illuminate\Support\Arr;
use App\Area;
use App\Seo;
use App\Http\Resources\Admin\AreaResource;
use App\Helpers\Helper;
use Validator;

/**
 * Class AreaController
 *
 * @package App\Http\Controllers
 */
class AreaController extends Controller
{
    const ITEM_PER_PAGE = 20;
    private $_imagePath;
    private $_startOrder = 0;

    public function __construct()
    {
        $this->_imagePath = public_path('uploads/image/area/');
    }

    public function index(Request $request)
    {
        $searchParams = $request->all();
        $list = Area::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('order')->orderBy('id');

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

    public function list(Request $request)
    {
        $searchParams = $request->all();
        $list = Area::select('id', 'name')->notDeleted()->orderBy('order')->orderBy('id');
        $limit = Arr::get($searchParams, 'limit', static::ITEM_PER_PAGE);

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

    public function all()
    {
        $list = Area::select('id', 'name', 'slug', 'description', 'logo', 'show_top', 'show_search')->where('is_deleted', false)->orderBy('order')->orderBy('id');

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

    public function allNested(Request $request)
    {
        $searchParams = $request->all();
        $ignoreId = Arr::get($searchParams, 'id', '');
        $list = Area::select('id', 'name as label', 'slug', 'parent_id')->where('is_deleted', false);
        if (!empty($ignoreId)) {
            $list->where('id', '!=', $ignoreId);
        }
        $list->orderBy('order')->orderBy('id');
        $rs = $this->getChildItems($list->get(), 0);

        return response()->json(['data' => $rs], 200);
    }

    public function listNested(Request $request)
    {
        $searchParams = $request->all();
        $keyword = Arr::get($searchParams, 'keyword', '');
        $status = Arr::get($searchParams, 'status', '');
        if ($keyword != '' || $status != '') {
            $list = Area::select('id', 'name', 'slug', 'description', 'show_top', 'show_search', 'parent_id', 'is_activated')->where('is_deleted', false);
            if ($keyword != "") {
                $list = $list->where(function ($query) use ($keyword) {
                    $query->where('name', 'LIKE', '%' . $keyword . '%')
                        ->orWhere('slug', 'LIKE', '%' . $keyword . '%');
                });
            }
            if ($status != "") {
                $list = $list->where('is_activated', $status);
            }
            $rs = $list->orderBy('order')->orderBy('id')->get();
        } else {
            $listAll = Area::select('id', 'name', 'slug', 'description', 'show_top', 'show_search', 'parent_id', 'is_activated')->where('is_deleted', false)->orderBy('order')->orderBy('id')->get();
            $rs = $this->getChildItems($listAll, 0);
        }

        return response()->json(['data' => $rs], 200);
    }

    public function getChildItems($list, $parent = 0)
    {
        $rs = [];
        foreach ($list as $item) {
            if ($item->parent_id == $parent) {
                $childItems = $this->getChildItems($list, $item->id);
                if (count($childItems) > 0) $item['children'] = $childItems;
                $rs[] = $item;
            }
        }

        return $rs;
    }

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

        return new AreaResource($area);
    }

    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();
        $countAll = 0;
        $lastItem = Area::where('is_deleted', false)->orderBy('order', 'DESC')->first();
        if (isset($lastItem)) $countAll = $lastItem->order + 1;
        $parentId = (isset($params['parent_id']) && !empty($params['parent_id'])) ? $params['parent_id'] : 0;
        $area = Area::create([
            'name'         => $params['name'],
            'slug'         => Helper::slug($params['slug']),
            'description'  => $params['description'],
            'logo'         => $params['logo'],
            'title'        => $params['title'],
            'sub_title'    => $params['sub_title'],
            'link'         => $params['link'],
            'order'        => $countAll,
            'parent_id'    => $parentId,
            'show_top'     => ($params['show_top'] === true) ? 1 : 0,
            'show_search'  => ($params['show_search'] === true) ? 1 : 0,
            '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')
        ]);
        if ($params['logo'] != "" && $params['logo'] != null) Helper::createThumbFit($this->_imagePath . $params['logo'], $this->_imagePath, 70, 70);

        $seoTitle = "『" . $params['name'] . "』の当たると口コミで評判のオススメの占い師｜占いの森 / URAMORI";
        $seoDesc = "『" . $params['name'] . "』の的中率の高い・当たると評判のオススメ占い師を口コミ評価レビュー、占い料金、性別、得意な占術・相談お悩み内容などで検索し探せます。";
        $uri = "/area/" . $area->slug;
        if ($parentId != 0 && $parentId != "0") {
            $parent = Area::where('id', $parentId)->first();
            if (isset($parent)) {
                $uri = "/area/" . $parent->slug . "/" . $area->slug;
            }
        }
        $checkSeo = Seo::where('uri', $uri)->first();
        if (isset($checkSeo) && $checkSeo->id != null) {
            $checkSeo->update([
                'title'       => $seoTitle,
                'description' => $seoDesc,
                'updated_at'  => date('Y-m-d H:i:s'),
            ]);
        } else {
            Seo::create([
                'uri'         => $uri,
                'title'       => $seoTitle,
                'description' => $seoDesc,
                'type'        => 'area',
                'created_at'  => date('Y-m-d H:i:s'),
                'updated_at'  => date('Y-m-d H:i:s'),
            ]);
        }

        return new AreaResource($area);
    }

    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);
        $area = Area::notDeleted()->where('id', $id)->first();
        if (!isset($area)) return response()->json(['errors' => 'Area is not valid'], 403);
        $oldSlug = $area->slug;
        $oldParentId = $area->parent_id;
        $params = $request->all();
        if ($params['logo'] != "" && $params['logo'] != null && $area->logo != $params['logo']) Helper::createThumbFit($this->_imagePath . $params['logo'], $this->_imagePath, 70, 70);
        $parentId = (isset($params['parent_id']) && !empty($params['parent_id'])) ? $params['parent_id'] : 0;

        $area->update([
            'name'         => $params['name'],
            'slug'         => Helper::slug($params['slug']),
            'description'  => $params['description'],
            'logo'         => $params['logo'],
            'title'        => $params['title'],
            'sub_title'    => $params['sub_title'],
            'link'         => $params['link'],
            'parent_id'    => $parentId,
            'show_top'     => ($params['show_top'] === true) ? 1 : 0,
            'show_search'  => ($params['show_search'] === true) ? 1 : 0,
            'is_activated' => ($params['is_activated'] === true) ? 1 : 0,
            'updated_at'   => date('Y-m-d H:i:s')
        ]);

        $seoTitle = "『" . $params['name'] . "』の当たると口コミで評判のオススメの占い師｜占いの森 / URAMORI";
        $seoDesc = "『" . $params['name'] . "』の的中率の高い・当たると評判のオススメ占い師を口コミ評価レビュー、占い料金、性別、得意な占術・相談お悩み内容などで検索し探せます。";

        $oldUri = "/area/" . $oldSlug;
        if ($oldParentId != 0 && $oldParentId != "0") {
            $oldParent = Area::where('id', $oldParentId)->first();
            if (isset($oldParent)) {
                $oldUri = "/area/" . $oldParent->slug . "/" . $oldSlug;
            }
        }

        $newUri = "/area/" . $area->slug;
        if ($parentId != 0 && $parentId != "0") {
            $parent = Area::where('id', $parentId)->first();
            if (isset($parent)) {
                $newUri = "/area/" . $parent->slug . "/" . $area->slug;
            }
        }

        $checkSeo = Seo::where('uri', $oldUri)->first();
        if (isset($checkSeo) && $checkSeo->id != null) {
            $checkSeo->update([
                'uri'         => $newUri,
                'title'       => $seoTitle,
                'description' => $seoDesc,
                'type'        => 'area',
                'updated_at'  => date('Y-m-d H:i:s'),
            ]);
        } else {
            $checkSeo = Seo::where('uri', $newUri)->first();
            if (isset($checkSeo) && $checkSeo->id != null) {
                $checkSeo->update([
                    'title'       => $seoTitle,
                    'description' => $seoDesc,
                    'updated_at'  => date('Y-m-d H:i:s'),
                ]);
            } else {
                Seo::create([
                    'uri'         => $newUri,
                    'title'       => $seoTitle,
                    'description' => $seoDesc,
                    'type'        => 'area',
                    'created_at'  => date('Y-m-d H:i:s'),
                    'updated_at'  => date('Y-m-d H:i:s'),
                ]);
            }
        }

        $newArea = Area::with('parent')->notDeleted()->where('id', $id)->first();

        return response()->json($newArea, 200);
    }

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

        try {
            $area->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', []);
        $areaList = Area::notDeleted()->whereIn('id', $listIds)->get();
        if ($areaList->count() <= 0) response()->json(['error' => 'Area is not valid.'], 403);
        try {
            Area::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', []);
        $areaList = Area::notDeleted()->whereIn('id', $listIds)->get();
        if ($areaList->count() <= 0) response()->json(['error' => 'Area is not valid.'], 403);
        try {
            Area::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', []);
        $areaList = Area::notDeleted()->whereIn('id', $listIds)->get();
        if ($areaList->count() <= 0) response()->json(['error' => 'Area is not valid.'], 403);
        try {
            Area::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')) {
            $file = $request->file('image');
            $baseName = $file->getClientOriginalName();
            $fileName = md5($baseName . rand(1111, 9999) . date('YmdHis')) . '.' . $file->getClientOriginalExtension();
            $file->move($this->_imagePath, $fileName);
            return response()->json(['status' => 'success', 'message' => 'Upload Success.', 'file_name' => $fileName, 'baseName' => $baseName], 200);
        }

        return response()->json(['status' => 'error', 'message' => 'Upload Fail.', 'file_name' => null], 403);
    }

    public function setTop($id = 0)
    {
        $area = Area::where('id', $id)->where('is_deleted', false)->first();
        if (isset($area)) {
            $setStatus = ($area->show_top == 0) ? 1 : 0;
            $area->update(['show_top' => $setStatus]);
        }
        return response()->json(null, 204);
    }

    public function position(Request $request)
    {
        if (!$request->has('position')) return response()->json(['errors' => 'Data is invalid'], 403);
        $newList = $request->position;
        if (isset($newList) && is_array($newList)) $this->updateAreaItem($newList, 0);

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

    private function updateAreaItem($items = [], $parentId = 0)
    {
        foreach ($items as $item) {
            $this->_startOrder += 1;
            Area::where('id', $item['id'])->update([
                'parent_id'  => $parentId,
                'order'      => $this->_startOrder,
                'updated_at' => date('Y-m-d H:i:s')
            ]);
            $this->updateAreaItem($item['elements'], $item['id']);
        }
    }
}
