<?php

namespace App\Livewire;

use App\Models\Author;
use App\Models\Game;
use App\Models\Genre;
use App\Models\Platform;
use Illuminate\View\View;
use Livewire\Component;

class AuthorsSelector extends Component
{
    public string $search = '';

    public bool $newAuthor = false;
    public string $newAuthorName = '';
    public array $selectedAuthors = []; // 'id', 'name'
    public array $newAuthors = [];

    public bool $dropdown = false;

    public function mount( array $oldAuthors = [], array $oldNewAuthors = [] ): void
    {
        $selectedAuthors = [];

        if ( is_string($oldAuthors) || is_int($oldAuthors) ) {
            $authors = [ $oldAuthors ];
        }

        if ( is_array($oldAuthors) && $oldAuthors !== [] ) {
            $firstItem = reset($oldAuthors);

            if ( is_array($firstItem) && array_key_exists('id', $firstItem) ) {
                $selectedAuthors = $oldAuthors;
            } else {
                $authorRecords = Author::whereIn('id', array_filter($oldAuthors, fn($id) => $id !== null))->get()->keyBy('id');

                foreach ($oldAuthors as $authorId) {
                    if ( isset($authorRecords[$authorId]) ) {
                        $selectedAuthors[] = [
                            'id' => $authorRecords[$authorId]->id,
                            'name' => $authorRecords[$authorId]->name,
                        ];
                    }
                }
            }
        }

        if ( is_string($oldNewAuthors) || is_int($oldNewAuthors) ) {
            $newAuthors = [ $oldNewAuthors ];
        }

        foreach ( (array) $oldNewAuthors as $name ) {
            if ( trim((string) $name) === '' ) {
                continue;
            }

            $selectedAuthors[] = [
                'id' => null,
                'name' => trim((string) $name),
            ];
        }

        $this->selectedAuthors = $selectedAuthors;
        $this->newAuthors = $oldNewAuthors;
    }

    public function updatedSearch(): void
    {
        $this->dropdown = strlen($this->search) > 2;
    }

    public function selectAuthor( int $id, string $name ): void
    {
        foreach ( $this->selectedAuthors as $author ) {
            if ( $author['id'] === $id ) {
                $this->search = '';
                $this->dropdown = false;
                return;
            }
        }

        $this->selectedAuthors[] = [
            'id' => $id,
            'name' => $name,
        ];

        $this->search = '';
        $this->dropdown = false;

    }

    public function removeAuthor( int $i ): void
    {
        array_splice( $this->selectedAuthors, $i, 1 );
    }

    public function addNewAuthor(): void
    {
        if( empty( trim( $this->newAuthorName ) ) )
            return;

        foreach ( $this->selectedAuthors as $author ) {
            if( strtolower($author['name']) === strtolower( $this->newAuthorName ) ){
                $this->newAuthor = false;
                $this->newAuthorName = '';
                return;
            }
        }

        $this->selectedAuthors[] = [
            'id' => null,
            'name' => trim( $this->newAuthorName ),
        ];

        $this->newAuthor = false;
        $this->newAuthorName = '';
    }

    public function switchNewAuthor(): void
    {
        $this->newAuthor = !$this->newAuthor;
        $this->newAuthorName = '';
        $this->search = '';
        $this->dropdown = false;
    }

    public function render(): View
    {
        $authors = collect();
        $data = [];

        if( $this->dropdown && strlen( $this->search ) > 2 && !$this->newAuthor ){
            $ids = array_filter(array_column( $this->selectedAuthors, 'id' ), function ( $id ) {
                return !is_null( $id );
            });

            $authors = Author::where( 'name', 'like', '%' . $this->search . '%' )
                ->when( !empty( $ids ), function ( $query ) use ( $ids ) { $query->whereNotIn( 'id', $ids ); } )
                ->orderBy( 'name' )
                ->limit( 20 )
                ->get();
            $data['authors'] = $authors;
        }

        return view('livewire.authors-selector', $data );
    }
}
