<?php

namespace App\Http\Controllers\Admin;

use App\Category;
use App\CategoryDetail;
use App\Events\SaveDataEvent;
use App\Gutenberg;
use App\Helpers\Helper;
use App\Http\Controllers\Controller;
use App\Keyword;
use App\KeywordDetail;
use App\Seo;
use App\SeoFormat;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Arr;
use App\Article;
use App\Http\Resources\Admin\ArticleResource;
use Illuminate\Support\Facades\Artisan;
use Validator;
use Auth;

/**
 * Class ArticleController
 *
 * @package App\Http\Controllers
 */
class QuestionController extends Controller
{
    const ITEM_PER_PAGE = 20;
    const POST_TYPE = 'question';
    protected $_pathFile;
    protected $_pathTemp;

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

    public function index(Request $request)
    {
        $searchParams = $request->all();
        $list = Article::notDeleted()->where('type', static::POST_TYPE);
        $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);
        }
        $list->orderBy('id', 'DESC');

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

    public function all()
    {
        $list = Article::select('id', 'title', 'slug')->notDeleted()->where('type', static::POST_TYPE)->orderBy('id');

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

    public function show($id = 0)
    {
        $article = Article::notDeleted()->where('id', $id)->where('type', static::POST_TYPE)->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'];
        $params['editor'] = "tinymce";
        //$params['gu_content'] = null;

        $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);
        $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('<h2></h2>', '<p>&nbsp;</p>', $content);
        $content = str_replace('<h2>&nbsp;</h2>', '<p>&nbsp;</p>', $content);
        $content = str_replace('<h2>&nbsp;&nbsp;</h2>', '<p>&nbsp;</p>', $content);
        $content = str_replace('<h2>&nbsp;&nbsp;&nbsp;</h2>', '<p>&nbsp;</p>', $content);
        $content = str_replace('<h2>&nbsp;&nbsp;&nbsp;&nbsp;</h2>', '<p>&nbsp;</p>', $content);
        $content = str_replace('href="../', 'href="/', $content);
        $content = str_replace('href="fortune-teller/', 'href="/fortune-teller/', $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'));
        $question_status = (trim($content) != "" && ($params['is_activated'] == true || $params['is_activated'] == 1)) ? 1 : 0;
        $author = $params['user_id'];
        if ($author == null || $author == 0 || $author == "") $author = auth('api')->user()->id;

        $createdBy = trim($params['created_by']);
        if ($createdBy == null || $createdBy == "" || $createdBy == "null") {
            $createdBy = auth('api')->user()->id;
        }

        $article = Article::create([
            'title'             => $params['title'],
            'slug'              => $slug,
            'description'       => $params['description'],
            'editor'            => $params['editor'],
            'gu_content'        => $params['gu_content'],
            'content'           => $content,
            'thumbnail'         => $params['thumbnail'],
            'shop_id'           => $params['shop_id'],
            'fortune_teller_id' => $params['fortune_teller_id'],
            'important'         => $params['important'],
            'publish_at'        => $publishAt,
            'created_by'        => $createdBy,
            'user_id'           => $author,
            'preview'           => $previewCode,
            'type'              => static::POST_TYPE,
            'question_status'   => $question_status,
            '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')
        ]);

        if (isset($params['category']) && $params['category'] != null) {
            $insertCategory = [];
            foreach ($params['category'] as $item) {
                if ($item == "" || $item == null) continue;
                $insertCategory[] = ['article_id' => $article->id, 'category_id' => $item, 'created_at' => date('Y-m-d H:i:s'), 'updated_at' => date('Y-m-d H:i:s')];
            }
            if (count($insertCategory) > 0) CategoryDetail::insert($insertCategory);
        }

        $keywordsStr = "";
        if (isset($params['keyword']) && is_array($params['keyword'])) {
            $keywords = [];
            foreach ($params['keyword'] 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'     => $article->id,
                    'type'       => 'article',
                    'created_at' => date('Y-m-d H:i:s'),
                    'updated_at' => date('Y-m-d H:i:s'),
                ];

                $keywordsStr .= $tag . ', ';
            }
            if (count($keywords) > 0) KeywordDetail::insert($keywords);
        }

        $this->updateSeoInfo($article->id, $params['title'], $slug, $keywordsStr, $params['description']);
        Artisan::call('cache:clear');

        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);
        $article = Article::notDeleted()->where('id', $id)->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');
        $content = $params['content'];
        $params['editor'] = "tinymce";
        //$params['gu_content'] = null;

        $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);
        $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('<h2></h2>', '<p>&nbsp;</p>', $content);
        $content = str_replace('<h2>&nbsp;</h2>', '<p>&nbsp;</p>', $content);
        $content = str_replace('<h2>&nbsp;&nbsp;</h2>', '<p>&nbsp;</p>', $content);
        $content = str_replace('<h2>&nbsp;&nbsp;&nbsp;</h2>', '<p>&nbsp;</p>', $content);
        $content = str_replace('<h2>&nbsp;&nbsp;&nbsp;&nbsp;</h2>', '<p>&nbsp;</p>', $content);
        $content = str_replace('href="../', 'href="/', $content);
        $content = str_replace('href="fortune-teller/', 'href="/fortune-teller/', $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'));
        }
        $question_status = (trim($content) != "" && ($params['is_activated'] == true || $params['is_activated'] == 1)) ? 1 : 3;
        $author = $params['user_id'];
        if ($author == null || $author == 0 || $author == "") $author = auth('api')->user()->id;

        $createdBy = $article->created_by;
        if ($params['created_by'] != null && $params['created_by'] != "" && $params['created_by'] != "null") {
            $createdBy = trim($params['created_by']);
        }
        if ($createdBy == null || $createdBy == "" || $createdBy == "null") {
            $createdBy = auth('api')->user()->id;
        }

        $article->update([
            'title'             => $params['title'],
            'slug'              => $slug,
            'description'       => $params['description'],
            'editor'            => $params['editor'],
            'gu_content'        => $params['gu_content'],
            'content'           => $content,
            'thumbnail'         => $params['thumbnail'],
            'shop_id'           => $params['shop_id'],
            'fortune_teller_id' => $params['fortune_teller_id'],
            'important'         => $params['important'],
            'publish_at'        => $publishAt,
            'created_by'        => $createdBy,
            'user_id'           => $author,
            'preview'           => $previewCode,
            'type'              => static::POST_TYPE,
            'question_status'   => $question_status,
            '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 ($article->user_id == null || $article->user_id == '') $article->update(['user_id' => auth('api')->user()->id]);

        CategoryDetail::where('article_id', $article->id)->delete();
        if (isset($params['category']) && $params['category'] != null) {
            $insertCategory = [];
            foreach ($params['category'] as $item) {
                if ($item == "" || $item == null) continue;
                $cateCheck = Category::where('is_activated', true)->where('is_deleted', false)->where('id', $item)->count();
                if ($cateCheck > 0) $insertCategory[] = ['article_id' => $article->id, 'category_id' => $item, 'created_at' => date('Y-m-d H:i:s'), 'updated_at' => date('Y-m-d H:i:s')];
            }
            if (count($insertCategory) > 0) CategoryDetail::insert($insertCategory);
        }

        $keywordsStr = "";
        if (isset($params['keyword']) && is_array($params['keyword'])) {
            KeywordDetail::where('ref_id', $article->id)->where('type', 'article')->delete();
            $keywords = [];
            foreach ($params['keyword'] 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'     => $article->id,
                    'type'       => 'article',
                    'created_at' => date('Y-m-d H:i:s'),
                    'updated_at' => date('Y-m-d H:i:s'),
                ];

                $keywordsStr .= $tag . ', ';
            }
            if (count($keywords) > 0) KeywordDetail::insert($keywords);
        }

        $this->updateSeoInfo($article->id, $params['title'], $slug, $keywordsStr, $params['description']);
        Artisan::call('cache:clear');

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

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

        try {
            $article->update(['is_deleted' => true]);
            Seo::where('uri', 'like', "/bbs/detail/" . $article->id . "/%")->delete();
            /*event(new SaveDataEvent());*/
            Artisan::call('cache:clear');
        } 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', []);
        $articleList = Article::notDeleted()->whereIn('id', $listIds)->where('type', static::POST_TYPE)->get();

        if ($articleList->count() <= 0) response()->json(['error' => 'Article is not valid.'], 403);
        try {
            Article::notDeleted()->whereIn('id', $listIds)->where('type', static::POST_TYPE)->update(['is_deleted' => true]);
            foreach ($listIds as $pId) {
                Seo::where('uri', 'like', "/bbs/detail/" . $pId . "/%")->delete();
            }
            /*event(new SaveDataEvent());*/
            Artisan::call('cache:clear');
        } 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', []);
        $articleList = Article::notDeleted()->whereIn('id', $listIds)->where('type', static::POST_TYPE)->get();

        if ($articleList->count() <= 0) response()->json(['error' => 'Article is not valid.'], 403);
        try {
            Article::notDeleted()->whereIn('id', $listIds)->where('type', static::POST_TYPE)->update(['is_activated' => true]);
            /*event(new SaveDataEvent());*/
        } 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', []);
        $articleList = Article::notDeleted()->whereIn('id', $listIds)->where('type', static::POST_TYPE)->get();

        if ($articleList->count() <= 0) response()->json(['error' => 'Article is not valid.'], 403);
        try {
            Article::notDeleted()->whereIn('id', $listIds)->where('type', static::POST_TYPE)->update(['is_activated' => false]);
            /*event(new SaveDataEvent());*/
        } 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);
    }

    private function updateSeoInfo($postId, $postTitle, $slug, $keywords, $postContent) {
        Seo::where('uri', 'like', "/bbs/detail/" . $postId . "/%")->delete();
        Seo::create([
            'uri'         => '/bbs/detail/' . $postId . '/' . $slug,
            'title'       => $postTitle . " | 掲示板 | " . config('settings.site_name'),
            'keywords'    => $keywords,
            'description' => $postContent,
            'type'        => 'bbs',
            'post_id'     => $postId,
            'created_at'  => date('Y-m-d H:i:s'),
            'updated_at'  => date('Y-m-d H:i:s'),
        ]);
    }

    private function gutenbergRenderContent($content) {
        $renderContent = $content;
        try {
            $gutenberg = new Gutenberg();
            $gutenberg->lb_content = $content;
            $gutenberg->save();
            $renderContent = $gutenberg->lb_content;
            $gutenberg->delete();
        } catch (\Exception $exception) {
            logger($exception->getMessage());
        }

        return $renderContent;
    }
}
