<?php

namespace App\Http\Controllers\Admin;

use App\TemplateAttachment;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Arr;
use App\Template;
use App\Http\Resources\Admin\TemplateResource;
use Validator;

/**
 * Class TemplateController
 *
 * @package App\Http\Controllers
 */
class TemplateController extends Controller
{
	const ITEM_PER_PAGE = 20;
	
	public function index(Request $request)
	{
		$searchParams = $request->all();
		$list = Template::notDeleted();
		$limit = Arr::get($searchParams, 'limit', static::ITEM_PER_PAGE);
		$keyword = Arr::get($searchParams, 'keyword', '');
		$status = Arr::get($searchParams, 'status', '');
		
		if (!empty($keyword)) {
			$list->where('name', 'LIKE', '%' . $keyword . '%');
		}
		if ($status != '') {
			$list->where('is_activated', $status);
		}
		$list->orderBy('id');
		
		return TemplateResource::collection($list->paginate($limit));
	}
	
	public function all(Request $request)
	{
		$searchParams = $request->all();
		$limit = Arr::get($searchParams, 'limit', static::ITEM_PER_PAGE);
		$list = Template::select('*')->notDeleted()->orderBy('id');
		
		return TemplateResource::collection($list->paginate($limit));
	}
	
	public function show($id = 0)
	{
		$template = Template::notDeleted()->where('id', $id)->first();
		if (!isset($template)) return response()->json(['errors' => 'Template is not valid'], 403);
		
		return new TemplateResource($template);
	}
	
	public function store(Request $request)
	{
		$validator = Validator::make($request->all(), [
			'name'         => ['required'],
			'type'         => ['required'],
			'title'        => ['required'],
			'content'      => ['required'],
			'group'        => ['required'],
			'is_activated' => ['required']
		]);
		if ($validator->fails()) return response()->json(['errors' => $validator->errors()], 403);
		$params = $request->all();
		
		$check = Template::notDeleted()->where('name', $params['name'])->first();
		if ($check) return response()->json(['errors' => 'Template already exists.'], 403);
		
		$template = Template::create([
			'name'         => $params['name'],
			'type'         => $params['type'],
			'description'  => $params['description'],
			'title'        => $this->_snippetCodeFormat($params['title']),
			'content'      => $this->_snippetCodeFormat($params['content']),
			'group'        => $params['group'],
			'user_id'      => auth('api')->user()->id,
			'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['attachments'])) {
			$insertData = [];
			foreach ($params['attachments'] as $item) {
				$insertData[] = [
					'template_id'    => $template->id,
					'title'          => $item['baseName'],
					'file_name'      => $item['file_name'],
					'file_type'      => $item['type'],
					'file_size'      => $item['size'],
					'file_extension' => $item['extension'],
					'created_at'     => date('Y-m-d H:i:s'),
					'updated_at'     => date('Y-m-d H:i:s')
				];
			}
			if (count($insertData) > 0) TemplateAttachment::insert($insertData);
		}
		
		return new TemplateResource($template);
	}
	
	public function update(Request $request, $id = 0)
	{
		$validator = Validator::make($request->all(), [
			'name'         => ['required'],
			'type'         => ['required'],
			'title'        => ['required'],
			'content'      => ['required'],
			'group'        => ['required'],
			'is_activated' => ['required']
		]);
		if ($validator->fails()) return response()->json(['errors' => $validator->errors()], 403);
		$template = Template::notDeleted()->where('id', $id)->first();
		if (!isset($template)) return response()->json(['errors' => 'Template is not valid'], 403);
		$params = $request->all();
		
		$check = Template::notDeleted()->where('id', '!=', $id)->where('name', $params['name'])->first();
		if ($check) return response()->json(['errors' => 'Template already exists.'], 403);
		
		$template->update([
			'name'         => $params['name'],
			'type'         => $params['type'],
			'description'  => $params['description'],
			'title'        => $this->_snippetCodeFormat($params['title']),
			'content'      => $this->_snippetCodeFormat($params['content']),
			'group'        => $params['group'],
			'user_id'      => auth('api')->user()->id,
			'is_activated' => ($params['is_activated'] === true) ? 1 : 0,
			'updated_at'   => date('Y-m-d H:i:s')
		]);
		
		if (isset($params['attachments'])) {
			TemplateAttachment::where('template_id', $template->id)->delete();
			$insertData = [];
			foreach ($params['attachments'] as $item) {
				$insertData[] = [
					'template_id'    => $template->id,
					'title'          => $item['baseName'],
					'file_name'      => $item['file_name'],
					'file_type'      => $item['type'],
					'file_size'      => $item['size'],
					'file_extension' => $item['extension'],
					'created_at'     => date('Y-m-d H:i:s'),
					'updated_at'     => date('Y-m-d H:i:s')
				];
			}
			if (count($insertData) > 0) TemplateAttachment::insert($insertData);
		}
		
		return response()->json(null, 204);
	}
	
	public function destroy($id = 0)
	{
		$template = Template::notDeleted()->where('id', $id)->first();
		if (!isset($template)) response()->json(['error' => 'Ehhh! Can not delete this template'], 403);
		
		try {
			$template->update(['is_deleted' => true, 'updated_at' => date('Y-m-d H:i:s')]);
		} 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', []);
		$templates = Template::notDeleted()->whereIn('id', $listIds)->get();
		if ($templates->count() <= 0) response()->json(['error' => 'Template is not valid.'], 403);
		try {
			Template::notDeleted()->whereIn('id', $listIds)->update(['is_deleted' => true, 'updated_at' => date('Y-m-d H:i:s')]);
		} 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', []);
		$templates = Template::notDeleted()->whereIn('id', $listIds)->get();
		if ($templates->count() <= 0) response()->json(['error' => 'Template is not valid.'], 403);
		try {
			Template::notDeleted()->whereIn('id', $listIds)->update(['is_activated' => true, 'updated_at' => date('Y-m-d H:i:s')]);
		} 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', []);
		$templates = Template::notDeleted()->whereIn('id', $listIds)->get();
		if ($templates->count() <= 0) response()->json(['error' => 'Template is not valid.'], 403);
		try {
			Template::notDeleted()->whereIn('id', $listIds)->update(['is_activated' => false, 'updated_at' => date('Y-m-d H:i:s')]);
		} catch (\Exception $ex) {
			response()->json(['error' => $ex->getMessage()], 403);
		}
		
		return response()->json(null, 204);
	}
	
	private function _snippetCodeFormat($str)
	{
		if (preg_match_all('/{{(.*?)}}/', $str, $match) !== false) {
			$list = [];
			foreach ($match[0] as $mItem) {
				$fixed = str_replace("&nbsp;", " ", $mItem);
				$fixed = preg_replace('!\s+!', ' ', $fixed);
				$fixed = preg_replace('/_+/', '_', $fixed);
				
				$fixed = str_replace(" _ ", "", $fixed);
				$fixed = str_replace(" _", "", $fixed);
				$fixed = str_replace("_ ", "", $fixed);
				
				$fixed = str_replace("{{_", "{{", $fixed);
				$fixed = str_replace("_}}", "}}", $fixed);
				
				$fixed = str_replace("{{ ", "{{", $fixed);
				$fixed = str_replace(" }}", "}}", $fixed);
				$fixed = str_replace(" ", "_", $fixed);
				
				$fixed = strtolower($fixed);
				$fixed = str_replace("{{", "{{ ", $fixed);
				$fixed = str_replace("}}", " }}", $fixed);
				$list[] = ['origin' => $mItem, 'converted' => $fixed];
			}
			
			foreach ($list as $lItem) {
				$str = str_replace($lItem['origin'], $lItem['converted'], $str);
			}
		}
		
		return $str;
	}
}
