<?php

namespace App\Livewire\Tables;

use App\Models\Song;
use App\Enums\SongLanguageType;
use App\Enums\SongSituation;
use Illuminate\Support\Carbon;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Blade;
use Illuminate\Database\Eloquent\Builder;
use PowerComponents\LivewirePowerGrid\Button;
use PowerComponents\LivewirePowerGrid\Column;
use PowerComponents\LivewirePowerGrid\Facades\Filter;
use PowerComponents\LivewirePowerGrid\Facades\PowerGrid;
use PowerComponents\LivewirePowerGrid\PowerGridFields;
use PowerComponents\LivewirePowerGrid\PowerGridComponent;
use PowerComponents\LivewirePowerGrid\Traits\WithExport; 
use PowerComponents\LivewirePowerGrid\Components\SetUp\Exportable; 
use PowerComponents\LivewirePowerGrid\Facades\Rule;
use Livewire\Attributes\On;
use WireUi\Traits\WireUiActions;

final class SongTable extends PowerGridComponent
{
    use WithExport, WireUiActions;

    public string $tableName = 'song-table';
    public bool $canCreate = false;
    public bool $canEdit   = false;
    public bool $canDownload = false;
    public bool $canDelect = false;

    public ?string $language_type = null;
    public ?string $situation = null;

    /* public bool $deferLoading = true;

    public string $loadingComponent = 'components.my-custom-loading'; */

    public bool $showFilters = false;

    public function boot(): void
    {
        config(['livewire-powergrid.filter' => 'outside']);
        $this->canCreate = Auth::user()?->can('song-edit') ?? false;
        $this->canEdit = Auth::user()?->can('song-edit') ?? false;
        $this->canDownload=Auth::user()?->can('song-delete') ?? false;
        $this->canDelect = Auth::user()?->can('song-delete') ?? false;
    }

    public function setUp(): array
    {
        if($this->canDownload || $this->canDelect){
            $this->showCheckBox();
        }
        $actions = [];
        if($this->canDownload){
            $actions[]=PowerGrid::exportable(fileName: $this->tableName.'-file') 
                ->type(Exportable::TYPE_XLS, Exportable::TYPE_CSV);
        }
        $header = PowerGrid::header()->showSoftDeletes()->showToggleColumns();
        $header->includeViewOnTop('livewire.headers.song');
        $actions[]=$header;
        $actions[]=PowerGrid::footer()->showPerPage()->showRecordCount();

        return $actions;
    }

    public function header(): array
    {
        $actions = [];
        if ($this->canDelect) {
            $actions[]=Button::add('bulk-delete')
                ->slot('Bulk delete (<span x-text="window.pgBulkActions.count(\'' . $this->tableName . '\')"></span>)')
                ->icon('solid-trash',['id' => 'my-custom-icon-id', 'class' => 'font-bold'])
                ->class('inline-flex items-center gap-1 px-3 py-1 rounded ')
                ->dispatch('bulkDelete.' . $this->tableName, []);
        }
        return $actions;
    } 

    public function datasource(): Builder
    {
        return Song::query()->with([
            'artists:id,name'
        ]);
    }

    public function relationSearch(): array
    {
        return [];
    }

    public function fields(): PowerGridFields
    {
        return PowerGrid::fields()
            ->add('id')
            ->add('name')
            ->add('simplified')
            ->add('phonetic_abbr')
            ->add('pinyin_abbr')
            ->add('strokes_abbr')
            ->add('filename')
            ->add('adddate_formatted', fn (Song $model) => Carbon::parse($model->adddate)->format('Y-m-d'))
            ->add('song_artists' ,fn(Song $model)=> $model->str_artists())
            ->add('language_type_str', fn (Song $model) => $this->renderLanguageType($model))
            ->add('song_categories', fn(Song $model) => $model->str_categories())
            ->add('db_change')
            ->add('vocal')
            ->add('status_str', fn (Song $model) => $this->renderSituation($model))
            ->add('copyright01')
            ->add('copyright02')
            ->add('note01')
            ->add('note02')
            ->add('note03')
            ->add('note04')
            ->add('enable')
            ->add('created_at_formatted', fn (Song $model) => Carbon::parse($model->created_at)->format('Y-m-d H:i:s'));
    }
    private function renderLanguageType(Song $model): string
    {
        if ($this->canEdit) {
            return Blade::render(
                '<x-select-dropdown type="occurrence" :options=$options  :modelId=$modelId :fieldName=$fieldName :selected=$selected/>', 
                [
                    'options' => SongLanguageType::options(), 
                    'modelId' => intval($model->id),
                    'fieldName'=>'language_type', 
                    'selected' => $model->language_type->value
                ]);
        }
        return $model->language_type->labelPowergridFilter();
    }

    private function renderSituation(Song $model): string
    {
        if ($this->canEdit) {
            return Blade::render(
                '<x-select-dropdown type="occurrence" :options=$options  :modelId=$modelId :fieldName=$fieldName :selected=$selected/>', 
                [
                    'options' => SongSituation::options(), 
                    'modelId' => intval($model->id),
                    'fieldName'=>'situation', 
                    'selected' => $model->situation->value
                ]);
        }
        return $model->situation->labelPowergridFilter();
    }

    public function columns(): array
    {
        $column=[];
        $column[]=Column::make(__('songs.id'), 'id')
                    ->editOnClick(hasPermission: $this->canEdit, dataField: 'id', fallback: 'N/A', saveOnMouseOut: true);
        $column[]=Column::make(__('songs.name'), 'name')->sortable()->searchable()
                    ->editOnClick(hasPermission: $this->canEdit, dataField: 'name', fallback: 'N/A', saveOnMouseOut: true);
        $column[]=Column::make(__('songs.name_simplified'), 'simplified')->sortable()->searchable()->hidden(true, false);
        $column[]=Column::make(__('songs.name_phinetic'), 'phonetic_abbr')->sortable()->searchable()->hidden(true, false);
        $column[]=Column::make(__('songs.name_pinyin'), 'pinyin_abbr')->sortable()->searchable()->hidden(true, false);
        $column[]=Column::make(__('songs.name_strokes'), 'strokes_abbr')->sortable()->searchable()->hidden(true, false);
        $column[]=Column::make(__('songs.filename'), 'filename')->sortable()->searchable()
                    ->editOnClick(hasPermission: $this->canEdit, dataField: 'filename', fallback: 'N/A', saveOnMouseOut: true);
        $column[]=Column::make(__('songs.adddate'), 'adddate_formatted', 'adddate')->sortable();
        $column[]=Column::make(__('songs.artists'), 'song_artists');
        $column[]=Column::make(__('songs.language_type'),'language_type_str', 'songs.language_type')->searchable();
        $column[]=Column::make(__('songs.categorys'), 'song_categories');
        $column[]=Column::make('Db change', 'db_change')
                    ->editOnClick(hasPermission: $this->canEdit, dataField: 'db_change', fallback: 'N/A', saveOnMouseOut: true);
        $column[]=Column::make(__('songs.vocal'), 'vocal')->toggleable(hasPermission: $this->canEdit, trueLabel: 'yes', falseLabel: 'no');
        $column[]=Column::make(__('songs.situation'), 'situation_str','songs.situation')->searchable();
        $column[]=Column::make(__('songs.copyright01'), 'copyright01')->sortable()->searchable()
                    ->editOnClick(hasPermission: $this->canEdit, dataField: 'copyright01', fallback: 'N/A', saveOnMouseOut: true);
        $column[]=Column::make(__('songs.copyright02'), 'copyright02')->sortable()->searchable()->hidden(true, false)
                    ->editOnClick(hasPermission: $this->canEdit, dataField: 'copyright02', fallback: 'N/A', saveOnMouseOut: true);
        $column[]=Column::make(__('songs.note01'), 'note01')->sortable()->searchable()
                    ->editOnClick(hasPermission: $this->canEdit, dataField: 'note01', fallback: 'N/A', saveOnMouseOut: true);
        $column[]=Column::make(__('songs.note02'), 'note02')->sortable()->searchable()->hidden(true, false)
                    ->editOnClick(hasPermission: $this->canEdit, dataField: 'note02', fallback: 'N/A', saveOnMouseOut: true);
        $column[]=Column::make(__('songs.note03'), 'note03')->sortable()->searchable()->hidden(true, false) 
                    ->editOnClick(hasPermission: $this->canEdit, dataField: 'note03', fallback: 'N/A', saveOnMouseOut: true);
        $column[]=Column::make(__('songs.note04'), 'note04')->sortable()->searchable()->hidden(true, false)    
                    ->editOnClick(hasPermission: $this->canEdit, dataField: 'note04', fallback: 'N/A', saveOnMouseOut: true);
        $column[]=Column::make(__('songs.enable'), 'enable')->toggleable(hasPermission: $this->canEdit, trueLabel: 'yes', falseLabel: 'no');
        $column[]=Column::make('Created at', 'created_at_formatted', 'created_at')->sortable()->hidden(true, false);
        $column[]=Column::action(__('songs.actions'));             
        return $column;
    }

    public function filters(): array
    {
        return [
            Filter::number('id')->placeholder(0,9999999),
            Filter::inputText('name')->placeholder(__('songs.name')),
            Filter::inputText('phonetic_abbr')->placeholder(__('songs.name_phinetic')),
            Filter::inputText('pinyin_abbr')->placeholder(__('songs.name_pinyin')),
            Filter::number('strokes_abbr'),
            Filter::inputText('filename')->placeholder(__('songs.filename')),
            Filter::datepicker('adddate'),
            Filter::inputText('song_artists')->placeholder(__('songs.artists'))
                ->filterRelation('artists','name'),
            Filter::enumSelect('language_type_str','songs.language_type') 
                ->datasource(SongLanguageType::cases())
                ->optionLabel('songs.language_type'),
            Filter::enumSelect('situation_str','songs.situation')
                ->datasource(SongSituation::cases())
                ->optionLabel('songs.situation')
                ->filterRelation('songs','situation'),
            Filter::inputText('copyright01')->placeholder(__('songs.copyright01')),
            Filter::inputText('copyright02')->placeholder(__('songs.copyright02')),
            Filter::inputText('note01')->placeholder(__('songs.note01')),
            Filter::inputText('note02')->placeholder(__('songs.note02')),
            Filter::inputText('note03')->placeholder(__('songs.note03')),
            Filter::inputText('note04')->placeholder(__('songs.note04')),
            Filter::boolean('enable')->label('✅', '❌'),
            Filter::datetimepicker('created_at'),
        ];
    }
    #[On('bulkDelete.{tableName}')]
    public function bulkDelete(): void
    {
        $this->js('alert(window.pgBulkActions.get(\'' . $this->tableName . '\'))');
        if($this->checkboxValues){
            foreach ($this->checkboxValues as $id) {
                $song = Song::find($id);
                if ($song) {
                    $song->artists()->detach();
                    $song->categories()->detach();
                    $song->delete();
                }
            }
            $this->js('window.pgBulkActions.clearAll()'); // clear the count on the interface.
        }
    }
    #[On('selectChanged')]
    public function selectChanged($value,$fieldName, $modelId): void
    {
        // dd($value,$fieldName, $modelId);
        if (in_array($fieldName, ['language_type', 'situation'])) {
            $this->noUpdated($modelId,$fieldName,$value);
        }
    }
    #[On('onUpdatedEditable')]
    public function onUpdatedEditable($id, $field, $value): void
    {
        if (in_array($field,[
                'name','filename','db_change',
                'copyright01','copyright02','note01','note02','note03','note04'
            ]) && $this->canEdit) {
            $this->noUpdated($id,$field,$value);
        }
    }
    #[On('onUpdatedToggleable')]
    public function onUpdatedToggleable($id, $field, $value): void
    {
        if (in_array($field,['vocal','enable']) && $this->canEdit) {
            $this->noUpdated($id,$field,$value);
        }
    }
    private function noUpdated($id,$field,$value){
        $song = Song::find($id);
        if ($song) {
            $song->{$field} = $value;
            $song->save(); // 明確觸發 saving
        }
        $this->notification()->send([
            'icon' => 'success',
            'title' => $id.'.'.__('songs.'.$field).':'.$value,
            'description' => '已經寫入',
        ]);
    }
    

    public function actions(Song $row): array
    {
        $actions = [];
        if ($this->canEdit) {
            $actions[]=Button::add('edit')
                ->slot(__('songs.edit'))
                ->icon('solid-pencil-square')
                ->class('inline-flex items-center gap-1 px-3 py-1 rounded ')
                ->dispatchTo('forms.song-form', 'openModal', ['id' => $row->id]);
        }
        if($this->canDelect){
            $actions[]=Button::add('delete')
                ->slot(__('songs.delete'))
                ->icon('solid-trash')
                ->class('inline-flex items-center gap-1 px-3 py-1 rounded ')
                ->dispatchTo('forms.song-form', 'deleteSong', ['id' => $row->id]);
        }

        return $actions;
    }
    
    /*
    public function actionRules($row): array
    {
       return [
            // Hide button edit for ID 1
            Rule::button('edit')
                ->when(fn($row) => $row->id === 1)
                ->hide(),
        ];
    }
    */
}
