<?php

namespace App\Http\Controllers\Api;

use App\Http\Requests\Api\EventsCalendar;
use App\Http\Resources\EventsCollection;
use App\Http\Resources\Events as EventResource;
use App\Models\Occasion;
use App\Http\Requests\Api\BaseShow;
use App\Http\Controllers\Controller;
use App\Http\Requests\Api\EventsIndex;
use Carbon\Carbon;

class EventController extends Controller
{
    /**
     * Display a listing of the resource.
     * @param  EventsIndex $request
     * @return EventCollection
     */
    public function index(EventsIndex $request)
    {
        $data = $request->validated();
        $encrypter = getEncrypter(config("app.lists_key"));
        $pageKey = isset($data['pagekey']) ? $data['pagekey'] : NULL;
        $pastEvents = isset($data['pastevents']) ? $data['pastevents'] : FALSE;
        $startDate = isset($data['start']) ? $data['start'] : NULL;
        $endDate = isset($data['end']) ? $data['end'] : NULL;

        $orderFieldName = 'date';
        $orderByDirection = 'asc';
        $orderDirection = '>';
        $reverseOrder = FALSE;
        $reverse = FALSE;
        $nextKeyValue = FALSE;

        $pageSize = 3;
        if ($pastEvents) {
            // Get past events from today date
            $orderByDirection = 'desc';
            $orderDirection = '<';
            $reverse = isset($data['reverse']) ? $data['reverse'] : FALSE;
            if ($reverse) {
                $orderByDirection = 'asc';

                if ($pageKey) {
                    $reverseOrder = TRUE;
                }
            }
            $pageSize = 5;
        }

        $now = Carbon::now();

        $query = Occasion::full()
            ->select(
                'id',
                'language_id',
                'title',
                'image_id',
                'date',
                'lang_slug',
                'lang_uri'
            )
            ->where($orderFieldName, $orderDirection, $now);
            if ($startDate && $endDate) {
                $query->where('date', '>', $startDate)
                    ->where('date', '<', $endDate);
            }
            $query->orderBy($orderFieldName, $orderByDirection);

        if ($pageKey) {
            addNextKeyToQuery($encrypter, $query, $pageKey, $orderFieldName, $orderDirection, 'id', $reverseOrder);
        }

        $query->limit($pageSize + 1); // Check if more pages exist

        // Fetch the query
        $occasions = $query->get();

        if ($occasions->count() > $pageSize) {
            $occasions->pop();
            $hasNextPage = TRUE;
        } else {
            $hasNextPage = FALSE;
        }

        if (!$occasions->isEmpty() && $hasNextPage) {
            $nextKeyValue = getNextKeyValue($encrypter, $occasions, $orderFieldName, 'id');
        }
        return new EventsCollection($occasions, $nextKeyValue);
    }

    /**
     * Display the specified resource.
     *
     * @param  BaseShow $request
     * @return EventResource
     */
    public function show(BaseShow $request)
    {
        // Retrieve the validated input data...
        $data = $request->validated();

        $event = Occasion::full()
            ->where('lang_slug', $data['slug'])
            ->first();

        return new EventResource($event, true);
    }

    /**
     * Display the calendar resource.
     *
     * @param  EventsCalendar $request
     * @return EventCollection
     */
    public function calendar(EventsCalendar $request) {
        // Retrieve the validated input data...
        $data = $request->validated();
        $monthsThreshold = 2;

        $prevDate = isset($data['prevdate']) ? $data['prevdate'] : NULL;
        $nextDate = isset($data['nextdate']) ? $data['nextdate'] : NULL;
        $order = isset($data['order']) ? $data['order'] : NULL;

        $dateFrom = Carbon::now()->subMonthsNoOverflow($monthsThreshold)->startOfMonth();
        $dateTo = Carbon::now()->addMonthsNoOverflow($monthsThreshold)->endOfMonth();

        $response = [];
        if ($prevDate && $nextDate && $order) {

            if($order === '>') {
                // Changes values for next monthsThreshold months
                $dateFrom = Carbon::createFromFormat('Y-m-d', $nextDate)->endOfMonth();
                $dateTo = Carbon::createFromFormat('Y-m-d', $nextDate)->addMonthsNoOverflow($monthsThreshold)->endOfMonth();
                $response['prevDate'] = $prevDate;
                $response['nextDate'] = $dateTo->format('Y-m-d');
            } else {
                // Change values for previous monthsThreshold months
                $dateFrom = Carbon::createFromFormat('Y-m-d', $prevDate)->subMonthsNoOverflow($monthsThreshold)->startOfMonth();
                $dateTo = Carbon::createFromFormat('Y-m-d', $prevDate)->startOfMonth();

                $response['prevDate'] = $dateFrom->format('Y-m-d');
                $response['nextDate'] = $nextDate;
            }
        } else {
            $response['prevDate'] = $dateFrom->format('Y-m-d');
            $response['nextDate'] = $dateTo->format('Y-m-d');
        }

        $query = Occasion::full()
            ->select(
                'id',
                'language_id',
                'title',
                'date',
                'lang_slug',
                'lang_uri'
            )
            ->whereBetween('date', [$dateFrom, $dateTo]);

        $occasions = $query->get();

        return new EventsCollection($occasions, FALSE, $response['prevDate'], $response['nextDate']);
    }
}
