<?php

namespace App\Http\Controllers\Admin;

use App\Fortuneteller;
use App\Helpers\Helper;
use App\Http\Controllers\Controller;
use App\RuleCustom;
use App\Shop;
use App\User;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Arr;
use App\Article;
use App\Http\Resources\Admin\ArticleResource;
use Validator;
use Auth;

/**
 * Class ArticleController
 *
 * @package App\Http\Controllers
 */
class ArticleController extends Controller
{
    const ITEM_PER_PAGE = 20;
    private $_pathFile;
    private $_pathTemp;
    private $_limitedArticleByShop;
    private $_limitedArticleByOwner;

    public function __construct()
    {
        $this->_pathFile = public_path('uploads/image/article/');
        $this->_pathTemp = storage_path('app/public/uploads/temp/image/');
        $this->_limitedArticleByShop = ['hasLimited' => false, 'data' => []];
        $this->_limitedArticleByOwner = ['hasLimited' => false, 'data' => []];

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

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

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

        if (!empty($keyword)) {
            $list->where('title', 'LIKE', '%' . $keyword . '%');
        }
        if ($status != '') {
            $list->where('is_activated', $status);
        }
        if ($this->_limitedArticleByShop['hasLimited']) {
            $list->whereIn('shop_id', $this->_limitedArticleByShop['data']);
        }
        if ($this->_limitedArticleByOwner['hasLimited']) {
            $list->whereIn('id', $this->_limitedArticleByOwner['data']);
        }
        $list->orderBy('id', 'DESC');

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

    public function all()
    {
        $list = Article::select('id', 'title', 'slug')->notDeleted();
        if ($this->_limitedArticleByShop['hasLimited']) $list->whereIn('shop_id', $this->_limitedArticleByShop['data']);
        if ($this->_limitedArticleByOwner['hasLimited']) $list->whereIn('id', $this->_limitedArticleByOwner['data']);

        $list->orderBy('id');

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

    public function show($id = 0)
    {
        $list = Article::notDeleted()->where('id', $id);
        if ($this->_limitedArticleByShop['hasLimited']) $list->whereIn('shop_id', $this->_limitedArticleByShop['data']);
        if ($this->_limitedArticleByOwner['hasLimited']) $list->whereIn('id', $this->_limitedArticleByOwner['data']);
        $article = $list->first();

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

        return new ArticleResource($article);
    }

    public function store(Request $request)
    {
        $validator = Validator::make($request->all(), ['title' => ['required'], 'is_activated' => ['required']]);
        if ($validator->fails()) return response()->json(['errors' => $validator->errors()], 403);
        $params = $request->all();
        $publishAt = (isset($params['publish_at']) && $params['publish_at'] != null && $params['publish_at'] != '') ? Carbon::parse($params['publish_at'])->format('Y-m-d H:i:s') : date('Y-m-d H:i:s');
        $content = $params['content'];
        $content = str_replace("../../../../uploads/image", "/uploads/image", $content);
        $content = str_replace("../../../uploads/image", "/uploads/image", $content);
        $content = str_replace("../../uploads/image", "/uploads/image", $content);
        $content = str_replace("../uploads/image", "/uploads/image", $content);
        $slug = Helper::slug($params['slug']);
        if (empty($slug)) $slug = Helper::slug($params['title']);

        $previewCode = null;
        if ($params['is_activated'] != true || $params['is_activated'] != "true" || $params['is_activated'] != 1) $previewCode = md5(rand(0, 1000) . date('Y-m-dH:i:s'));

        $article = Article::create([
            'title'             => $params['title'],
            'slug'              => $slug,
            'description'       => $params['description'],
            'content'           => $content,
            'thumbnail'         => $params['thumbnail'],
            'category_id'       => $params['category_id'],
            'shop_id'           => $params['shop_id'],
            'fortune_teller_id' => $params['fortune_teller_id'],
            'keyword'           => $params['keyword'],
            'tag'               => $params['tag'],
            'important'         => $params['important'],
            'publish_at'        => $publishAt,
            'user_id'           => Auth::user()->id,
            'preview'           => $previewCode,
            'is_published'      => ($params['is_activated'] === 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')
        ]);

        $fileName = trim($params['thumbnail']);
        if ($fileName != null && $fileName != '' && file_exists($this->_pathTemp . $fileName)) rename($this->_pathTemp . $fileName, $this->_pathFile . $fileName);

        if ($params['shop_id'] !== "" && $params['shop_id'] !== null) {
            Shop::where('id', $params['shop_id'])->update(['interview_url' => url('article/' . $slug)]);
        }

        return new ArticleResource($article);
    }

    public function update($id = 0, Request $request)
    {
        $validator = Validator::make($request->all(), ['title' => ['required'], 'is_activated' => ['required']]);
        if ($validator->fails()) return response()->json(['errors' => $validator->errors()], 403);
        $list = Article::notDeleted()->where('id', $id);
        if ($this->_limitedArticleByShop['hasLimited']) $list->whereIn('shop_id', $this->_limitedArticleByShop['data']);
        if ($this->_limitedArticleByOwner['hasLimited']) $list->whereIn('id', $this->_limitedArticleByOwner['data']);
        $article = $list->first();

        if (!isset($article)) return response()->json(['errors' => 'Article is not valid'], 403);
        $params = $request->all();
        $publishAt = (isset($params['publish_at']) && $params['publish_at'] != null && $params['publish_at'] != '') ? Carbon::parse($params['publish_at'])->format('Y-m-d H:i:s') : date('Y-m-d H:i:s');
        $thumb = $article->thumbnail;
        $fileName = trim($params['thumbnail']);
        if ($fileName != null && $fileName != '' && $fileName != $thumb) {
            if (file_exists($this->_pathTemp . $fileName)) rename($this->_pathTemp . $fileName, $this->_pathFile . $fileName);
            $thumb = $fileName;
        } else {
            if (isset($params['remove_thumbnail']) && ($params['remove_thumbnail'] == true || $params['remove_thumbnail'] == "true")) {
                $thumb = null;
            }
        }
        $content = $params['content'];
        $content = str_replace("../../../../uploads/image", "/uploads/image", $content);
        $content = str_replace("../../../uploads/image", "/uploads/image", $content);
        $content = str_replace("../../uploads/image", "/uploads/image", $content);
        $content = str_replace("../uploads/image", "/uploads/image", $content);
        $slug = Helper::slug($params['slug']);
        if (empty($slug)) $slug = Helper::slug($params['title']);

        $previewCode = $article->preview;
        if ($params['is_activated'] != true || $params['is_activated'] != "true" || $params['is_activated'] != 1) {
            if ($previewCode == null || $previewCode == "") $previewCode = md5(rand(0, 1000) . date('Y-m-dH:i:s'));
        }

        $article->update([
            'title'             => $params['title'],
            'slug'              => $slug,
            'description'       => $params['description'],
            'content'           => $content,
            'thumbnail'         => $thumb,
            'category_id'       => $params['category_id'],
            'shop_id'           => $params['shop_id'],
            'fortune_teller_id' => $params['fortune_teller_id'],
            'keyword'           => $params['keyword'],
            'tag'               => $params['tag'],
            'important'         => $params['important'],
            'publish_at'        => $publishAt,
            /*'user_id'           => Auth::user()->id,*/
            'preview'           => $previewCode,
            'is_published'      => ($params['is_activated'] === true) ? 1 : 0,
            'is_activated'      => ($params['is_activated'] === true) ? 1 : 0,
            'updated_at'        => date('Y-m-d H:i:s')
        ]);

        if ($params['shop_id'] !== "" && $params['shop_id'] !== null) {
            Shop::where('id', $params['shop_id'])->update(['interview_url' => url('article/' . $slug)]);
        }

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

    public function destroy($id = 0)
    {
        $list = Article::notDeleted()->where('id', $id);
        if ($this->_limitedArticleByShop['hasLimited']) $list->whereIn('shop_id', $this->_limitedArticleByShop['data']);
        if ($this->_limitedArticleByOwner['hasLimited']) $list->whereIn('id', $this->_limitedArticleByOwner['data']);
        $article = $list->first();
        if (!isset($article)) response()->json(['error' => 'Ehhh! Can not delete this category'], 403);

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

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

    public function destroyMultiple(Request $request)
    {
        $validator = Validator::make($request->all(), ['ids' => 'required']);
        if ($validator->fails()) return response()->json(['errors' => $validator->errors()], 403);
        $listIds = $request->get('ids', []);
        $list = Article::notDeleted()->whereIn('id', $listIds);
        if ($this->_limitedArticleByShop['hasLimited']) $list->whereIn('shop_id', $this->_limitedArticleByShop['data']);
        if ($this->_limitedArticleByOwner['hasLimited']) $list->whereIn('id', $this->_limitedArticleByOwner['data']);
        $articleList = $list->get();

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

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

    public function activateMultiple(Request $request)
    {
        $validator = Validator::make($request->all(), ['ids' => 'required']);
        if ($validator->fails()) return response()->json(['errors' => $validator->errors()], 403);
        $listIds = $request->get('ids', []);
        $list = Article::notDeleted()->whereIn('id', $listIds);
        if ($this->_limitedArticleByShop['hasLimited']) $list->whereIn('shop_id', $this->_limitedArticleByShop['data']);
        if ($this->_limitedArticleByOwner['hasLimited']) $list->whereIn('id', $this->_limitedArticleByOwner['data']);
        $articleList = $list->get();

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

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

    public function deactivateMultiple(Request $request)
    {
        $validator = Validator::make($request->all(), ['ids' => 'required']);
        if ($validator->fails()) return response()->json(['errors' => $validator->errors()], 403);
        $listIds = $request->get('ids', []);
        $list = Article::notDeleted()->whereIn('id', $listIds);
        if ($this->_limitedArticleByShop['hasLimited']) $list->whereIn('shop_id', $this->_limitedArticleByShop['data']);
        if ($this->_limitedArticleByOwner['hasLimited']) $list->whereIn('id', $this->_limitedArticleByOwner['data']);
        $articleList = $list->get();

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

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

    public function uploadImage(Request $request)
    {
        if ($request->hasFile('image')) {
            $file = $request->file('image');
            $baseName = $file->getClientOriginalName();
            $fileName = md5($baseName . rand(1111, 9999) . date('YmdHis')) . '.' . $file->getClientOriginalExtension();
            $file->move($this->_pathTemp, $fileName);
            chmod($this->_pathTemp . $fileName, 0777);
            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 uploadImages(Request $request)
    {
        if ($request->hasFile('file')) {
            $file = $request->file('file');
            $baseName = $file->getClientOriginalName();
            $fileName = md5($baseName . rand(1111, 9999) . date('YmdHis')) . '.' . $file->getClientOriginalExtension();
            $file->move($this->_pathFile, $fileName);
            chmod($this->_pathFile . $fileName, 0777);
            return response()->json(['hasSuccess' => true, 'message' => 'Upload Success.', 'file_name' => $fileName, 'baseName' => $baseName, 'files' => ['file' => $fileName]], 200);
        }

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