<?php

namespace App\Http\Controllers\Admin;

use App\Area;
use App\ConsultationDetail;
use App\Events\SaveDataEvent;
use App\FortunemethodDetail;
use App\FortuneSchedule;
use App\Helpers\Helper;
use App\Http\Controllers\Controller;
use App\Http\Resources\Admin\FortunetellerListResource;
use App\Keyword;
use App\KeywordDetail;
use App\RuleCustom;
use App\Shop;
use App\Laravue\Models\User;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Arr;
use App\Fortuneteller;
use App\FortunetellerFile;
use App\RefName;
use App\FortuneMeta;
use App\FortuneReview;
use App\ShopMeta;
use App\Seo;
use App\Http\Resources\Admin\FortunetellerResource;
use Validator;
use ImageCross;

/**
 * Class FortunetellerController
 *
 * @package App\Http\Controllers
 */
class FortunetellerController extends Controller
{
    const ITEM_PER_PAGE = 20;
    private $_imagePath;
    private $_limitedByShop;
    private $_limitedByOwner;
    private $_limitedByAssign;

    public function __construct()
    {
        $this->_imagePath = public_path('uploads/image/fortune/');
        $this->_limitedByShop = ['hasLimited' => false, 'data' => []];
        $this->_limitedByOwner = ['hasLimited' => false, 'data' => []];
        $this->_limitedByAssign = ['hasLimited' => false, 'data' => []];

        $user = auth('api')->user();
        if ($user != null && !$user->hasRole('admin') && !$user->hasRole('manager') && !$user->hasPermissionTo('manage-fortuneteller')) {
            if ($user->hasPermissionTo('manage-fortuneteller-group') && $user->hasPermissionTo('manage-shop-custom')) {
                $this->_limitedByShop['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') {
                                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->_limitedByShop['data'] = $shopLimited->pluck('id')->toArray();
                        if ($this->_limitedByShop['data'] == null || count($this->_limitedByShop['data']) <= 0) {
                            $this->_limitedByShop['data'][] = 0;
                        }
                    }
                }
            }

            if ($user->hasPermissionTo('manage-fortuneteller-owner')) {
                $this->_limitedByOwner['hasLimited'] = true;
                $this->_limitedByOwner['data'] = Fortuneteller::select('id')->where('is_deleted', false)->where('user_id', $user->id)->pluck('id')->toArray();
            }

            if ($user->hasPermissionTo('manage-fortuneteller-assign')) {
                $this->_limitedByAssign['hasLimited'] = true;
                $this->_limitedByAssign['data'] = Fortuneteller::select('id')->where('is_deleted', false)->where('assigned_user_id', $user->id)->pluck('id')->toArray();
            }
        }
    }

    public function index(Request $request)
    {
        //DB::connection()->enableQueryLog();
        $searchParams = $request->all();
        $list = Fortuneteller::where('is_deleted', false);
        $limit = Arr::get($searchParams, 'limit', static::ITEM_PER_PAGE);
        $keyword = Arr::get($searchParams, 'keyword', '');
        $areaId = Arr::get($searchParams, 'area_id', '');
        $shopId = Arr::get($searchParams, 'shop_id', '');
        $status = Arr::get($searchParams, 'status', '');

        if ($this->_limitedByShop['hasLimited']) {
            $list->whereIn('shop_id', $this->_limitedByShop['data']);
        }
        if ($this->_limitedByOwner['hasLimited'] && $this->_limitedByAssign['hasLimited']) {
            $ownerAssignList = array_merge($this->_limitedByOwner['data'], $this->_limitedByAssign['data']);
            $list->whereIn('id', $ownerAssignList);
        } else if ($this->_limitedByOwner['hasLimited']) {
            $list->whereIn('id', $this->_limitedByOwner['data']);
        } else if ($this->_limitedByAssign['hasLimited']) {
            $list->whereIn('id', $this->_limitedByAssign['data']);
        }

        if (!empty($keyword) && $keyword != "") {
            $keywordAreas = Area::select('id')
                ->where(function ($query) use ($keyword) {
                    $query->where('name', 'LIKE', '%' . $keyword . '%')
                        ->orWhere('slug', 'LIKE', '%' . $keyword . '%');
                })
                ->where('is_deleted', false)
                ->pluck('id')
                ->toArray();

            $keywordShops = Shop::select('id')
                ->where(function ($query) use ($keyword, $keywordAreas) {
                    $query->where('name', 'LIKE', '%' . $keyword . '%')
                        ->orWhere('slug', 'LIKE', '%' . $keyword . '%')
                        ->orWhereIn('area_id', $keywordAreas);
                })
                ->where('is_deleted', false)
                ->pluck('id')
                ->toArray();

            $list->where(function ($query) use ($keyword, $keywordShops) {
                $query->where('name', 'LIKE', '%' . $keyword . '%')
                    ->orWhere('display_name', 'LIKE', '%' . $keyword . '%')
                    ->orWhere('slug', 'LIKE', '%' . $keyword . '%')
                    ->orWhere('number', $keyword)
                    ->orWhere('id', $keyword)
                    ->orWhereIn('shop_id', $keywordShops);
            });
        }

        $filterByShop = false;
        $shopIds = [];
        if ($shopId != null && $shopId != '') {
            $filterByShop = true;
            $shopIds[] = $shopId;
        } else {
            if ($areaId != null && $areaId != '') {
                $filterByShop = true;
                $shopIds = Shop::select('id')->where('is_deleted', false)->where('area_id', $areaId)->pluck('id')->toArray();
            }
        }

        if ($filterByShop == true) {
            $list->whereIn('shop_id', $shopIds);
        }

        if ($status != '') {
            if ($status == '0' || $status == 0) {
                $list->where('is_activated', false);
            } else {
                $list->where('is_activated', true);
            }
        }

        $list->orderBy('is_activated', 'DESC')->orderBy('id', 'DESC');
        $list = $list->paginate($limit);
        //logger(DB::getQueryLog());

        return FortunetellerResource::collection($list);
    }

    public function getByStore(Request $request)
    {
        $searchParams = $request->all();
        $list = Fortuneteller::notDeleted();
        $limit = Arr::get($searchParams, 'limit', static::ITEM_PER_PAGE);
        if ($this->_limitedByShop['hasLimited']) $list->whereIn('shop_id', $this->_limitedByShop['data']);
        if ($this->_limitedByOwner['hasLimited'] && $this->_limitedByAssign['hasLimited']) {
            $ownerAssignList = array_merge($this->_limitedByOwner['data'], $this->_limitedByAssign['data']);
            $list->whereIn('id', $ownerAssignList);
        } else if ($this->_limitedByOwner['hasLimited']) {
            $list->whereIn('id', $this->_limitedByOwner['data']);
        } else if ($this->_limitedByAssign['hasLimited']) {
            $list->whereIn('id', $this->_limitedByAssign['data']);
        }

        $list->orderBy('id', 'DESC');

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

    public function all()
    {
        $list = Fortuneteller::select('id', 'name')->notDeleted();
        if ($this->_limitedByShop['hasLimited']) $list->whereIn('shop_id', $this->_limitedByShop['data']);
        if ($this->_limitedByOwner['hasLimited'] && $this->_limitedByAssign['hasLimited']) {
            $ownerAssignList = array_merge($this->_limitedByOwner['data'], $this->_limitedByAssign['data']);
            $list->whereIn('id', $ownerAssignList);
        } else if ($this->_limitedByOwner['hasLimited']) {
            $list->whereIn('id', $this->_limitedByOwner['data']);
        } else if ($this->_limitedByAssign['hasLimited']) {
            $list->whereIn('id', $this->_limitedByAssign['data']);
        }

        $list->orderBy('id');

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

    public function show($id = 0)
    {
        $list = Fortuneteller::notDeleted()->where('id', $id);
        if ($this->_limitedByShop['hasLimited']) $list->whereIn('shop_id', $this->_limitedByShop['data']);
        if ($this->_limitedByOwner['hasLimited'] && $this->_limitedByAssign['hasLimited']) {
            $ownerAssignList = array_merge($this->_limitedByOwner['data'], $this->_limitedByAssign['data']);
            $list->whereIn('id', $ownerAssignList);
        } else if ($this->_limitedByOwner['hasLimited']) {
            $list->whereIn('id', $this->_limitedByOwner['data']);
        } else if ($this->_limitedByAssign['hasLimited']) {
            $list->whereIn('id', $this->_limitedByAssign['data']);
        }
        $fortuneteller = $list->first();

        if (!isset($fortuneteller)) return response()->json(['errors' => 'Fortuneteller is not valid'], 403);

        return new FortunetellerResource($fortuneteller);
    }

    public function store(Request $request)
    {
        $validator = Validator::make($request->all(), ['name' => ['required'], 'shop_id' => ['required'], 'is_activated' => ['required']]);
        if ($validator->fails()) return response()->json(['errors' => $validator->errors()], 403);
        $params = $request->all();

        $checkNumber = true;
        $number = Fortuneteller::count();
        do {
            $number += 1;
            $countNum = Fortuneteller::where('number', $number)->count();
            if ($countNum <= 0) $checkNumber = false;
        } while ($checkNumber);

        $slug = $number;
        if (isset($params['slug']) && $params['slug'] != null && $params['slug'] != "") {
            $slug = Helper::slug($params['slug']);
            $checkSlug = Fortuneteller::where('is_activated', 1)->where('is_deleted', 0)->where('slug', $slug)->count();
            if ($checkSlug > 0) return response()->json(['data' => ['status' => 'error', 'message' => 'Slug is exits']], 200);
        } else {
            do {
                $checkSlug = Fortuneteller::where('is_activated', 1)->where('is_deleted', 0)->where('slug', $slug)->count();
                if ($checkSlug > 0) $slug .= "-1";
            } while ($checkSlug > 0);
        }

        $firstChar = mb_substr($params['name'], 0, 1, "UTF-8");
        $refName = RefName::where('name', $firstChar)->first();
        if ($refName == null || !isset($refName->id)) {
            $refName = RefName::create(['name' => $firstChar, 'created_at' => date('Y-m-d H:i:s'), 'updated_at' => date('Y-m-d H:i:s')]);
        }

        if ($params['avatar'] == null || $params['avatar'] == "") $params['avatar'] = "no-image.png";

        $insertData = [
            'number'               => $number,
            'slug'                 => $slug,
            'shop_id'              => $params['shop_id'],
            'name'                 => $params['name'],
            'display_name'         => $params['display_name'],
            'gender'               => (int)$params['gender'],
            'age'                  => ($params['age'] != '' && $params['age'] != null) ? $params['age'] : '',
            'phone_number'         => $params['phone_number'],
            'email'                => $params['email'],
            'address'              => $params['address'],
            'avatar'               => $params['avatar'],
            'desc_1_image'         => $params['desc_1_image'],
            'desc_1_title'         => ($params['desc_1_title'] != null && $params['desc_1_title'] != "") ? $params['desc_1_title'] : $params['name'],
            'desc_1_short'         => $params['desc_1_short'],
            'desc_1_full'          => $params['desc_1_full'],
            'desc_2_image'         => $params['desc_2_image'],
            'desc_2_title'         => $params['desc_2_title'],
            'desc_2_short'         => $params['desc_2_short'],
            'desc_2_full'          => $params['desc_2_full'],
            'cost'                 => $params['cost'],
            'consultation_minutes' => $params['consultation_minutes'],
            'performance'          => $params['performance'],
            'use_scry'             => $params['use_scry'],
            'consultation_genre'   => $params['consultation_genre'],
            'good_consultation'    => $params['good_consultation'],
            'commitment'           => $params['commitment'],
            'boom'                 => $params['boom'],
            'message'              => $params['message'],
            'message_image'        => $params['message_image'],
            'ref_name_id'          => $refName->id,
            'preview_code'         => md5(Helper::generateRandomString(8)),
            'user_id'              => auth('api')->user()->id,
            'assigned_user_id'     => $params['assigned_user_id'],
            'show_top'             => ($params['show_top'] === true) ? 1 : 0,
            'is_popular'           => ($params['is_popular'] === 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['category_id']) && $params['category_id'] != null && $params['category_id'] != '') {
            $insertData['category_id'] = $params['category_id'];
        }
        $fortuneteller = Fortuneteller::create($insertData);

        if (isset($params['profile']) && is_array($params['profile'])) {
            $metaProfileData = [];
            foreach ($params['profile'] as $item) {
                $metaProfileData[] = [
                    'fortune_teller_id' => $fortuneteller->id,
                    'title'             => $item['title'],
                    'content'           => $item['content'],
                    'type'              => 'profile',
                    'created_at'        => date('Y-m-d H:i:s'),
                    'updated_at'        => date('Y-m-d H:i:s'),
                ];
            }
            if (count($metaProfileData) > 0) FortuneMeta::insert($metaProfileData);
        }
        if (isset($params['comment']) && is_array($params['comment'])) {
            $metaCommentData = [];
            foreach ($params['comment'] as $item) {
                $metaCommentData[] = [
                    'fortune_teller_id' => $fortuneteller->id,
                    'title'             => $item['title'],
                    'content'           => $item['content'],
                    'type'              => 'comment',
                    'created_at'        => date('Y-m-d H:i:s'),
                    'updated_at'        => date('Y-m-d H:i:s'),
                ];
            }
            if (count($metaCommentData) > 0) FortuneMeta::insert($metaCommentData);
        }

        if (isset($params['method']) && is_array($params['method'])) {
            $fortunemethodDetailData = [];
            foreach ($params['method'] as $item) {
                $fortunemethodDetailData[] = [
                    'fortune_teller_id' => $fortuneteller->id,
                    'fortune_method_id' => $item,
                    'created_at'        => date('Y-m-d H:i:s'),
                    'updated_at'        => date('Y-m-d H:i:s'),
                ];
            }
            if (count($fortunemethodDetailData) > 0) FortunemethodDetail::insert($fortunemethodDetailData);
        }

        if (isset($params['consultation']) && is_array($params['consultation'])) {
            $consultationDetailData = [];
            foreach ($params['consultation'] as $item) {
                $consultationDetailData[] = [
                    'fortune_teller_id' => $fortuneteller->id,
                    'consultation_id'   => $item,
                    'created_at'        => date('Y-m-d H:i:s'),
                    'updated_at'        => date('Y-m-d H:i:s'),
                ];
            }
            if (count($consultationDetailData) > 0) ConsultationDetail::insert($consultationDetailData);
        }

        if ($params['avatar'] != null && $params['avatar'] != "" && $params['avatar'] != "no-image.png") $this->generateFortuneThumb($params['avatar'], $this->_imagePath);

        if (isset($params['slider']) && is_array($params['slider'])) {
            foreach ($params['slider'] as $item) {
                FortunetellerFile::create([
                    'fortune_teller_id' => $fortuneteller->id,
                    'file_name'         => $item,
                    'type'              => 'slider',
                    'created_at'        => date('Y-m-d H:i:s'),
                    'updated_at'        => date('Y-m-d H:i:s')
                ]);
            }
        }

        /*if (isset($params['gallery']) && is_array($params['gallery'])) {
            foreach ($params['gallery'] as $item) {
                FortunetellerFile::create([
                    'fortune_teller_id' => $fortuneteller->id,
                    'file_name'         => $item['file_name'],
                    'type'              => 'gallery',
                    'created_at'        => date('Y-m-d H:i:s'),
                    'updated_at'        => date('Y-m-d H:i:s')
                ]);
            }
        }*/

        if (isset($params['schedule']) && is_array($params['schedule'])) {
            $insertSchedule = [];
            foreach ($params['schedule'] as $item) {
                $insertSchedule[] = [
                    'fortune_teller_id' => $fortuneteller->id,
                    'schedule_id'       => $item['id'],
                    'time_8'            => $item['time_8'],
                    'time_9'            => $item['time_9'],
                    'time_10'           => $item['time_10'],
                    'time_11'           => $item['time_11'],
                    'time_12'           => $item['time_12'],
                    'time_13'           => $item['time_13'],
                    'time_14'           => $item['time_14'],
                    'time_15'           => $item['time_15'],
                    'time_16'           => $item['time_16'],
                    'time_17'           => $item['time_17'],
                    'time_18'           => $item['time_18'],
                    'time_19'           => $item['time_19'],
                    'time_20'           => $item['time_20'],
                    'time_21'           => $item['time_21'],
                    'time_22'           => $item['time_22'],
                    'time_23'           => $item['time_23'],
                    'time_24'           => $item['time_24'],
                    'time_1'            => $item['time_1'],
                    'created_at'        => date('Y-m-d H:i:s'),
                    'updated_at'        => date('Y-m-d H:i:s')
                ];
            }
            FortuneSchedule::insert($insertSchedule);
        }

        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[] = [
                        'fortune_teller_id' => $fortuneteller->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')
                    ];
                }
            }
            FortuneReview::insert($insertReview);
        }

        ShopMeta::where('shop_id', $params['shop_id'])->delete();
        if (isset($params['info']) && is_array($params['info'])) {
            $metaInfoData = [];
            foreach ($params['info'] as $item) {
                $metaInfoData[] = [
                    'shop_id'    => $params['shop_id'],
                    'title'      => $item['title'],
                    'content'    => $item['content'],
                    'created_at' => date('Y-m-d H:i:s'),
                    'updated_at' => date('Y-m-d H:i:s'),
                ];
                if (trim($item['title']) == "屋号") {
                    Shop::where('id', $params['shop_id'])->update(['name' => $item['content']]);
                }
            }
            if (count($metaInfoData) > 0) ShopMeta::insert($metaInfoData);
        }

        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'     => $fortuneteller->id,
                    'type'       => 'teller',
                    '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);
        }

        $metaSeo = Seo::where('post_id', $fortuneteller->id)->where('type', 'teller')->first();
        $seoData = [
            'uri'         => '/fortune-teller/detail/' . $slug,
            'title'       => ($params['seo']['title'] != null && $params['seo']['title'] != "") ? $params['seo']['title'] : $params['name'],
            'keywords'    => $params['seo']['keywords'],
            'description' => $params['seo']['description'],
            'image'       => $params['seo']['image'],
            'type'        => 'teller',
            'post_id'     => $fortuneteller->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 SaveDataEvent());

        return new FortunetellerResource($fortuneteller);
    }

    public function update($id = 0, Request $request)
    {
        $validator = Validator::make($request->all(), ['name' => ['required'], 'shop_id' => ['required'], 'is_activated' => ['required']]);
        if ($validator->fails()) return response()->json(['errors' => $validator->errors()], 403);

        $list = Fortuneteller::notDeleted()->where('id', $id);
        if ($this->_limitedByShop['hasLimited']) $list->whereIn('shop_id', $this->_limitedByShop['data']);
        if ($this->_limitedByOwner['hasLimited'] && $this->_limitedByAssign['hasLimited']) {
            $ownerAssignList = array_merge($this->_limitedByOwner['data'], $this->_limitedByAssign['data']);
            $list->whereIn('id', $ownerAssignList);
        } else if ($this->_limitedByOwner['hasLimited']) {
            $list->whereIn('id', $this->_limitedByOwner['data']);
        } else if ($this->_limitedByAssign['hasLimited']) {
            $list->whereIn('id', $this->_limitedByAssign['data']);
        }
        $fortuneteller = $list->first();

        if (!isset($fortuneteller)) return response()->json(['errors' => 'Fortuneteller is not valid'], 403);
        $params = $request->all();
        $slug = $fortuneteller->slug;
        if (!isset($params['slug']) || $params['slug'] == null || $params['slug'] == "") {
            $slug = $fortuneteller->number;
            do {
                $checkSlug = Fortuneteller::where('is_activated', 1)->where('is_deleted', 0)->where('slug', $slug)->where('id', '!=', $id)->count();
                if ($checkSlug > 0) $slug .= "-1";
            } while ($checkSlug > 0);
        } else if (isset($params['slug']) && Helper::slug($params['slug']) != $slug) {
            $slugNew = Helper::slug($params['slug']);
            $checkSlug = Fortuneteller::where('is_activated', 1)->where('is_deleted', 0)->where('slug', $slugNew)->where('id', '!=', $id)->count();
            if ($checkSlug > 0) {
                return response()->json(['data' => ['status' => 'error', 'message' => 'Slug is exits']], 200);
            } else {
                $slug = $slugNew;
            }
        } else {
            $slug = $fortuneteller->slug;
        }

        if ($params['avatar'] == null || $params['avatar'] == "") $params['avatar'] = "no-image.png";
        if ($params['avatar'] != null && $params['avatar'] != "" && $params['avatar'] != "no-image.png" && $fortuneteller->avatar != $params['avatar']) $this->generateFortuneThumb($params['avatar'], $this->_imagePath);

        $firstChar = mb_substr($params['name'], 0, 1, "UTF-8");
        $refName = RefName::where('name', $firstChar)->first();
        if ($refName == null || !isset($refName->id)) {
            $refName = RefName::create(['name' => $firstChar, 'created_at' => date('Y-m-d H:i:s'), 'updated_at' => date('Y-m-d H:i:s')]);
        }

        $insertData = [
            'name'                 => $params['name'],
            'slug'                 => $slug,
            'shop_id'              => $params['shop_id'],
            'display_name'         => $params['display_name'],
            'gender'               => (int)$params['gender'],
            'age'                  => ($params['age'] != '' && $params['age'] != null) ? $params['age'] : '',
            'phone_number'         => $params['phone_number'],
            'email'                => $params['email'],
            'address'              => $params['address'],
            'avatar'               => $params['avatar'],
            'desc_1_image'         => $params['desc_1_image'],
            'desc_1_title'         => ($params['desc_1_title'] != null && $params['desc_1_title'] != "") ? $params['desc_1_title'] : $params['name'],
            'desc_1_short'         => $params['desc_1_short'],
            'desc_1_full'          => $params['desc_1_full'],
            'desc_2_image'         => $params['desc_2_image'],
            'desc_2_title'         => $params['desc_2_title'],
            'desc_2_short'         => $params['desc_2_short'],
            'desc_2_full'          => $params['desc_2_full'],
            'cost'                 => $params['cost'],
            'consultation_minutes' => $params['consultation_minutes'],
            'performance'          => $params['performance'],
            'use_scry'             => $params['use_scry'],
            'consultation_genre'   => $params['consultation_genre'],
            'good_consultation'    => $params['good_consultation'],
            'commitment'           => $params['commitment'],
            'boom'                 => $params['boom'],
            'message'              => $params['message'],
            'message_image'        => $params['message_image'],
            'ref_name_id'          => $refName->id,
            'user_id'              => $fortuneteller->user_id == null || $fortuneteller->user_id == "" ? auth('api')->user()->id : $fortuneteller->user_id,
            'assigned_user_id'     => $params['assigned_user_id'],
            'show_top'             => ($params['show_top'] === true) ? 1 : 0,
            'is_popular'           => ($params['is_popular'] === true) ? 1 : 0,
            'is_activated'         => ($params['is_activated'] === true) ? 1 : 0,
            'updated_at'           => date('Y-m-d H:i:s')
        ];

        if ($fortuneteller->preview_code == null && $fortuneteller->preview_code == "") $insertData['preview_code'] = md5(Helper::generateRandomString(8));
        if (isset($params['category_id']) && $params['category_id'] != null && $params['category_id'] != '') {
            $insertData['category_id'] = $params['category_id'];
        }
        $fortuneteller->update($insertData);

        FortuneMeta::where('fortune_teller_id', $fortuneteller->id)->delete();
        if (isset($params['profile']) && is_array($params['profile'])) {
            $metaProfileData = [];
            foreach ($params['profile'] as $item) {
                $metaProfileData[] = [
                    'fortune_teller_id' => $fortuneteller->id,
                    'title'             => $item['title'],
                    'content'           => $item['content'],
                    'type'              => 'profile',
                    'created_at'        => date('Y-m-d H:i:s'),
                    'updated_at'        => date('Y-m-d H:i:s'),
                ];
            }
            if (count($metaProfileData) > 0) FortuneMeta::insert($metaProfileData);
        }
        if (isset($params['comment']) && is_array($params['comment'])) {
            $metaCommentData = [];
            foreach ($params['comment'] as $item) {
                $metaCommentData[] = [
                    'fortune_teller_id' => $fortuneteller->id,
                    'title'             => $item['title'],
                    'content'           => $item['content'],
                    'type'              => 'comment',
                    'created_at'        => date('Y-m-d H:i:s'),
                    'updated_at'        => date('Y-m-d H:i:s'),
                ];
            }
            if (count($metaCommentData) > 0) FortuneMeta::insert($metaCommentData);
        }

        if (isset($params['method']) && is_array($params['method'])) {
            FortunemethodDetail::where('fortune_teller_id', $fortuneteller->id)->delete();
            $fortunemethodDetailData = [];
            foreach ($params['method'] as $item) {
                $fortunemethodDetailData[] = [
                    'fortune_teller_id' => $fortuneteller->id,
                    'fortune_method_id' => $item,
                    'created_at'        => date('Y-m-d H:i:s'),
                    'updated_at'        => date('Y-m-d H:i:s'),
                ];
            }
            if (count($fortunemethodDetailData) > 0) FortunemethodDetail::insert($fortunemethodDetailData);
        }

        if (isset($params['consultation']) && is_array($params['consultation'])) {
            ConsultationDetail::where('fortune_teller_id', $fortuneteller->id)->delete();
            $consultationDetailData = [];
            foreach ($params['consultation'] as $item) {
                $consultationDetailData[] = [
                    'fortune_teller_id' => $fortuneteller->id,
                    'consultation_id'   => $item,
                    'created_at'        => date('Y-m-d H:i:s'),
                    'updated_at'        => date('Y-m-d H:i:s'),
                ];
            }
            if (count($consultationDetailData) > 0) ConsultationDetail::insert($consultationDetailData);
        }

        FortunetellerFile::where('fortune_teller_id', $fortuneteller->id)->where('type', 'slider')->delete();
        if (isset($params['slider']) && is_array($params['slider'])) {
            foreach ($params['slider'] as $item) {
                FortunetellerFile::create([
                    'fortune_teller_id' => $fortuneteller->id,
                    'file_name'         => $item,
                    'type'              => 'slider',
                    'created_at'        => date('Y-m-d H:i:s'),
                    'updated_at'        => date('Y-m-d H:i:s')
                ]);
            }
        }

        /*FortunetellerFile::where('fortune_teller_id', $fortuneteller->id)->where('type', 'gallery')->delete();
        if (isset($params['gallery']) && is_array($params['gallery'])) {
            foreach ($params['gallery'] as $item) {
                FortunetellerFile::create([
                    'fortune_teller_id' => $fortuneteller->id,
                    'file_name'         => $item['file_name'],
                    'type'              => 'gallery',
                    'created_at'        => date('Y-m-d H:i:s'),
                    'updated_at'        => date('Y-m-d H:i:s')
                ]);
            }
        }*/

        FortuneSchedule::where('fortune_teller_id', $fortuneteller->id)->delete();
        if (isset($params['schedule']) && is_array($params['schedule'])) {
            $insertSchedule = [];
            foreach ($params['schedule'] as $item) {
                $insertSchedule[] = [
                    'fortune_teller_id' => $fortuneteller->id,
                    'schedule_id'       => $item['id'],
                    'time_8'            => $item['time_8'],
                    'time_9'            => $item['time_9'],
                    'time_10'           => $item['time_10'],
                    'time_11'           => $item['time_11'],
                    'time_12'           => $item['time_12'],
                    'time_13'           => $item['time_13'],
                    'time_14'           => $item['time_14'],
                    'time_15'           => $item['time_15'],
                    'time_16'           => $item['time_16'],
                    'time_17'           => $item['time_17'],
                    'time_18'           => $item['time_18'],
                    'time_19'           => $item['time_19'],
                    'time_20'           => $item['time_20'],
                    'time_21'           => $item['time_21'],
                    'time_22'           => $item['time_22'],
                    'time_23'           => $item['time_23'],
                    'time_24'           => $item['time_24'],
                    'time_1'            => $item['time_1'],
                    'created_at'        => date('Y-m-d H:i:s'),
                    'updated_at'        => date('Y-m-d H:i:s')
                ];
            }
            FortuneSchedule::insert($insertSchedule);
        }

        FortuneReview::where('fortune_teller_id', $fortuneteller->id)->delete();
        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[] = [
                        'fortune_teller_id' => $fortuneteller->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')
                    ];
                }
            }
            FortuneReview::insert($insertReview);
        }

        ShopMeta::where('shop_id', $params['shop_id'])->delete();
        if (isset($params['info']) && is_array($params['info'])) {
            $metaInfoData = [];
            foreach ($params['info'] as $item) {
                $metaInfoData[] = [
                    'shop_id'    => $params['shop_id'],
                    'title'      => $item['title'],
                    'content'    => $item['content'],
                    '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['tags']) && is_array($params['tags'])) {
            KeywordDetail::where('ref_id', $fortuneteller->id)->where('type', 'teller')->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'     => $fortuneteller->id,
                    'type'       => 'teller',
                    '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);
        }

        /*'uri'         => '/fortune-teller/detail/' . $slug,
        'title'       => ($params['desc_1_title'] != null && $params['desc_1_title'] != "") ? $params['desc_1_title'] : $params['name'],
        'keywords'    => $params['desc_1_short'],
        'description' => $params['desc_1_full'],*/

        $metaSeo = Seo::where('post_id', $fortuneteller->id)->where('type', 'teller')->first();
        $seoData = [
            'uri'         => '/fortune-teller/detail/' . $slug,
            'title'       => ($params['seo']['title'] != null && $params['seo']['title'] != "") ? $params['seo']['title'] : $params['name'],
            'keywords'    => $params['seo']['keywords'],
            'description' => $params['seo']['description'],
            'image'       => $params['seo']['image'],
            'type'        => 'teller',
            'post_id'     => $fortuneteller->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 SaveDataEvent());

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

    public function destroy($id = '')
    {
        $list = Fortuneteller::notDeleted()->where('id', $id);
        if ($this->_limitedByShop['hasLimited']) $list->whereIn('shop_id', $this->_limitedByShop['data']);
        if ($this->_limitedByOwner['hasLimited'] && $this->_limitedByAssign['hasLimited']) {
            $ownerAssignList = array_merge($this->_limitedByOwner['data'], $this->_limitedByAssign['data']);
            $list->whereIn('id', $ownerAssignList);
        } else if ($this->_limitedByOwner['hasLimited']) {
            $list->whereIn('id', $this->_limitedByOwner['data']);
        } else if ($this->_limitedByAssign['hasLimited']) {
            $list->whereIn('id', $this->_limitedByAssign['data']);
        }
        $fortuneteller = $list->first();
        if (!isset($fortuneteller)) response()->json(['error' => 'Ehhh! Can not delete this category'], 403);

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

        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', []);

        $list = Fortuneteller::notDeleted()->whereIn('id', $listIds);
        if ($this->_limitedByShop['hasLimited']) $list->whereIn('shop_id', $this->_limitedByShop['data']);
        if ($this->_limitedByOwner['hasLimited'] && $this->_limitedByAssign['hasLimited']) {
            $ownerAssignList = array_merge($this->_limitedByOwner['data'], $this->_limitedByAssign['data']);
            $list->whereIn('id', $ownerAssignList);
        } else if ($this->_limitedByOwner['hasLimited']) {
            $list->whereIn('id', $this->_limitedByOwner['data']);
        } else if ($this->_limitedByAssign['hasLimited']) {
            $list->whereIn('id', $this->_limitedByAssign['data']);
        }
        $fortunetellerList = $list->get();
        if ($fortunetellerList->count() <= 0) response()->json(['error' => 'Fortuneteller is not valid.'], 403);
        try {
            Fortuneteller::notDeleted()->whereIn('id', $listIds)->update(['is_deleted' => true]);
        } catch (\Exception $ex) {
            response()->json(['error' => $ex->getMessage()], 403);
        }
        event(new SaveDataEvent());

        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', []);
        $list = Fortuneteller::notDeleted()->whereIn('id', $listIds);
        if ($this->_limitedByShop['hasLimited']) $list->whereIn('shop_id', $this->_limitedByShop['data']);
        if ($this->_limitedByOwner['hasLimited'] && $this->_limitedByAssign['hasLimited']) {
            $ownerAssignList = array_merge($this->_limitedByOwner['data'], $this->_limitedByAssign['data']);
            $list->whereIn('id', $ownerAssignList);
        } else if ($this->_limitedByOwner['hasLimited']) {
            $list->whereIn('id', $this->_limitedByOwner['data']);
        } else if ($this->_limitedByAssign['hasLimited']) {
            $list->whereIn('id', $this->_limitedByAssign['data']);
        }
        $fortunetellerList = $list->get();

        if ($fortunetellerList->count() <= 0) response()->json(['error' => 'Fortuneteller is not valid.'], 403);
        try {
            Fortuneteller::notDeleted()->whereIn('id', $listIds)->update(['is_activated' => true]);
        } catch (\Exception $ex) {
            response()->json(['error' => $ex->getMessage()], 403);
        }
        event(new SaveDataEvent());

        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', []);
        $list = Fortuneteller::notDeleted()->whereIn('id', $listIds);
        if ($this->_limitedByShop['hasLimited']) $list->whereIn('shop_id', $this->_limitedByShop['data']);
        if ($this->_limitedByOwner['hasLimited'] && $this->_limitedByAssign['hasLimited']) {
            $ownerAssignList = array_merge($this->_limitedByOwner['data'], $this->_limitedByAssign['data']);
            $list->whereIn('id', $ownerAssignList);
        } else if ($this->_limitedByOwner['hasLimited']) {
            $list->whereIn('id', $this->_limitedByOwner['data']);
        } else if ($this->_limitedByAssign['hasLimited']) {
            $list->whereIn('id', $this->_limitedByAssign['data']);
        }
        $fortunetellerList = $list->get();
        if ($fortunetellerList->count() <= 0) response()->json(['error' => 'Fortuneteller is not valid.'], 403);
        try {
            Fortuneteller::notDeleted()->whereIn('id', $listIds)->update(['is_activated' => false]);
        } catch (\Exception $ex) {
            response()->json(['error' => $ex->getMessage()], 403);
        }
        event(new SaveDataEvent());

        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)
    {
        $fortune = Fortuneteller::where('id', $id)->where('is_deleted', false)->first();
        if (isset($fortune)) {
            $setStatus = ($fortune->show_top == true || $fortune->show_top == 0) ? 1 : 0;
            $fortune->update(['show_top' => $setStatus]);
        }
        event(new SaveDataEvent());

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

    private function generateFortuneThumb($name, $path)
    {
        $filePath = public_path('uploads/files/');
        $key = "87252hahagawbj";
        $webpFile = str_replace(".jpg" . $key, "", $name . $key);
        $webpFile = str_replace(".png" . $key, "", $webpFile);
        $webpFile = str_replace(".jpeg" . $key, "", $webpFile);
        $webpFile = str_replace(".PNG" . $key, "", $webpFile);
        $webpFile = str_replace(".JPG" . $key, "", $webpFile);
        $webpFile = str_replace(".JPEG" . $key, "", $webpFile);
        $webpFile .= ".webp";
        if (!file_exists($filePath . $webpFile)) ImageCross::make($filePath . $name)->encode('webp', 90)->save($filePath . $webpFile);

        $this->genThumb($name, 60, 60);
        $this->genThumb($name, 90, 50);
        $this->genThumb($name, 100, 60);
        $this->genThumb($name, 170, 230);
        $this->genThumb($name, 205, 205);
        $this->genThumb($name, 260, 356);
        $this->genThumb($name, 'auto', 260);
        $this->genThumb($name, 460, 360);
    }

    private function genThumb($fileName, $width, $height) {
        $filePath = public_path('uploads/files/');
        $key = "87252hahagawbj";

        $extension = "." . $this->fileExtension($fileName);
        $baseName = basename($fileName);
        $baseName = str_replace($extension . $key, "", $baseName . $key);
        $nameFile = $baseName . "_" . $width . "x" . $height . $extension;

        if (!file_exists($filePath . $nameFile)) {
            $imgCross = ImageCross::make($filePath . $fileName)->orientate();
            if ($width == "auto" && is_numeric($height)) {
                $imgCross->fit(null, $height, function ($constraint) {
                    $constraint->upsize();
                })->save($filePath . $nameFile);
            } else if ($height == "auto" && is_numeric($width)) {
                $imgCross->fit($width, null, function ($constraint) {
                    $constraint->upsize();
                })->save($filePath . $nameFile);
            } else {
                $imgCross->fit($width, $height, function ($constraint) {
                    $constraint->upsize();
                })->save($filePath . $nameFile);
            }
        }

        $webpFile = str_replace(".jpg" . $key, "", $nameFile . $key);
        $webpFile = str_replace(".png" . $key, "", $webpFile);
        $webpFile = str_replace(".jpeg" . $key, "", $webpFile);
        $webpFile = str_replace(".PNG" . $key, "", $webpFile);
        $webpFile = str_replace(".JPG" . $key, "", $webpFile);
        $webpFile = str_replace(".JPEG" . $key, "", $webpFile);
        $webpFile .= ".webp";

        if (!file_exists($filePath . $webpFile)) {
            ImageCross::make($filePath . $nameFile)->encode('webp', 90)->save($filePath . $webpFile);
        }
    }

    private function fileExtension($s)
    {
        $n = strrpos($s, ".");
        return ($n === false) ? "" : substr($s, $n + 1);
    }
}
