<?php

namespace App\Http\Controllers\Admin;

use App\CsvFile;
use App\CsvFileConfig;
use App\CsvFileDetail;
use App\Events\TellerProcessed;
use App\Http\Controllers\Controller;
use App\Http\Resources\Admin\CsvResource;
use App\Http\Resources\Admin\ShopCsvResource;
use App\Http\Resources\Admin\ShopResourceSelectOnly;
use App\Indexer\ShopIndex;
use App\Keyword;
use App\KeywordDetail;
use App\RuleCustom;
use App\Seo;
use App\ShopCsvLog;
use App\ShopInfo;
use App\ShopReview;
use App\ShopSlider;
use App\Laravue\Models\User;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Arr;
use App\Shop;
use App\Area;
use App\ShopMeta;
use App\Http\Resources\Admin\ShopResource;
use App\Http\Resources\Admin\ShopResourceMeta;
use App\Http\Resources\Admin\ShopResourceSelect;
use App\Helpers\Helper;
use Illuminate\Support\Facades\Log;
use Validator;
use ImageCross;

/**
 * Class ShopController
 *
 * @package App\Http\Controllers
 */
class ShopController extends Controller
{
    const ITEM_PER_PAGE = 20;
    private $_imagePath;
    private $_csvPath;
    private $_limitedItems;

    public function __construct()
    {
        $this->_imagePath = public_path('uploads/image/shop/');
        $this->_csvPath = storage_path('app/public/uploads/temp/csv/');

        $this->_limitedItems = ['hasLimited' => false, 'data' => []];
        $user = auth('api')->user();
        if ($user != null && !$user->hasRole('admin') && !$user->hasRole('manager') && !$user->hasPermissionTo('manage-shop') && $user->hasPermissionTo('manage-shop-custom')) {
            $this->_limitedItems['hasLimited'] = true;
            $permissions = $user->getAllPermissions();
            $pId = 0;
            $rId = 0;
            foreach ($permissions as $permission) {
                if ($permission->name == "manage-shop-custom") {
                    $pId = $permission->id;
                    $rId = $permission->pivot->role_id;
                    break;
                }
            }

            if ($pId > 0 && $rId > 0) {
                $rules = RuleCustom::where('role_id', $rId)->where('permission_id', $pId)->get();
                if ($rules->count() > 0) {
                    $shopLimited = Shop::select('id')->where('is_deleted', false);
                    foreach ($rules as $rule) {
                        $conditionVal = trim($rule->condition_value);
                        if ($rule->condition_name == 'id' || $rule->condition_name == 'name') {
                            if ($rule->condition_compare == 'is') {
                                $shopLimited->where($rule->condition_name, $conditionVal);
                            } elseif ($rule->condition_compare == 'start_with') {
                                $shopLimited->where($rule->condition_name, 'like', "$conditionVal%");
                            } elseif ($rule->condition_compare == 'end_with') {
                                $shopLimited->where($rule->condition_name, 'like', "%$conditionVal");
                            } elseif ($rule->condition_compare == 'contain') {
                                $shopLimited->where($rule->condition_name, 'like', "%$conditionVal%");
                            } elseif ($rule->condition_compare == 'in_list') {
                                $orgParam = str_replace(" ", "", $conditionVal);
                                $listParams = explode(",", $orgParam);
                                $pList = [];
                                foreach ($listParams as $l) {
                                    if (trim($l) != null && trim($l) != "") $pList[] = $l;
                                }
                                $shopLimited->whereIn($rule->condition_name, $pList);
                            }
                        } elseif ($rule->condition_name == 'user_id') {
                            $conditionVal = str_replace(" ", "", $conditionVal);
                            if ($conditionVal == "" || $conditionVal == "own" || $conditionVal == "owner") {
                                $shopLimited->where("user_id", $user->id);
                            } else if ($conditionVal == "store") {
                                $cUser = User::select('created_by')->where('id', $user->id)->first();
                                $storeManger = User::role('storemanage')->select('id')->where('id', $cUser->created_by)->first();
                                $shopLimited->where("user_id", $storeManger->id);
                            } else if ($conditionVal == "owner,store" || $conditionVal == "store,owner" || $conditionVal == "owner,store," || $conditionVal == "store,owner,") {
                                $listUserIds = [$user->id];
                                $cUser = User::select('created_by')->where('id', $user->id)->first();
                                $storeManger = User::role('storemanage')->select('id')->where('id', $cUser->created_by)->first();
                                $listUserIds[] = $storeManger->id;
                                $shopLimited->whereIn("user_id", $listUserIds);
                            } else {
                                if (strpos($conditionVal, "@") !== false) {
                                    $author = User::select('id')->where('email', $conditionVal)->first();
                                } else {
                                    $author = User::select('id')->where('name', $conditionVal)->first();
                                }
                                if (isset($author) && isset($author->id)) {
                                    $shopLimited->where("user_id", $author->id);
                                } else {
                                    $shopLimited->where("user_id", 0);
                                }
                            }
                        }
                    }
                    $this->_limitedItems['data'] = $shopLimited->pluck('id')->toArray();
                    if ($this->_limitedItems['data'] == null || count($this->_limitedItems['data']) <= 0) {
                        $this->_limitedItems['data'][] = 0;
                    }
                }
            }
        }
    }

    public function index(Request $request)
    {
        /*$searchParams = $request->all();
        $limit = Arr::get($searchParams, 'limit', static::ITEM_PER_PAGE);
        $list = ShopIndex::select('*')->orderBy('id')->paginate($limit);
        return ShopResource::collection($list);*/

        $searchParams = $request->all();
        $list = Shop::notDeleted();
        $limit = Arr::get($searchParams, 'limit', static::ITEM_PER_PAGE);
        $keyword = Arr::get($searchParams, 'keyword', '');
        $status = Arr::get($searchParams, 'status', '');
        $areaId = Arr::get($searchParams, 'area_id', '');
        $areaIdList = null;

        if (!empty($keyword)) {
            $list->where('name', 'LIKE', '%' . $keyword . '%');
        }
        if ($status != '') {
            $list->where('is_activated', $status);
        }
        if ($areaId != null && $areaId != "") {
            $list->where('area_id', $areaId);
        }

        if ($this->_limitedItems['hasLimited']) {
            $list->whereIn('id', $this->_limitedItems['data']);
        }

        $list->orderBy('order')->orderBy('id');

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

    public function list(Request $request)
    {
        $searchParams = $request->all();
        $list = Shop::select('id', 'name', 'area_id')->notDeleted();
        $limit = Arr::get($searchParams, 'limit', static::ITEM_PER_PAGE);
        if ($this->_limitedItems['hasLimited']) $list->whereIn('id', $this->_limitedItems['data']);
        $list->orderBy('order')->orderBy('id');

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

    public function listSelect(Request $request)
    {
        $searchParams = $request->all();
        $list = Shop::select('id', 'name', 'area_id')->notDeleted();
        $limit = Arr::get($searchParams, 'limit', static::ITEM_PER_PAGE);
        if ($this->_limitedItems['hasLimited']) $list->whereIn('id', $this->_limitedItems['data']);
        $list->orderBy('order')->orderBy('id');

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

    public function getAreaListChild($id = 0)
    {
        $rs = [];
        $list = Area::select('id')->where('is_deleted', 0)->where('parent_id', $id)->get();
        foreach ($list as $item) {
            $rs[] = $item->id;
            $child = $this->getAreaListChild($item->id);
            $rs = array_merge($rs, $child);
        }
        return $rs;
    }

    public function all()
    {
        $list = Shop::select('id', 'name', 'show_search')->where('is_deleted', false);
        if ($this->_limitedItems['hasLimited']) $list->whereIn('id', $this->_limitedItems['data']);
        $list->orderBy('order')->orderBy('id');

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

    public function show($id = 0)
    {
        if ($this->_limitedItems['hasLimited']) {
            $shop = Shop::where('is_deleted', false)->whereIn('id', $this->_limitedItems['data'])->where('id', $id)->first();
        } else {
            $shop = Shop::where('is_deleted', false)->where('id', $id)->first();
        }
        if (!isset($shop)) return response()->json(['errors' => 'Shop is not valid'], 403);

        return new ShopResource($shop);
    }

    public function infoDetail($id = 0)
    {
        $information = ShopMeta::select('id', 'shop_id', 'title', 'content')->where('shop_id', $id)->orderBy('order')->get();

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

    public function store(Request $request)
    {
        $params = $request->all();
        if (isset($params['information']) && is_array($params['information'])) {
            if ($request->name == null || $request->name == "") $request->name = $this->detectStoreName($params['information']);
        }
        $validator = Validator::make($request->all(), ['area_id' => ['required'], 'name' => ['required'], 'is_activated' => ['required']]);
        if ($validator->fails()) return response()->json(['errors' => $validator->errors()], 403);

        $shop = Shop::create([
            'area_id'       => $params['area_id'],
            'name'          => $params['name'],
            'slug'          => Helper::slug($params['name']),
            'description'   => $params['description'],
            'logo'          => $params['logo'],
            'fee'           => $params['fee'],
            'average'       => $params['average'],
            'benefits'      => $params['benefits'],
            'enrolled'      => $params['enrolled'],
            'operation'     => $params['operation'],
            'reviews'       => $params['reviews'],
            'evaluation'    => $params['evaluation'],
            'station'       => $params['station'],
            'address'       => $params['address'],
            'points'        => $params['points'],
            'interview_url' => $params['interview_url'],
            'user_id'       => auth('api')->user()->id,
            '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 (isset($params['information']) && is_array($params['information'])) {
            $metaInfoData = [];
            foreach ($params['information'] as $key => $item) {
                $metaInfoData[] = [
                    'shop_id'    => $shop->id,
                    'title'      => $item['title'],
                    'content'    => $item['content'],
                    'order'      => ($key + 1),
                    'created_at' => date('Y-m-d H:i:s'),
                    'updated_at' => date('Y-m-d H:i:s'),
                ];
            }
            if (count($metaInfoData) > 0) ShopMeta::insert($metaInfoData);
        }

        if (isset($params['method']) && is_array($params['method'])) {
            $metaMethodData = [];
            foreach ($params['method'] as $key => $item) {
                $metaMethodData[] = [
                    'shop_id'    => $shop->id,
                    'info_id'    => $item,
                    'created_at' => date('Y-m-d H:i:s'),
                    'updated_at' => date('Y-m-d H:i:s'),
                ];
            }
            if (count($metaMethodData) > 0) ShopInfo::insert($metaMethodData);
        }

        if (isset($params['review']) && is_array($params['review'])) {
            $insertReview = [];
            foreach ($params['review'] as $item) {
                if (isset($item['name']) && $item['name'] != null && $item['name'] != "") {
                    $created_at = date('Y-m-d H:i:s');
                    if (isset($item['created_at']) && $item['created_at'] != "" && $item['created_at'] != null) {
                        $dateCreated = Carbon::parse($item['created_at']);
                        $created_at = $dateCreated->format('Y-m-d H:i:s');
                    }
                    $insertReview[] = [
                        'shop_id'    => $shop->id,
                        'name'       => $item['name'],
                        'rate'       => $item['rate'],
                        'content'    => $item['content'],
                        'like'       => $item['like'],
                        'color'      => Helper::randColor(),
                        'image_text' => mb_substr($item['name'], 0, 1, "UTF-8"),
                        'created_at' => $created_at,
                        'updated_at' => date('Y-m-d H:i:s')
                    ];
                }
            }
            ShopReview::insert($insertReview);
        }

        if (isset($params['tags']) && is_array($params['tags'])) {
            $keywords = [];
            foreach ($params['tags'] as $item) {
                $tag = trim($item['text']);
                $checkKeyword = Keyword::where('is_deleted', 0)
                    ->where(function ($query) use ($tag) {
                        $query->where('name', $tag)
                            ->orWhere('name', strtolower($tag))
                            ->orWhere('name', strtoupper($tag))
                            ->orWhere('name', ucfirst($tag));
                    })->first();
                if (!isset($checkKeyword) || $checkKeyword->id == null) {
                    $checkKeyword = Keyword::create([
                        'name'         => $tag,
                        'is_activated' => true,
                        'is_deleted'   => false,
                        'created_at'   => date('Y-m-d H:i:s'),
                        'updated_at'   => date('Y-m-d H:i:s'),
                    ]);
                }

                $keywords[] = [
                    'keyword_id' => $checkKeyword->id,
                    'ref_id'     => $shop->id,
                    'type'       => 'shop',
                    'created_at' => date('Y-m-d H:i:s'),
                    'updated_at' => date('Y-m-d H:i:s'),
                ];
            }
            if (count($keywords) > 0) KeywordDetail::insert($keywords);
        }

        if (isset($params['slider']) && is_array($params['slider'])) {
            $thumbPath = public_path('uploads/image/shop/');
            foreach ($params['slider'] as $item) {
                ShopSlider::create([
                    'shop_id'    => $shop->id,
                    'name'       => $item['name'],
                    'file_name'  => $item['file_name'],
                    'type'       => 'slider',
                    'created_at' => date('Y-m-d H:i:s'),
                    'updated_at' => date('Y-m-d H:i:s')
                ]);

                Helper::createThumbFit($thumbPath . $item['file_name'], $thumbPath, 60, 60);
                Helper::createThumbFit($thumbPath . $item['file_name'], $thumbPath, 760, 550);
            }
        }

        $shopUri = '/shop/detail/' . $shop->id;
        $metaSeo = Seo::where('uri', $shopUri)->where('post_id', $shop->id)->first();
        $seoData = [
            'uri'         => $shopUri,
            'title'       => (isset($params['seo']['title']) && $params['seo']['title'] != null && $params['seo']['title'] != "") ? $params['seo']['title'] : $params['name'],
            'keywords'    => isset($params['seo']['keywords']) ? $params['seo']['keywords'] : '',
            'description' => isset($params['seo']['description']) ? $params['seo']['description'] : '',
            'image'       => isset($params['seo']['image']) ? $params['seo']['image'] : '',
            'type'        => 'shop',
            'post_id'     => $shop->id,
            'updated_at'  => date('Y-m-d H:s:i'),
        ];
        if (isset($metaSeo)) {
            $metaSeo->update($seoData);
        } else {
            $seoData['created_at'] = date('Y-m-d H:s:i');
            Seo::create($seoData);
        }
        event(new TellerProcessed());

        return new ShopResource($shop);
    }

    public function update($id = 0, Request $request)
    {
        $params = $request->all();
        if (isset($params['information']) && is_array($params['information'])) {
            if ($request->name == null || $request->name == "") $request->name = $this->detectStoreName($params['information']);
        }

        $validator = Validator::make($request->all(), ['area_id' => ['required'], 'name' => ['required'], 'is_activated' => ['required']]);
        if ($validator->fails()) return response()->json(['errors' => $validator->errors()], 403);
        if ($this->_limitedItems['hasLimited']) {
            $shop = Shop::where('is_deleted', false)->whereIn('id', $this->_limitedItems['data'])->where('id', $id)->first();
        } else {
            $shop = Shop::where('is_deleted', false)->where('id', $id)->first();
        }

        if (!isset($shop)) return response()->json(['errors' => 'Shop is not valid'], 403);
        $params = $request->all();
        $shop->update([
            'area_id'       => $params['area_id'],
            'name'          => $params['name'],
            'slug'          => Helper::slug($params['name']),
            'description'   => $params['description'],
            'logo'          => $params['logo'],
            'fee'           => $params['fee'],
            'average'       => $params['average'],
            'benefits'      => $params['benefits'],
            'enrolled'      => $params['enrolled'],
            'operation'     => $params['operation'],
            'reviews'       => $params['reviews'],
            'evaluation'    => $params['evaluation'],
            'station'       => $params['station'],
            'address'       => $params['address'],
            'points'        => $params['points'],
            'interview_url' => $params['interview_url'],
            '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')
        ]);

        if (isset($params['information']) && is_array($params['information'])) {
            ShopMeta::where('shop_id', $shop->id)->delete();
            $metaInfoData = [];
            foreach ($params['information'] as $key => $item) {
                $metaInfoData[] = [
                    'shop_id'    => $shop->id,
                    'title'      => $item['title'],
                    'content'    => $item['content'],
                    'order'      => ($key + 1),
                    'created_at' => date('Y-m-d H:i:s'),
                    'updated_at' => date('Y-m-d H:i:s'),
                ];
            }
            if (count($metaInfoData) > 0) ShopMeta::insert($metaInfoData);
        }

        if (isset($params['method']) && is_array($params['method'])) {
            ShopInfo::where('shop_id', $shop->id)->delete();
            $metaMethodData = [];
            foreach ($params['method'] as $key => $item) {
                $metaMethodData[] = [
                    'shop_id'    => $shop->id,
                    'info_id'    => $item,
                    'created_at' => date('Y-m-d H:i:s'),
                    'updated_at' => date('Y-m-d H:i:s'),
                ];
            }
            if (count($metaMethodData) > 0) ShopInfo::insert($metaMethodData);
        }

        if (isset($params['review']) && is_array($params['review'])) {
            ShopReview::where('shop_id', $shop->id)->delete();
            $insertReview = [];
            foreach ($params['review'] as $item) {
                if (isset($item['name']) && $item['name'] != null && $item['name'] != "") {
                    $created_at = date('Y-m-d H:i:s');
                    if (isset($item['created_at']) && $item['created_at'] != "" && $item['created_at'] != null) {
                        $dateCreated = Carbon::parse($item['created_at']);
                        $created_at = $dateCreated->format('Y-m-d H:i:s');
                    }
                    $insertReview[] = [
                        'shop_id'    => $shop->id,
                        'name'       => $item['name'],
                        'rate'       => $item['rate'],
                        'content'    => $item['content'],
                        'like'       => $item['like'],
                        'color'      => Helper::randColor(),
                        'image_text' => mb_substr($item['name'], 0, 1, "UTF-8"),
                        'created_at' => $created_at,
                        'updated_at' => date('Y-m-d H:i:s')
                    ];
                }
            }
            ShopReview::insert($insertReview);
        }

        if (isset($params['tags']) && is_array($params['tags'])) {
            KeywordDetail::where('ref_id', $shop->id)->where('type', 'shop')->delete();
            $keywords = [];
            foreach ($params['tags'] as $item) {
                $tag = trim($item['text']);
                $checkKeyword = Keyword::where('is_deleted', 0)
                    ->where(function ($query) use ($tag) {
                        $query->where('name', $tag)
                            ->orWhere('name', strtolower($tag))
                            ->orWhere('name', strtoupper($tag))
                            ->orWhere('name', ucfirst($tag));
                    })->first();
                if (!isset($checkKeyword) || $checkKeyword->id == null) {
                    $checkKeyword = Keyword::create([
                        'name'         => $tag,
                        'is_activated' => true,
                        'is_deleted'   => false,
                        'created_at'   => date('Y-m-d H:i:s'),
                        'updated_at'   => date('Y-m-d H:i:s'),
                    ]);
                }

                $keywords[] = [
                    'keyword_id' => $checkKeyword->id,
                    'ref_id'     => $shop->id,
                    'type'       => 'shop',
                    'created_at' => date('Y-m-d H:i:s'),
                    'updated_at' => date('Y-m-d H:i:s'),
                ];
            }
            if (count($keywords) > 0) KeywordDetail::insert($keywords);
        }

        if (isset($params['slider']) && is_array($params['slider'])) {
            ShopSlider::where('shop_id', $shop->id)->delete();
            $thumbPath = public_path('uploads/image/shop/');

            foreach ($params['slider'] as $item) {
                ShopSlider::create([
                    'shop_id'    => $shop->id,
                    'name'       => $item['name'],
                    'file_name'  => $item['file_name'],
                    'type'       => 'slider',
                    'created_at' => date('Y-m-d H:i:s'),
                    'updated_at' => date('Y-m-d H:i:s')
                ]);
                if (!file_exists($thumbPath . "thumb_60x60/" . $item['file_name'])) Helper::createThumbFit($thumbPath . $item['file_name'], $thumbPath, 60, 60);
                if (!file_exists($thumbPath . "thumb_760x550/" . $item['file_name'])) Helper::createThumbFit($thumbPath . $item['file_name'], $thumbPath, 760, 550);
            }
        }

        $shopUri = '/shop/detail/' . $shop->id;
        $metaSeo = Seo::where('uri', $shopUri)->where('post_id', $shop->id)->first();
        $seoData = [
            'uri'         => $shopUri,
            'title'       => (isset($params['seo']['title']) && $params['seo']['title'] != null && $params['seo']['title'] != "") ? $params['seo']['title'] : $params['name'],
            'keywords'    => isset($params['seo']['keywords']) ? $params['seo']['keywords'] : '',
            'description' => isset($params['seo']['description']) ? $params['seo']['description'] : '',
            'type'        => 'shop',
            'post_id'     => $shop->id,
            'updated_at'  => date('Y-m-d H:s:i'),
        ];

        if (isset($metaSeo)) {
            $seoData['image'] = $metaSeo->image;
        }
        if (isset($params['seo']['image']) && $params['seo']['image'] !== "") {
            $seoData['image'] = $params['seo']['image'];
        }
        if (isset($metaSeo)) {
            $metaSeo->update($seoData);
        } else {
            $seoData['created_at'] = date('Y-m-d H:s:i');
            Seo::create($seoData);
        }
        event(new TellerProcessed());

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

    public function destroy($id = 0)
    {
        if ($this->_limitedItems['hasLimited']) {
            $shop = Shop::where('is_deleted', false)->whereIn('id', $this->_limitedItems['data'])->where('id', $id)->first();
        } else {
            $shop = Shop::where('is_deleted', false)->where('id', $id)->first();
        }
        if (!isset($shop)) response()->json(['error' => 'Ehhh! Can not delete this shop'], 403);

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

        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', []);
        if ($this->_limitedItems['hasLimited']) {
            $newList = [];
            foreach ($listIds as $it) {
                if (in_array($it, $this->_limitedItems['data'])) $newList = $it;
            }
            $listIds = $newList;
        }
        $shopList = Shop::notDeleted()->whereIn('id', $listIds)->get();
        if ($shopList->count() <= 0) response()->json(['error' => 'Shop is not valid.'], 403);
        try {
            Shop::notDeleted()->whereIn('id', $listIds)->update(['is_deleted' => true]);
        } catch (\Exception $ex) {
            response()->json(['error' => $ex->getMessage()], 403);
        }
        event(new TellerProcessed());

        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', []);
        if ($this->_limitedItems['hasLimited']) {
            $newList = [];
            foreach ($listIds as $it) {
                if (in_array($it, $this->_limitedItems['data'])) $newList = $it;
            }
            $listIds = $newList;
        }
        $shopList = Shop::notDeleted()->whereIn('id', $listIds)->get();
        if ($shopList->count() <= 0) response()->json(['error' => 'Shop is not valid.'], 403);
        try {
            Shop::notDeleted()->whereIn('id', $listIds)->update(['is_activated' => true]);
        } catch (\Exception $ex) {
            response()->json(['error' => $ex->getMessage()], 403);
        }
        event(new TellerProcessed());

        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', []);
        if ($this->_limitedItems['hasLimited']) {
            $newList = [];
            foreach ($listIds as $it) {
                if (in_array($it, $this->_limitedItems['data'])) $newList = $it;
            }
            $listIds = $newList;
        }
        $shopList = Shop::notDeleted()->whereIn('id', $listIds)->get();
        if ($shopList->count() <= 0) response()->json(['error' => 'Shop is not valid.'], 403);
        try {
            Shop::notDeleted()->whereIn('id', $listIds)->update(['is_activated' => false]);
        } catch (\Exception $ex) {
            response()->json(['error' => $ex->getMessage()], 403);
        }
        event(new TellerProcessed());

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

    public function position(Request $request)
    {
        if (!$request->has('position')) return response()->json(['errors' => 'Data is invalid'], 403);
        $newIndexes = $request->position;
        if (is_array($newIndexes)) {
            foreach ($newIndexes as $item) {
                Shop::where('id', $item['id'])->update(['order' => $item['order']]);
            }
        }
        event(new TellerProcessed());

        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 uploadCSV(Request $request)
    {
        /*CsvFile::truncate();
        CsvFileDetail::truncate();
        CsvFileConfig::truncate();*/

        if (!$request->hasFile('csv')) {
            return response()->json(['status' => 'error', 'userKey' => null, 'fileNameKey' => null, 'fileName' => null, 'baseName' => null, 'headerInfo' => null], 403);
        }

        $file = $request->file('csv');
        $baseName = $file->getClientOriginalName();
        $fileNameKey = md5($baseName . rand(1111, 9999) . date('YmdHis'));
        $fileName = $fileNameKey . '.' . $file->getClientOriginalExtension();
        $file->move($this->_csvPath, $fileName);
        $csvFilePath = $this->_csvPath . $fileName;
        $headerInfo = [];
        $status = 'error';

        if (!file_exists($csvFilePath)) {
            return response()->json(['status' => 'error', 'userKey' => null, 'fileNameKey' => null, 'fileName' => null, 'baseName' => null, 'headerInfo' => null], 403);
        }

        $totalItem = 0;
        $userKey = md5(rand(0, 1000) . date("YmdHis"));
        $csvFile = CsvFile::create([
            'key'        => $userKey,
            'file'       => $fileNameKey,
            'name'       => $baseName,
            'type'       => 'shop',
            'status'     => 0,
            'created_at' => date("Y-m-d H:i:s"),
            'updated_at' => date("Y-m-d H:i:s")
        ]);
        try {
            chmod($csvFilePath, 0777);
            $fileContent = fopen($csvFilePath, "r");
            $isHeader = true;
            $parentId = 0;

            while (!feof($fileContent)) {
                $row = fgetcsv($fileContent);
                if (isset($row) && is_array($row) && count($row) > 0) {
                    $cFileDetailItem = [
                        'csv_file_id' => $csvFile->id,
                        'type'        => $isHeader ? 0 : 1,
                        'status'      => 0
                    ];
                    for ($i = 0; $i < count($row); $i++) {
                        if (isset($row[$i]) && $row[$i] != null && trim($row[$i]) != "") {
                            $rKey = 'data_' . ($i + 1);
                            $cFileDetailItem[$rKey] = trim($row[$i]);
                            if ($isHeader) {
                                $headerInfo[] = ['key' => $rKey, 'name' => $row[$i]];
                            } else {
                                $totalItem++;
                            }
                        }
                    }
                    $cFileDetailItem['parent_id'] = (isset($row[2]) && ($row[2] == "" || $row[2] == null)) ? $parentId : 0;
                    $cFileDetailItem['created_at'] = date("Y-m-d H:i:s");
                    $cFileDetailItem['updated_at'] = date("Y-m-d H:i:s");
                    $cDetail = CsvFileDetail::create($cFileDetailItem);
                    if (isset($row[2]) && $row[2] != null && $row[2] != "") $parentId = $cDetail->id;
                    $isHeader = false;
                }
            }
            fclose($fileContent);
            $status = 'success';
        } catch (\Exception $exception) {
            logger($exception->getMessage());
        }
        $csvFile->update(['total' => $totalItem]);

        return response()->json(['status' => $status, 'userKey' => $userKey, 'fileNameKey' => $fileNameKey, 'fileName' => $fileName, 'baseName' => $baseName, 'headerInfo' => $headerInfo], 200);
    }

    public function csvConfig(Request $request)
    {
        $validator = Validator::make($request->all(), ['file' => ['required'], 'overwrite' => ['required'], 'column_data' => ['required']]);
        if ($validator->fails()) return response()->json(['errors' => $validator->errors()], 403);
        $params = $request->all();
        $csvFile = CsvFile::where('file', $params['file'])->where('type', 'shop')->where('status', 0)->first();
        if (!isset($csvFile)) return response()->json(['errors' => 'CSV is not valid'], 403);
        $csvFile->update(['overwrite' => $params['overwrite']]);
        $insertData = [];
        foreach ($params['column_data'] as $key => $col) {
            $insertData[] = [
                'csv_file_id' => $csvFile->id,
                'name'        => $key,
                'key'         => $col,
                'created_at'  => date('Y-m-d H:i:s'),
                'updated_at'  => date('Y-m-d H:i:s'),
            ];
        }
        CsvFileConfig::insert($insertData);

        return response()->json(['status' => 'success', 'file' => $csvFile->file], 200);
    }

    public function csvCheckKey($file = "")
    {
        $csvFile = CsvFile::where('file', $file)->where('type', 'shop')->first();
        if (!isset($csvFile)) return response()->json(['errors' => 'CSV is not valid'], 403);

        $status = 'fails';
        $newKey = $csvFile->key;
        $total = CsvFileDetail::where('csv_file_id', $csvFile->id)->where('parent_id', 0)->where('type', 1)->count();
        $imported = CsvFileDetail::where('csv_file_id', $csvFile->id)->where('parent_id', 0)->where('type', 1)->where('status', 2)->count();

        if ($csvFile->status == 2) {
            $status = 'done';
        } else {
            $checkDetail = CsvFileDetail::where('csv_file_id', $csvFile->id)->where('parent_id', 0)->where('type', 1)->where('status', 0)->count();
            if ($checkDetail > 0) {
                $status = 'success';
                $newKey = md5(rand(100, 100000) . date('YmdHis'));
                $csvFile->update(['status' => 1, 'key' => $newKey]);
            }
        }

        return response()->json([
            'status'   => $status,
            'key'      => $newKey,
            'total'    => $total,
            'imported' => $imported,
        ], 200);
    }

    public function csvInfo(Request $request, $file = "")
    {
        $csvFile = CsvFile::where('file', $file)->where('type', 'shop')->where('status', '!=', 2)->first();
        if (!isset($csvFile)) return response()->json(['errors' => 'CSV is not valid'], 403);
        $params = $request->all();
        $limit = Arr::get($params, 'limit', 50);
        $configs = CsvFileConfig::select('name', 'key')->where('csv_file_id', $csvFile->id)->get();
        $selectRaw = "id, type, status";
        foreach ($configs as $config) {
            if ($selectRaw != "") {
                $selectRaw .= ", " . $config->key . " as " . $config->name;
            } else {
                $selectRaw .= $config->key . " as " . $config->name;
            }
        }
        $list = CsvFileDetail::selectRaw($selectRaw)->where('csv_file_id', $csvFile->id)->where('parent_id', 0)->where('type', 1)->orderBy('id');

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

    public function csvImport(Request $request, $id = 0)
    {
        $params = $request->all();
        $userKey = $params['key'];
        $file = $params['file'];
        $csvFile = CsvFile::where('file', $file)->where('key', $userKey)->where('type', 'shop')->where('status', 1)->first();
        if (!isset($csvFile)) return response()->json(['errors' => 'Progress was stopped by another import task.'], 403);
        $methodRoot = ['対面占い', '電話占い', 'チャット占い', 'メール占い', 'オンライン占い'];
        $code_status = 3;
        $configs = CsvFileConfig::select('name', 'key')->where('csv_file_id', $csvFile->id)->get();
        $selectRaw = "id, type, status";
        foreach ($configs as $config) {
            $selectRaw .= ", " . $config->key . " as " . $config->name;
        }
        $csvDetail = CsvFileDetail::selectRaw($selectRaw)->where('csv_file_id', $csvFile->id)->where('id', $id)->where('status', 0)->first();
        if (!isset($csvDetail)) return response()->json(['errors' => 'CSV is not valid'], 403);

        $areaName = trim($csvDetail->csv_area);
        $area = Area::where('is_deleted', false)->where('name', $areaName)->first();
        if (!isset($area)) {
            $area = Area::create([
                'name'       => $areaName,
                'slug'       => $areaName,
                'parent_id'  => 0,
                'created_at' => date('Y-m-d H:i:s'),
                'updated_at' => date('Y-m-d H:i:s'),
            ]);
        }

        $shopName = trim($csvDetail->csv_name);
        $shop = Shop::where('is_deleted', false)->where('area_id', $area->id)->where('name', $shopName)->first();
        $isAllowOverwrite = $csvFile->overwrite == 1;

        if (!isset($shop) || (isset($shop) && $isAllowOverwrite)) {
            $logoName = (isset($shop) && $shop->id != null) ? $shop->logo : "no-image.png";
            $logoUrl = trim($csvDetail->csv_logo);
            if ($logoUrl != null && $logoUrl != "") $logoName = $this->csvCreateThumb($logoUrl);

            $evaluation = 0;
            if (trim($csvDetail->csv_evaluation) != null && trim($csvDetail->csv_evaluation) != "" && is_numeric(trim($csvDetail->csv_evaluation))) {
                $evaluation = (double) trim($csvDetail->csv_evaluation);
            }

            $shopData = [
                'area_id'      => $area->id,
                'name'         => $shopName,
                'slug'         => Helper::slug($shopName),
                'user_id'      => auth('api')->user()->id,
                'description'  => trim($csvDetail->csv_description),
                'logo'         => $logoName,
                'fee'          => trim($csvDetail->csv_fee),
                'average'      => trim($csvDetail->csv_budget),
                'benefits'     => trim($csvDetail->csv_benefits),
                'operation'    => trim($csvDetail->csv_operation),
                'reviews'      => trim($csvDetail->csv_review),
                'evaluation'   => $evaluation,
                'show_search'  => (trim($csvDetail->csv_search) == "true" || trim($csvDetail->csv_search) == "1" || trim($csvDetail->csv_search) == true) ? 1 : 0,
                'is_activated' => (trim($csvDetail->csv_activated) == "false" || trim($csvDetail->csv_activated) == "0" || trim($csvDetail->csv_activated) == false) ? 0 : 1,
                'updated_at'   => date('Y-m-d H:i:s')
            ];

            if (!isset($shop)) {
                $shopData['created_at'] = date('Y-m-d H:i:s');
                $shop = Shop::create($shopData);
            } else {
                if ($isAllowOverwrite) $shop->update($shopData);
            }

            //Info
            $metaInfoData = [];
            if (trim($csvDetail->csv_info_name) != null && trim($csvDetail->csv_info_name) != "") {
                $metaInfoData[] = [
                    'shop_id'    => $shop->id,
                    'title'      => trim($csvDetail->csv_info_name),
                    'content'    => trim($csvDetail->csv_info_value),
                    'order'      => 1,
                    'created_at' => date('Y-m-d H:i:s'),
                    'updated_at' => date('Y-m-d H:i:s'),
                ];
            }
            $csvDetailItems = CsvFileDetail::selectRaw($selectRaw)->where('csv_file_id', $csvFile->id)->where('parent_id', $csvDetail->id)->where('status', 0)->get();
            foreach ($csvDetailItems as $mKey => $item) {
                if (trim($item->csv_info_name) != null && trim($item->csv_info_name) != "") {
                    $metaInfoData[] = [
                        'shop_id'    => $shop->id,
                        'title'      => trim($item->csv_info_name),
                        'content'    => trim($item->csv_info_value),
                        'order'      => $mKey + 2,
                        'created_at' => date('Y-m-d H:i:s'),
                        'updated_at' => date('Y-m-d H:i:s'),
                    ];
                }
            }
            if ($isAllowOverwrite) ShopMeta::where('shop_id', $shop->id)->delete();
            if (count($metaInfoData) > 0) ShopMeta::insert($metaInfoData);

            //Method
            $methodList = trim($csvDetail->csv_method);
            if ($methodList != null && $methodList != "") {
                $methodList = explode("|", $methodList);
                $metaMethodData = [];
                foreach ($methodList as $m) {
                    $m = trim($m);
                    if ($m == "" || $m == null || !in_array($m, $methodRoot)) continue;
                    $mItemId = null;
                    if ($m == "対面占い") {
                        $mItemId = 1;
                    } else if ($m == "電話占い") {
                        $mItemId = 2;
                    } else if ($m == "チャット占い") {
                        $mItemId = 3;
                    } else if ($m == "メール占い") {
                        $mItemId = 4;
                    } else if ($m == "オンライン占い") {
                        $mItemId = 5;
                    }

                    if ($mItemId != null) {
                        $metaMethodData[] = [
                            'shop_id'    => $shop->id,
                            'info_id'    => $mItemId,
                            'created_at' => date('Y-m-d H:i:s'),
                            'updated_at' => date('Y-m-d H:i:s'),
                        ];
                    }
                }
                if ($isAllowOverwrite) ShopInfo::where('shop_id', $shop->id)->delete();
                if (count($metaMethodData) > 0) ShopInfo::insert($metaMethodData);
            }

            //Slider
            $slider = trim($csvDetail->csv_image);
            if ($slider != null && $slider != "") {
                $slider = explode("|", $slider);
                $sInsertData = [];
                foreach ($slider as $fileUrl) {
                    if (trim($fileUrl) == null || trim($fileUrl) == "") continue;
                    $imgFileName =  $this->csvCreateThumb(trim($fileUrl));
                    $sInsertData[] = [
                        'shop_id'    => $shop->id,
                        'name'       => $imgFileName,
                        'file_name'  => $imgFileName,
                        'type'       => 'slider',
                        'created_at' => date('Y-m-d H:i:s'),
                        'updated_at' => date('Y-m-d H:i:s')
                    ];
                }

                if ($isAllowOverwrite) ShopSlider::where('type', 'slider')->where('shop_id', $shop->id)->delete();
                if (count($sInsertData) > 0) ShopSlider::insert($sInsertData);
            }

            //SEO
            $shopUri = '/shop/detail/' . $shop->id;
            $metaSeo = Seo::where('uri', $shopUri)->where('post_id', $shop->id)->first();
            $seoTitle = trim($csvDetail->csv_seo_title);
            $seoTitle = ($seoTitle == null || $seoTitle == "") ? $shopName : $seoTitle;
            $seoData = [
                'uri'         => $shopUri,
                'title'       => $seoTitle,
                'keywords'    => $csvDetail->csv_seo_keywords,
                'description' => $csvDetail->csv_seo_desc,
                'image'       => $csvDetail->csv_seo_image,
                'type'        => 'shop',
                'post_id'     => $shop->id,
                'updated_at'  => date('Y-m-d H:s:i'),
            ];
            if (isset($metaSeo)) {
                $metaSeo->update($seoData);
            } else {
                $seoData['created_at'] = date('Y-m-d H:s:i');
                Seo::create($seoData);
            }

            $code_status = 2;
            $csvFile->update(['imported' => ($csvFile->imported + 1)]);
        }

        $csvDetail->update(['status' => $code_status]);
        CsvFileDetail::where('csv_file_id', $csvFile->id)->where('parent_id', $csvDetail->id)->update(['status' => $code_status]);

        $imported = CsvFileDetail::where('csv_file_id', $csvFile->id)->where('parent_id', 0)->where('type', 1)->where('status', 2)->count();
        $nextDetail = CsvFileDetail::select('id')->where('csv_file_id', $csvFile->id)
            ->where('parent_id', 0)
            ->where('type', 1)
            ->where('status', 0)
            ->orderBy('id')
            ->first();

        $rsStatus = 'success';
        $nextId = (isset($nextDetail) && $nextDetail->id != null) ? $nextDetail->id : null;
        if ($nextId == null) {
            $rsStatus = 'done';
            $csvFile->update(['status' => 2]);
            event(new TellerProcessed());
        }

        return response()->json([
            'status'      => $rsStatus,
            'next'        => $nextId,
            'imported'    => $imported,
            'code_status' => $code_status
        ], 200);
    }

    public function csvImportError(Request $request, $id = 0) {
        $csvFile = CsvFile::where('file', $request->get('file'))->where('key', $request->get('key'))->where('type', 'shop')->where('status', 1)->first();
        if (!isset($csvFile)) return response()->json(['errors' => 'Progress was stopped by another import task.'], 403);
        $csvDetail = CsvFileDetail::where('csv_file_id', $csvFile->id)->where('id', $id)->first();
        if (!isset($csvDetail)) return response()->json(['errors' => 'CSV is not valid'], 403);
        $csvDetail->update(['status' => 3]);
        CsvFileDetail::where('csv_file_id', $csvFile->id)->where('parent_id', $csvDetail->id)->update(['status' => 3]);

        $nextDetail = CsvFileDetail::select('id')->where('csv_file_id', $csvFile->id)
            ->where('parent_id', 0)
            ->where('type', 1)
            ->where('status', 0)
            ->orderBy('id')
            ->first();

        $rsStatus = 'success';
        $nextId = (isset($nextDetail) && $nextDetail->id != null) ? $nextDetail->id : null;
        if ($nextId == null) {
            $rsStatus = 'done';
            $csvFile->update(['status' => 2]);
            event(new TellerProcessed());
        }

        return response()->json([
            'status'      => $rsStatus,
            'next'        => $nextId,
        ], 200);
    }

    private function csvCreateThumb($imgUrl) {
        $fileName = md5(rand(100, 100000) . date('YmdHis')) . ".jpg";
        try {
            $imgCross = ImageCross::make($imgUrl)->orientate()->save($this->_imagePath . $fileName);;
            $imgCross->fit(760, 550, function ($constraint) {
                $constraint->upsize();
            })->save($this->_imagePath . "thumb_760x550/" . $fileName);
            $imgCross->fit(60, 60, function ($constraint) {
                $constraint->upsize();
            })->save($this->_imagePath . "thumb_60x60/" . $fileName);
        } catch (Intervention\Image\Exception\NotSupportedException $exception) {
            logger("[Thumb] Image error: " . $exception->getMessage());
        } catch (\Exception $exception) {
            logger("[Importing] Get Image Logo Error: " . $exception->getMessage());
        } finally {
            return $fileName;
        }
    }

    public function changeAreaMultiple(Request $request)
    {
        $validator = Validator::make($request->all(), ['area_id' => 'required', 'ids' => 'required']);
        if ($validator->fails()) return response()->json(['errors' => $validator->errors()], 403);
        $listIds = $request->get('ids', []);
        $areaId = $request->get('area_id');
        if ($this->_limitedItems['hasLimited']) {
            $newList = [];
            foreach ($listIds as $it) {
                if (in_array($it, $this->_limitedItems['data'])) $newList = $it;
            }
            $listIds = $newList;
        }
        $shopList = Shop::notDeleted()->whereIn('id', $listIds)->get();
        if ($shopList->count() <= 0) response()->json(['error' => 'Shop is not valid.'], 403);
        try {
            Shop::notDeleted()->whereIn('id', $listIds)->update(['area_id' => $areaId]);
        } catch (\Exception $ex) {
            response()->json(['error' => $ex->getMessage()], 403);
        }

        return response()->json(['data' => ['status' => 'success', 'message' => 'Update successfully.']], 200);
    }

    private function detectStoreName($information = [])
    {
        $storeName = '';
        foreach ($information as $key => $item) {
            if ((trim($item['title']) == '屋号' || trim($item['title']) == '店舗名') && $storeName == '') {
                $storeName = trim($item['content']);
                break;
            }
        }

        return $storeName;
    }
}
