<?php

namespace App\Http\Controllers;

use App\Exceptions\SubmissionException;
use App\Helpers\EntryHelpers;
use App\Http\Requests\StoreDraftRequest;
use App\Http\Requests\StoreEntryRequest;
use App\Http\Requests\StoreNewsDraftRequest;
use App\Http\Requests\StoreNewsRequest;
use App\Jobs\DeleteXenForoCommentsThread;
use App\Models\News;
use App\Services\NewsService;
use Artesaos\SEOTools\Facades\SEOTools;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Gate;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;

class NewsController extends Controller
{

    public function index()
    {
        SEOTools::setTitle('News');
        return view('news.index');
    }

    public function show(Request $request, News $news)
    {
        if( !\Auth::guest() )
            Gate::authorize('viewAny', $news);

        // Permissions.
        $entryPolicy = match ($news->state) {
            'pending' => 'viewPending',
            'draft' => 'viewDraft',
            'rejected' => 'viewRejected',
            'hidden' => 'viewHidden',
            'locked' => 'viewLocked',
            'published' => null,
            'default' => null
        };

        if ($entryPolicy)
            Gate::authorize($entryPolicy, $news);

        $comments = EntryHelpers::getLatestComments($news);

        SEOTools::setTitle($news->title);
        SEOTools::setDescription( Str::limit( $news->description , 150 ) );
        SEOTools::opengraph()->addProperty('type', 'article');
        if( $news->gallery->first() ){
            SEOTools::opengraph()->addImage( url( Storage::url( $news->gallery->first()->image ) ) );
        }

        return view('news.show', compact('news', 'comments'));
    }

    public function create(Request $request)
    {
        $data = [
            'news' => new News(),
            'isEdit' => false,
            'oldCategory' => old('category') ? [ old('category') ] : []
        ];

        SEOTools::setTitle('Submit News');
        return view ('news.create', $data);
    }

    public function edit(Request $request, News $news)
    {
        $data = [
            'news' => $news,
            'isEdit' => true,
            'oldCategory' => old('category', $news->category_id) ? [ old('category', $news->category_id) ] : []
        ];

        SEOTools::setTitle('Edit News');
        return view ('news.edit', $data);
    }

    public function store(Request $request)
    {
        $request = $request->input('submit-state') === 'draft' ? app(StoreNewsDraftRequest::class) : app(StoreNewsRequest::class);
        $request->validateResolved();

        $service = app(NewsService::class);

        try {
            $entry = $service->storeNews($request);

            return match ($entry->state) {
                'published' => redirect()->route('news.show', ['news' => $entry->slug])->with('success', "Your entry has been published."),
                'pending' => redirect()->route('home')->with('success', "Your entry has been submitted and is pending review."),
                default => redirect()->route('home')->with('success', "Your entry has been saved as a draft.")
            };
        } catch ( SubmissionException $e ) {
            return back()->withInput()->withErrors(['error' => $e->getMessage()]);
        } catch ( \Exception $e ) {
            return back()->withInput()->withErrors(['error' => 'Unknown error: '.$e->getMessage()]);
        }
    }

    public function update(Request $request, News $news)
    {
        $request = $request->input('submit-state') === 'draft' ? app(StoreNewsDraftRequest::class) : app(StoreNewsRequest::class);
        $request->validateResolved();

        $service = app(NewsService::class);

        try {
            $news = $service->editNews($request, $news);

            return match ($news->state) {
                'published' => redirect()->route('news.show', ['news' => $news->slug])->with('success', "Your entry has been published."),
                'pending' => redirect()->route('home')->with('success', "Your entry has been submitted and is pending review."),
                default => redirect()->route('home')->with('success', "Your entry has been saved as a draft.")
            };
        } catch ( SubmissionException $e ) {
            return back()->withInput()->withErrors(['error' => $e->getMessage()]);
        } catch ( \Exception $e ) {
            return back()->withInput()->withErrors(['error' => 'Unknown error: '.$e->getMessage()]);
        }

    }

    public function destroy(Request $request, News $news)
    {
        if( $news->comments_thread_id )
            DeleteXenForoCommentsThread::dispatch( $news->comments_thread_id );

        $news->delete();
        return redirect( route('news.index') )->with('success', "Entry successfully deleted.");
    }
}
