<?php

namespace App\Http\Controllers;

use App\Exceptions\SubmissionException;
use App\Helpers\FormHelpers;
use App\Http\Requests\StoreDraftRequest;
use App\Http\Requests\StoreEntryRequest;
use App\Jobs\DeleteXenForoCommentsThread;
use App\Models\Author;
use App\Models\Entry;
use App\Models\EntryFile;
use App\Models\Gallery;
use App\Models\EntryHash;
use App\Models\Game;
use App\Models\Genre;
use App\Models\Language;
use App\Models\Level;
use App\Models\Modification;
use App\Models\Platform;
use App\Models\Status;
use App\Models\System;
use App\Services\SubmissionsService;
use App\Services\XenforoApiService;
use Artesaos\SEOTools\Facades\SEOTools;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use Illuminate\View\View;

class SubmissionController extends Controller
{

    public function __construct(private SubmissionsService $services){}

    public function index(Request $request)
    {

        $entryTypes = [
        'romhack' => [
            'slug'        => 'romhacks',
            'label'       => 'Romhack',
            'icon'        => 'gamepad-2',
            'color'       => '#4a6fc2',
            'bg'          => '#d5e1fc1a',
            'border'      => '#d5e1fc40',
        ],
        'translation' => [
            'slug'        => 'translations',
            'label'       => 'Translation',
            'icon'        => 'languages',
            'color'       => '#4a8a2a',
            'bg'          => '#e7f4d91a',
            'border'      => '#e7f4d940',
        ],
        'homebrew' => [
            'slug'        => 'homebrew',
            'label'       => 'Homebrew',
            'icon'        => 'cpu',
            'color'       => '#c23060',
            'bg'          => '#ffeaf01a',
            'border'      => '#ffeaf040',
        ],
        'utility' => [
            'slug'        => 'utilities',
            'label'       => 'Utility',
            'icon'        => 'wrench',
            'color'       => '#8a6600',
            'bg'          => '#fff8d51a',
            'border'      => '#fff8d540',
        ],
        'document' => [
            'slug'        => 'documents',
            'label'       => 'Document',
            'icon'        => 'file-text',
            'color'       => '#7a35c2',
            'bg'          => '#f3eaff1a',
            'border'      => '#f3eaff40',
        ],
        'lua-scripts' => [
            'slug'        => 'lua-scripts',
            'label'       => 'Lua script',
            'icon'        => 'terminal',
            'color'       => '#a04515',
            'bg'          => '#eed6c51a',
            'border'      => '#eed6c540',
        ] ];

        SEOTools::setTitle('Submit');
        return view('submissions.index', compact('entryTypes'));
    }

    public function create(Request $request, string $section)
    {
        $data = [
            'entry' => new Entry(),
            'section' => $section,
            'words' => FormHelpers::getEntryFormWords($section),
            'isEdit' => false,
            'oldModifications' => old( 'modifications', [] ),
            'oldSystems' => old( 'systems', [] ),
            'oldLanguages' => old( 'languages', [] ),
            'oldCategories' => old( 'categories', [] ),
            'oldFilesArray' => $this->services->prepareOldFiles( null )
        ];

        if( $data['words'] === [] )
            abort(500);

        if( section_must_be( ['romhacks', 'lua-scripts'], $section ) ){
            $data['modifications'] = Modification::orderBy('name')->get();
        }
        if( section_must_be( [ 'romhacks', 'translations', 'homebrew', 'lua-scripts' ], $section ) ){
            $data['statuses'] = Status::orderBy('id')->get();
        }
        if( section_must_be( 'utilities' , $section ) ){
            $data['systems'] = System::orderBy('name')->get();
        }
        if( section_must_be( [ 'utilities', 'documents' ], $section ) ) {
            $data['levels'] = Level::orderBy('id')->get();
        }

        SEOTools::setTitle( $data['words']['page_title'] );
        return view('submissions.create', $data);
    }


    public function edit(Request $request, string $section, Entry $entry){

        if( $entry->type !== $section )
            abort(404);

        $data = [
            'entry' => $entry,
            'section' => $section,
            'words' => FormHelpers::getEntryFormWords($section),
            'isEdit' => true,
            'oldModifications' => old('modifications', $entry->modifications->pluck('id')->toArray() ?? [] ),
            'oldSystems' => old( 'systems', $entry->systems->pluck('id')->toArray() ?? [] ),
            'oldLanguages' => old('languages', $entry->languages->pluck('id')->toArray() ?? [] ),
            'oldCategories' => old('categories', $entry->categories->pluck('id')->toArray() ?? [] ),
            'oldFilesArray' => $this->services->prepareOldFiles( $entry )
        ];

        if( $data['words'] === [] )
            abort(500);

        if( section_must_be( [ 'romhacks', 'lua-scripts' ], $section ) ){
            $data['modifications'] = Modification::orderBy('name')->get();
        }
        if( section_must_be( [ 'romhacks', 'translations', 'homebrew', 'lua-scripts' ], $section ) ){
            $data['statuses'] = Status::orderBy('id')->get();
        }
        if( section_must_be( 'utilities' , $section ) ){
            $data['systems'] = System::orderBy('name')->get();
        }
        if( section_must_be( [ 'utilities', 'documents' ], $section ) ) {
            $data['levels'] = Level::orderBy('id')->get();
        }

        SEOTools::setTitle( $data['words']['page_title'] );
        return view('submissions.edit', $data);
    }

    public function destroy(Request $request, string $section, Entry $entry)
    {
        if( $entry->type !== $section )
            abort(404);

        if( $entry->comments_thread_id )
            DeleteXenForoCommentsThread::dispatch( $entry->comments_thread_id );

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

    public function store(Request $request, string $section){

        $request = $request->input('submit-state') === 'draft' ? app(StoreDraftRequest::class) : app(StoreEntryRequest::class);
        $request->validateResolved();

        try {
            $entry = $this->services->storeEntry($request, $section);

            return match ($entry->state) {
                'published' => redirect()->route('entries.show', ['section' => $section, 'entry' => $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, string $section, Entry $entry)
    {
        $request = $request->input('submit-state') === 'draft' ? app(StoreDraftRequest::class) : app(StoreEntryRequest::class);
        $request->validateResolved();

        try {
            $entry = $this->services->editEntry($request, $section, $entry);

            return match ($entry->state) {
                'published' => redirect()->route('entries.show', ['section' => $section, 'entry' => $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()]);
        }

    }
}
