<?php

namespace App\Http\Controllers\Admin;

use App\Customer;
use App\Http\Controllers\Controller;
use App\ReportDetail;
use App\User;
use App\UserNotify;
use App\Events\NotifyUserEvent;
use Barryvdh\DomPDF\Facade\Pdf;
use Illuminate\Http\Request;
use Illuminate\Support\Arr;
use Carbon\Carbon;
use App\Report;
use App\Http\Resources\Admin\ReportResource;
use Validator;

/**
 * Class ReportController
 *
 * @package App\Http\Controllers
 */
class ReportController extends Controller
{
	const ITEM_PER_PAGE = 100;
	
	public function index(Request $request)
	{
		$searchParams = $request->all();
		$list = Report::notDeleted();
		$limit = Arr::get($searchParams, 'limit', static::ITEM_PER_PAGE);
		$keyword = Arr::get($searchParams, 'keyword', '');
		$status = Arr::get($searchParams, 'status', '');
		
		$keyword = str_replace("#", "", $keyword);
		$keyword = str_replace("-", "", $keyword);
		if (!empty($keyword)) {
			$userIds = User::where('full_name', 'LIKE', '%' . $keyword . '%')->pluck('id')->toArray();
			$customerIds = Customer::where('name', 'LIKE', '%' . $keyword . '%')->pluck('id')->toArray();
			$list->where(function ($query) use ($keyword, $userIds, $customerIds) {
				$query->where('id', 'LIKE', '%' . $keyword . '%')
					->orWhere('code', 'LIKE', '%' . $keyword . '%')
					->orWhere('report_date', 'LIKE', '%' . $keyword . '%');
				
				if (count($userIds) > 0) {
					$query->orWhereIn('user_id', $userIds);
				}
				
				if (count($customerIds) > 0) {
					$query->orWhereIn('customer_id', $customerIds);
				}
				
				
			});
		}
		
		if ($status != '') {
			$list->where('is_activated', $status);
		}
		$list->orderBy('id', 'DESC');
		
		return ReportResource::collection($list->paginate($limit));
	}
	
	public function all(Request $request)
	{
		$searchParams = $request->all();
		$limit = Arr::get($searchParams, 'limit', static::ITEM_PER_PAGE);
		$list = Report::select('id', 'name', 'slug')->notDeleted()->orderBy('id', 'DESC');
		
		return ReportResource::collection($list->paginate($limit));
	}
	
	public function available(Request $request)
	{
		$ignoreId = Arr::get($request->all(), 'ignoreId', '');
		$list = Report::select('id', 'name')->isPublished();
		
		if ($ignoreId != null && $ignoreId != "") {
			$list->where('id', '!=', $ignoreId);
		}
		
		$list->orderBy('id', 'DESC');
		
		return ReportResource::collection($list->get());
	}
	
	public function show($id = 0)
	{
		$report = Report::notDeleted()->where('id', $id)->first();
		if (!isset($report)) return response()->json(['errors' => 'Report is not valid'], 403);
		
		return new ReportResource($report);
	}
	
	public function store(Request $request)
	{
		$validator = Validator::make($request->all(), ['site_name' => ['required'], 'customer_name' => ['required'], 'contact_name' => ['required']]);
		if ($validator->fails()) return response()->json(['errors' => $validator->errors()], 403);
		$params = $request->all();
		$today = date('Ymd');
		$countItems = Report::where('code', 'like', $today . '%')->count();
		
		do {
			$countItems++;
			$code = $today . str_pad($countItems, 5, "0", STR_PAD_LEFT);
			$checkExist = Report::where('code', $code)->count();
		} while ($checkExist > 0);
		
		$report = Report::create([
			'code'               => $code,
			'report_date'        => $params['report_date'],
			'customer_id'        => $params['customer_name'],
			'charge_id'          => $params['contact_name'],
			'primary_member'     => $params['primary_member'],
			'second_member'      => $params['second_member'],
			'car'                => $params['car'],
			'notice'             => $params['notice'],
			'request'            => $params['request'],
			'on_site_cost'       => $params['on_site_cost'],
			'address'            => $params['address'],
			'has_estimated'      => ($params['has_estimated'] === true) ? 1 : 0,
			'is_finished'        => ($params['is_finished'] === true) ? 1 : 0,
			'estimated_workload' => $params['estimated_workload'],
			'user_id'            => auth('api')->user()->id,
			'is_new'             => 1,
			'is_activated'       => (in_array($params['is_activated'], [0, 1, 2, 3])) ? $params['is_activated'] : 0,
			'created_at'         => date('Y-m-d H:i:s'),
			'updated_at'         => date('Y-m-d H:i:s')
		]);
		
		foreach ($params['details'] as $item) {
			ReportDetail::create([
				'report_id'           => $report->id,
				'working_zone'        => $item['working_zone'],
				'piping'              => $item['piping'],
				'temperature_keeping' => $item['temperature_keeping'],
				'size'                => $item['size'],
				'length'              => $item['length'],
				'elbow'               => $item['elbow'],
				'note'                => $item['note'],
				'created_at'          => date('Y-m-d H:i:s'),
				'updated_at'          => date('Y-m-d H:i:s')
			]);
		}
		
		return new ReportResource($report);
	}
	
	public function update(Request $request, $id = 0)
	{
		$validator = Validator::make($request->all(), ['site_name' => ['required'], 'customer_name' => ['required'], 'contact_name' => ['required']]);
		if ($validator->fails()) return response()->json(['errors' => $validator->errors()], 403);
		$report = Report::notDeleted()->where('id', $id)->first();
		if (!isset($report)) return response()->json(['errors' => 'Report is not valid'], 403);
		$params = $request->all();
		
		$report->update([
			'report_date'         => $params['report_date'],
			'customer_id'         => $params['customer_name'],
			'charge_id'           => $params['contact_name'],
			'primary_member'      => $params['primary_member'],
			'second_member'       => $params['second_member'],
			'car'                 => $params['car'],
			'notice'              => $params['notice'],
			'request'             => $params['request'],
			'on_site_cost'        => $params['on_site_cost'],
			'address'             => $params['address'],
			'has_estimated'       => ($params['has_estimated'] === true) ? 1 : 0,
			'is_finished'         => ($params['is_finished'] === true) ? 1 : 0,
			'estimated_workload'  => $params['estimated_workload'],
			'progressing_user_id' => auth('api')->user()->id,
			'is_activated'        => (in_array($params['is_activated'], [0, 1, 2, 3])) ? $params['is_activated'] : 1,
			'updated_at'          => date('Y-m-d H:i:s')
		]);
		
		ReportDetail::where('report_id', $report->id)->delete();
		foreach ($params['details'] as $item) {
			ReportDetail::create([
				'report_id'           => $report->id,
				'working_zone'        => $item['working_zone'],
				'piping'              => $item['piping'],
				'temperature_keeping' => $item['temperature_keeping'],
				'size'                => $item['size'],
				'length'              => $item['length'],
				'elbow'               => $item['elbow'],
				'note'                => $item['note'],
				'created_at'          => date('Y-m-d H:i:s'),
				'updated_at'          => date('Y-m-d H:i:s')
			]);
		}
		
		return response()->json(null, 204);
	}
	
	public function destroy($id = 0)
	{
		$report = Report::notDeleted()->where('id', $id)->first();
		if (!isset($report)) response()->json(['error' => 'Ehhh! Can not delete this report'], 403);
		
		try {
			$report->update(['progressing_user_id' => auth('api')->user()->id, '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', []);
		$reports = Report::notDeleted()->whereIn('id', $listIds)->get();
		if ($reports->count() <= 0) response()->json(['error' => 'Report is not valid.'], 403);
		try {
			Report::notDeleted()->whereIn('id', $listIds)->update(['progressing_user_id' => auth('api')->user()->id, '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);
		$searchParams = $request->all();
		$listIds = Arr::get($searchParams, 'ids', []);
		$status = Arr::get($searchParams, 'status', 1);
		
		$reports = Report::notDeleted()->whereIn('id', $listIds)->get();
		if ($reports->count() <= 0) response()->json(['error' => 'Report is not valid.'], 403);
		try {
			Report::notDeleted()->whereIn('id', $listIds)->update(['progressing_user_id' => auth('api')->user()->id, 'is_activated' => $status]);
			
			//Notify
			$userNotifyIds = [];
			foreach ($reports as $report) {
				UserNotify::create([
					'content'    => "[" . auth('api')->user()->full_name . "] レポート ステータス#" . $report->code . "を更新しました。",
					'user_id'    => $report->user_id,
					'module'     => 'report',
					'item_id'    => $report->id,
					'created_at' => date('Y-m-d H:i:s'),
					'updated_at' => date('Y-m-d H:i:s'),
				]);
				if (!in_array($report->user_id, $userNotifyIds)) $userNotifyIds[] = $report->user_id;
			}
			
			foreach ($userNotifyIds as $uId) {
				event(new NotifyUserEvent($uId));
			}
		} 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);
		$searchParams = $request->all();
		$listIds = Arr::get($searchParams, 'ids', []);
		$status = Arr::get($searchParams, 'status', 1);
		
		$reports = Report::notDeleted()->whereIn('id', $listIds)->get();
		if ($reports->count() <= 0) response()->json(['error' => 'Report is not valid.'], 403);
		try {
			Report::notDeleted()->whereIn('id', $listIds)->update(['progressing_user_id' => auth('api')->user()->id, 'is_activated' => $status]);
		} catch (\Exception $ex) {
			response()->json(['error' => $ex->getMessage()], 403);
		}
		
		return response()->json(null, 204);
	}
	
	public function download($id = 0)
	{
		$report = Report::notDeleted()->where('id', $id)->first();
		if (!isset($report)) return response()->json(['errors' => 'Report is not valid'], 403);
		
		$detail = [];
		foreach ($report->detail as $item) {
			$detail[] = [
				'working_zone'        => $item->working_zone,
				'piping'              => $item->piping,
				'temperature_keeping' => $item->temperature_keeping,
				'size'                => $item->size,
				'length'              => $item->length,
				'elbow'               => $item->elbow,
				'note'                => $item->note
			];
		}
		
		if (count($detail) < 26) {
			$addMore = 26 - count($detail);
			for ($i = 0; $i < $addMore; $i++) {
				$detail[] = [
					'working_zone'        => '',
					'piping'              => '',
					'temperature_keeping' => '',
					'size'                => '',
					'length'              => '',
					'elbow'               => '',
					'note'                => ''
				];
			}
		}
		
		$address = $report->address;
		if ($address !== null && $address !== "") {
			$totalLength = count($detail);
			$addressIndex = $totalLength - 3;
			$addressIndexNext = $totalLength - 2;
			$addressIndexNext2 = $totalLength - 1;
			if (isset($detail[$addressIndex]) && ($detail[$addressIndex]['temperature_keeping'] === null || $detail[$addressIndex]['temperature_keeping'] === "")) {
				$detail[$addressIndex]['temperature_keeping'] = $address;
			} elseif (isset($detail[$addressIndexNext]) && ($detail[$addressIndexNext]['temperature_keeping'] === null || $detail[$addressIndexNext]['temperature_keeping'] === "")) {
				$detail[$addressIndexNext]['temperature_keeping'] = $address;
			} elseif (isset($detail[$addressIndexNext2]) && ($detail[$addressIndexNext2]['temperature_keeping'] === null || $detail[$addressIndexNext2]['temperature_keeping'] === "")) {
				$detail[$addressIndexNext2]['temperature_keeping'] = $address;
			} else {
				$detail[] = [
					'working_zone'        => '',
					'piping'              => '',
					'temperature_keeping' => $address,
					'size'                => '',
					'length'              => '',
					'elbow'               => '',
					'note'                => ''
				];
			}
		}
		
		$txtReportDate = Carbon::parse($report->report_date)->format('Y年m月d日');
		$title = $txtReportDate . ' - ID#' . $report->id;
		$onSiteCost = $report->on_site_cost;
		if ($onSiteCost != null && $onSiteCost != "") {
			$onSiteCost = (float)$onSiteCost;
			if ($onSiteCost > 0) {
				$onSiteCost = number_format($onSiteCost);
			}
		}
		
		$data = [
			'id'                 => $report->id,
			'title'              => $title,
			'report_year'        => Carbon::parse($report->report_date)->format('Y'),
			'report_month'       => Carbon::parse($report->report_date)->format('m'),
			'report_date'        => Carbon::parse($report->report_date)->format('d'),
			'report_full_date'   => $report->report_date,
			'site_name'          => $report->customer->project->site->name,
			'project_name'       => $report->customer->project->name,
			'customer_name'      => $report->customer->name,
			'contact_name'       => $report->charge->name,
			'has_estimated'      => $report->has_estimated,
			'estimated_workload' => $report->estimated_workload,
			'is_finished'        => $report->is_finished,
			'detail'             => $detail,
			'car'                => ($report->car != null && $report->car != "") ? $report->car : '/',
			'primary_member'     => $report->primary_member,
			'second_member'      => $report->second_member,
			'notice'             => $report->notice,
			'request'            => $report->request,
			'on_site_cost'       => $onSiteCost,
		];
		
		$fileName = $txtReportDate . '_ID' . $report->id . "_" . date("YmdHis") . ".pdf";
		Pdf::loadView('pdf.report', $data)
			->setPaper('A4', 'portrait')
			->setWarnings(false)
			->save(public_path('export/pdf/report/') . $fileName); //->stream('invoice.pdf');
		
		return response()->json(['status' => 'success', 'file' => $fileName], 200);
	}
}
