<?php

namespace App\Http\Controllers;

use App\Enum\OfferStatus;
use App\Http\Controllers\Utils\UtilController;
use App\Models\Artist;
use App\Models\Offer;
use App\Models\User;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Contracts\View\Factory;
use Illuminate\Contracts\View\View;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use App\Models\EventType;
use App\Models\Event;
use App\Models\Organizer;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Response;
use PHPUnit\Exception;

class EventController extends Controller
{
    //
    public function __construct()
    {
        $this->middleware(['auth', 'verified', 'onboarding']);
        $this->middleware(['role:artist,organizer,manager'])->only('show');
        $this->middleware('role:organizer')->except('show');
    }

    public function index()
    {
        return view('web.organizer.event.events')
            ->with('events', Event::where('organizer_id', '=', Auth::id())->paginate(15));
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return Response|Application|Factory|View
     */
    public function create($username = null)
    {
        if (is_null($username)) {
            return view('web.organizer.event.create')
                ->with('event_types', EventType::all());
        } else {
            $user = User::where('username', $username)->firstOrFail();
            $artist = Artist::where('user_id', $user->id)->firstOrFail();

            return view('web.organizer.event.create')
                ->with('event_types', EventType::all())
                ->with('artist', $artist);
        }
    }

    /**
     * Store a newly created resource in storage.
     *
     * @return RedirectResponse
     */
    public function store(Request $request)
    {
        $events = Event::where([
            ['organizer_id', Auth::id()],
            ['title', trim($request->title)]
        ])->exists();

        if ($events) {
            return redirect()->route('organizer.events')
                ->with('warning', 'You can not add an event with an existing name');
        }

        $event = new Event();
        $event->title = trim($request->title);
        $event->slug = UtilController::generateSlugFromString($request->title);
        $event->event_date = $request->event_date;
        $event->start_time = $request->start_time;
        $event->end_time = $request->end_time;
        $event->city = $request->city;
        $event->country = $request->country;
        $event->description = $request->description;

        $eventType = EventType::findOrFail($request->event_type);
        $event->event_type()->associate($eventType);

        $organizer = Organizer::findOrFail(Auth::id());
        $event->organizer()->associate($organizer);

        try {
            $event->save();
        } catch (\Exception $e) {
            return redirect()->back()
                ->with('error', $e->getMessage());
        }

        if ($request->artist_id != null) { // Znaci deka doagja od offer
            $content = new Request();
            $content->artist_id = $request->artist_id;
            $content->event_id = $event->id;

            $offerStore = (new OfferController())->store($content);
            return redirect()->to($offerStore->getTargetUrl());
        }

        return redirect()->route('organizer.events');
    }

    /**
     * Display the specified resource.
     *
     * @return Response|Application|Factory|View
     */
    public function show($slug)
    {
        $event = Event::where('slug', $slug)->firstOrFail();

        return view('web.organizer.event.event')
            ->with('event', $event);
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param $slug
     * @return Application|Factory|View|RedirectResponse
     */
    public function edit($slug)
    {
        $event = Event::where('slug', $slug)->firstOrFail();

        $offers = Offer::where([
            ['event_id', $event->id],
            ['status', OfferStatus::IN_PROGRESS->value]])->exists();

        if ($offers) {
            return redirect()->route('organizer.events')
                ->with('warning', 'You cannot change event that is currently in progress.');
        }

        return view('web.organizer.event.create')
            ->with('event_types', EventType::all())
            ->with('event', $event);
    }

    /**
     * Update the specified resource in storage.
     *
     * @param int $id
     * @return Application|Factory|View|RedirectResponse
     */
    public function update(int $id, Request $request)
    {
        //
        $offers = Offer::where([
            ['event_id', $id],
            ['status', OfferStatus::IN_PROGRESS->value]])->exists();

        if ($offers) {
            return redirect()->route('organizer.events')
                ->with('warning', 'You cannot change event that is currently in progress.');
        }

        $event = Event::findOrFail($id);

        $event->title = $request->title;
        $event->slug = UtilController::generateSlugFromString($request->title);
        $event->event_date = $request->event_date;
        $event->start_time = $request->start_time;
        $event->end_time = $request->end_time;
        $event->city = $request->city;
        $event->country = $request->country;
        $event->description = $request->description;

        $eventType = EventType::find($request->event_type);
        $event->event_type()->associate($eventType);
        try {
            $event->update();
        } catch (Exception $e) {
            return redirect()->back()
                ->with('error', $e->getMessage());
        }

        return redirect()->route('organizer.events');

    }

    /**
     * Remove the specified resource from storage.
     *
     * @param int $id
     * @return Response
     */
    public function destroy($id)
    {
        //TODO: Add delete option for events that have been created but no offer is related to it...
    }
}
