<?php

namespace Daylight\Core\Livewire\Content;

use Daylight\Core\Livewire\Tables\BaseTable;
use Daylight\Core\Livewire\Tables\Concerns\WithBulkActions;
use Daylight\Core\Livewire\Tables\Concerns\WithFiltering;
use Daylight\Core\Livewire\Tables\Concerns\WithMultilingualism;
use Daylight\Core\Livewire\Tables\Concerns\WithRowActions;
use Daylight\Core\Livewire\Tables\Concerns\WithSearch;
use Daylight\Core\Livewire\Tables\Concerns\WithSorting;
use Daylight\Core\Models\Enums\PublishStatus;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\DB;
use Illuminate\View\View;
use Livewire\Attributes\Computed;

class PageTable extends BaseTable
{
    use WithBulkActions;
    use WithFiltering;
    use WithMultilingualism;
    use WithRowActions;
    use WithSearch;
    use WithSorting;

    protected function getBaseQuery(): Builder
    {
        return (daylightModel('page'))::query()
            ->with('translations');
    }

    protected function applySearch(Builder $query, ?string $searchQuery): Builder
    {
        return $query->when($searchQuery, function ($query, $searchQuery) {
            $query->whereHas('translations', function ($query) use ($searchQuery) {
                $query->where('name', 'like', "%{$searchQuery}%");
            });
        });
    }

    protected function applyMultilingualism(Builder $query, ?string $locale): Builder
    {
        return $query->withWhereHas('translations', function ($query) use ($locale) {
            $query->where('locale', $locale);
        });
    }

    protected function sortableColumns(): array
    {
        return ['name', 'created_at'];
    }

    protected function applySorting(Builder $query): Builder
    {
        if ($this->sortField === 'name') {
            return $query->orderBy(
                (daylightModel('page_translation'))::select('name')
                    ->whereColumn('page_id', 'pages.id')
                    ->where('locale', app()->getLocale())
                    ->limit(1),
                $this->sortDirection
            );
        }

        return $query->orderBy($this->sortField, $this->sortDirection);
    }

    protected function applyFilter(Builder $query, string $name, mixed $value): Builder
    {
        return match ($name) {
            'status' => $query->where('status', $value),
            default => $query,
        };
    }

    protected function availableFilters(): array
    {
        return [
            'status' => [
                'label' => __('daylight::general.status'),
                'options' => PublishStatus::formattedValues()->toArray(),
            ],
        ];
    }

    #[Computed]
    protected function availableBulkActions(): array
    {
        return [
            'bulk_delete' => [
                'name' => __('daylight::general.delete'),
                'action' => 'bulkDelete',
                'confirm' => true,
            ],
            'bulk_publish' => [
                'name' => __('daylight::general.published'),
                'action' => 'bulkPublish',
            ],
            'bulk_draft' => [
                'name' => __('daylight::general.draft'),
                'action' => 'bulkDraft',
            ],
        ];
    }

    public function bulkPublish(): void
    {
        $this->bulkStatusChange(PublishStatus::PUBLISHED->value);
    }

    public function bulkDraft(): void
    {
        $this->bulkStatusChange(PublishStatus::DRAFT->value);
    }

    protected function performDuplicate($model)
    {
        $model->load('translations.components.media', 'translations.components.relatables');

        return DB::transaction(function () use ($model) {
            $newPage = $model->replicate(['id']);
            $newPage->status = PublishStatus::DRAFT;
            $newPage->save();

            foreach ($model->translations as $translation) {
                $newTranslation = $translation->replicate(['id', 'page_id']);
                $newTranslation->page_id = $newPage->id;
                $newTranslation->slug = null;
                $newTranslation->name = __('daylight::content.copy_of', ['name' => $translation->name]);
                $newTranslation->save();

                foreach ($translation->components as $component) {
                    $newComponent = $component->replicate(['id', 'buildable_id', 'buildable_type']);
                    $newComponent->buildable_id = $newTranslation->id;
                    $newComponent->buildable_type = $newTranslation->getMorphClass();
                    $newComponent->save();

                    foreach ($component->media as $media) {
                        $newComponent->media()->attach($media->id, [
                            'properties' => $media->pivot->properties,
                            'order' => $media->pivot->order,
                        ]);
                    }

                    foreach ($component->relatables as $relatable) {
                        $newComponent->relatables()->create([
                            'relatable_type' => $relatable->relatable_type,
                            'relatable_id' => $relatable->relatable_id,
                            'order' => $relatable->order,
                        ]);
                    }
                }
            }

            return $newPage;
        });
    }

    protected function getEditRoute($model): string
    {
        return route('daylight.content.pages.edit', $model);
    }

    public function render(): View
    {
        return view('daylight::livewire.content.page-table');
    }
}
