<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Arr;

use App\Http\Requests\LivestreamValidation;
use App\Http\Requests\LivestreamRegistrationValidation;

use App\Models\Livestream;
use App\Utilities\Paginate;
use App\Utilities\PageResponse;
use App\Models\Page;
use App\Models\Inquiry;
use App\Models\User;
use App\Utilities\SearchResult;

use App\Mail\LivestreamReminder;

class LivestreamsController extends Controller
{
    public function index()
    {
        if (auth()->user()) {
            if (!auth()->user()->can('viewAny', Livestream::class)) {
                if (request()->expectsJson()) {
                    return response()->json(['error' => 'You do not have permission to sort pages'], 403);
                } else {
                    return redirect('/')->with('error', 'You do not have access to view Livestreams');
                }
            }
        } else {
            return redirect('/')->with('error', 'You do not have access to view Livestreams');
        }

        if (request()->expectsJson()) {
            $livestreams = Livestream::getLivestreams(requestInput());
            return Paginate::create($livestreams);
        } else {
            return view('livestreams.index');
        }
    }

    public function paginate()
    {
        $livestreams = Livestream::getLivestreams(requestInput());
        return Paginate::create($livestreams);
    }

    public function search()
    {
        request()->validate([
            'terms' => 'required|min:3',
        ]);

        $terms = SearchResult::collectTerms();
        $livestreams = Livestream::searchResults($terms, true);

        if (auth()->user()?->can('manage', Livestream::class)) {
            $livestreams->load('livestreamRegistrations', 'livestreamRegistrations.user', 'livestreamRegistrations.location', 'permissions');
        }

        return Paginate::create($livestreams);
    }

    public function store(LivestreamValidation $request, $id = null)
    {
        if ($id) {
            $livestream = Livestream::findOrFail($id);
            if (!auth()->user()->can('update', $livestream)) {
                return response()->json(['error' => 'You do not have permission to update that Livestream'], 403);
            }
        } else {
            if (!auth()->user()->can('create', Livestream::class)) {
                return response()->json(['error' => 'You do not have permission to create Livestreams'], 403);
            }
        }

        $livestream = (new Livestream())->saveLivestream(requestInput(), $id);

        return response()->json([
            'success' => $livestream->name.' Saved',
            'livestream' => $livestream,
        ]);
    }

    public function view($id)
    {
        $livestream = Livestream::findOrFail($id);

        if ($livestream->unlisted) {
            if (!auth()->check()) {
                session()->put('url.intended', request()->fullUrl());
                return redirect()->route('login');
            }

            if (!auth()->user()->can('view', $livestream)) {
                return redirect('/')->with(['error' => 'You do not have permission to view that livestream']);
            }
        }

        if (editing()) {
            auth()->user()?->disableEditing();
        }

        $livestream->markUserAttended();

        $page = (new Page())->findByFullSlug('live/view');
        return (new PageResponse())->view($page, 'pages.view', [
            'livestream' => $livestream,
            'page_title' => $livestream->name.' - Livestream',
            'slug' => request()->path(),
        ]);
    }

    public function user($id, $user_id)
    {
        if (! request()->hasValidSignature()) {
            abort(401);
        }

        $livestream = Livestream::findOrFail($id);
        $user = User::findOrFail($user_id);

        auth()->login($user);
        auth()->user()->setSessionTimeout();

        $livestream->markUserAttended();

        $slug = substr(route('livestreams.view', ['id' => $livestream->id], false), 1);

        $page = (new Page())->findByFullSlug('live/view');
        return (new PageResponse())->view($page, 'pages.view', [
            'livestream' => $livestream,
            'user' => $user,
            'slug' => $slug,
        ]);
    }

    public function register($id)
    {
        $livestream = Livestream::findOrFail($id);

        if ($livestream->hasCompleted) {
            return redirect()->back()->with([
                'error' => 'That livestream has completed',
            ]);
        }

        if ($livestream->unlisted) {
            if (!auth()->check()) {
                session()->put('url.intended', request()->fullUrl());
                return redirect()->route('login');
            }

            if (!auth()->user()->can('view', $livestream)) {
                return redirect('/')->with(['error' => 'You do not have permission to regsiter for that livestream']);
            }
        }

        $page = (new Page())->findByFullSlug('live/register');
        return (new PageResponse())->view($page, 'pages.view', ['livestream' => $livestream]);
    }

    public function saveRegistration(LivestreamRegistrationValidation $request, $id)
    {
        $livestream = Livestream::findOrFail($id);

        if ($livestream->unlisted) {
            if (!auth()->check()) {
                session()->put('url.intended', request()->fullUrl());
                return redirect()->route('login');
            }

            if (!auth()->user()->can('view', $livestream)) {
                return redirect('/')->with(['error' => 'You do not have permission to view that livestream']);
            }
        }

        $livestream->registerUser(request()->all());

        return response()->json([
            'success' => 'Registration Complete',
            'redirect' => route('livestreams.registration-complete', ['id' => $livestream->id]),
        ]);
    }

    public function registrationComplete($id)
    {
        $livestream = Livestream::findOrFail($id);

        $page = (new Page())->findByFullSlug('live/registration-complete');
        return (new PageResponse())->view($page, 'pages.view', ['livestream' => $livestream]);
    }

    public function sendReminderEmails($id)
    {
        $livestream = Livestream::findOrFail($id);

        if (!auth()->user()->can('sendReminderEmails', $livestream)) {
            return response()->json(['error' => 'You do not have permission to send reminder emails'], 403);
        }

        $input = requestInput();

        if (Arr::get($input, 'user_ids')) {
            $livestream_registrations = $livestream->livestreamRegistrations()->whereIn('user_id', Arr::get($input, 'user_ids'))->get();
        } else {
            $livestream_registrations = $livestream->livestreamRegistrations()->get();
        }

        foreach ($livestream_registrations as $livestream_registration) {
            Mail::to($livestream_registration->user->email)
                ->queue(new LivestreamReminder($livestream, $livestream_registration->user, $livestream_registration->url, $livestream_registration->unregister_url));

            $livestream_registration->reminder_email_sent_at = now();
            $livestream_registration->save();
        }

        return response()->json([
            'success' => $livestream_registrations->count().' Reminder Emails Queued To Send',
        ]);
    }

    public function unregister($id, $user_id)
    {
        if (! request()->hasValidSignature()) {
            abort(401);
        }

        $livestream = Livestream::findOrFail($id);
        $user = User::findOrFail($user_id);

        $livestream_registration = $livestream->livestreamRegistrations()->firstWhere('user_id', $user->id);

        if ($livestream_registration) {
            $livestream_registration->delete();
            $livestream->removePermission('view', $user);
        }

        $page = (new Page())->findByFullSlug('live/unregister-complete');
        return (new PageResponse())->view($page, 'pages.view', ['livestream' => $livestream, 'user' => $user]);
    }
}
