<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use Carbon\Carbon;
use Carbon\CarbonPeriod;
use Illuminate\Http\Request;
use Illuminate\Support\Arr;
use App\Schedule;
use App\Http\Resources\Admin\ScheduleResource;
use Validator;
use Illuminate\Validation\Rule;

/**
 * Class ScheduleController
 *
 * @package App\Http\Controllers
 */
class ScheduleController extends Controller
{
    const ITEM_PER_PAGE = 20;

    public function index(Request $request)
    {
        $searchParams = $request->all();
        $list = Schedule::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('work_date', 'LIKE', '%' . $keyword . '%');
        }
        if ($status != '') {
            $list->where('is_activated', $status);
        }
        $list->orderBy('work_date', 'DESC')->orderBy('id', 'DESC');

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

    public function all()
    {
        $list = Schedule::select('id', 'work_date')->notDeleted()->orderBy('id');

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

    public function nextSchedule()
    {
        $list = Schedule::select('id', 'work_date')->isPublished()->where('work_date', '>=', date('Y-m-d H:i:s'))->orderBy('work_date')->limit(7);

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

    public function show($id = 0)
    {
        $schedule = Schedule::notDeleted()->where('id', $id)->first();
        if (!isset($schedule)) return response()->json(['errors' => 'Schedule is not valid'], 403);

        return new ScheduleResource($schedule);
    }

    public function store(Request $request)
    {
        $validator = Validator::make($request->all(), ['work_date' => ['required', Rule::unique('schedules')], 'is_activated' => ['required']]);
        if ($validator->fails()) return response()->json(['errors' => $validator->errors()], 403);
        $params = $request->all();
        $schedule = Schedule::create([
            'work_date'    => $params['work_date'],
            'description'  => $params['description'],
            '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')
        ]);

        return new ScheduleResource($schedule);
    }

    public function quickAdd(Request $request)
    {
        $validator = Validator::make($request->all(), ['week' => 'required']);
        if ($validator->fails()) return response()->json(['errors' => $validator->errors()], 403);
        $params = $request->all();
        $weeks = Arr::get($params, 'week', 0);
        if ($weeks <= 0) return response()->json(['errors' => $validator->errors()], 403);

        $latestDate = Schedule::select('work_date')->notDeleted()->orderBy('work_date', 'DESC')->first();
        $startDate = Carbon::createFromFormat('Y-m-d H:i:s',  $latestDate->work_date);
        $startDate->addDays(1);
        $endDate = Carbon::createFromFormat('Y-m-d H:i:s',  $startDate->format('Y-m-d H:i:s'));
        $endDate->addWeeks($weeks);
        $periods = CarbonPeriod::create($startDate, $endDate);

        $listInsert = [];
        foreach ($periods as $date) {
            $listInsert[] = [
                'work_date'    => $date->format('Y-m-d H:i:s'),
                'is_activated' => 1,
                'created_at'   => date('Y-m-d H:i:s'),
                'updated_at'   => date('Y-m-d H:i:s')
            ];
        }
        if (count($listInsert) > 0) Schedule::insert($listInsert);

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

    public function update($id = 0, Request $request)
    {
        $validator = Validator::make($request->all(), ['work_date' => ['required', Rule::unique('schedules')->ignore($id)], 'is_activated' => ['required']]);
        if ($validator->fails()) return response()->json(['errors' => $validator->errors()], 403);
        $schedule = Schedule::notDeleted()->where('id', $id)->first();
        if (!isset($schedule)) return response()->json(['errors' => 'Schedule is not valid'], 403);
        $params = $request->all();
        $schedule->update([
            'work_date'    => $params['work_date'],
            'description'  => $params['description'],
            'is_activated' => ($params['is_activated'] === true) ? 1 : 0,
            'updated_at'   => date('Y-m-d H:i:s')
        ]);

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

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

        try {
            $schedule->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', []);
        $scheduleList = Schedule::notDeleted()->whereIn('id', $listIds)->get();
        if ($scheduleList->count() <= 0) response()->json(['error' => 'Schedule is not valid.'], 403);
        try {
            Schedule::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', []);
        $scheduleList = Schedule::notDeleted()->whereIn('id', $listIds)->get();
        if ($scheduleList->count() <= 0) response()->json(['error' => 'Schedule is not valid.'], 403);
        try {
            Schedule::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', []);
        $scheduleList = Schedule::notDeleted()->whereIn('id', $listIds)->get();
        if ($scheduleList->count() <= 0) response()->json(['error' => 'Schedule is not valid.'], 403);
        try {
            Schedule::notDeleted()->whereIn('id', $listIds)->update(['is_activated' => false]);
        } catch (\Exception $ex) {
            response()->json(['error' => $ex->getMessage()], 403);
        }

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