<?php

namespace Daylight\Core\Modules\MediaLibrary\Livewire;

use Daylight\Core\Modules\MediaLibrary\Models\Directory;
use Daylight\Core\Modules\MediaLibrary\Models\Media;
use Illuminate\View\View;
use Livewire\Attributes\On;
use Livewire\Attributes\Url;
use Livewire\Component;

class MediaLibrary extends Component
{
    #[Url(as: 'directory')]
    public ?int $directoryId = null;

    #[Url(as: 'search')]
    public string $search = '';

    public bool $selectable = false;

    public bool $singleFile = false;

    public array $selectedItems = [];

    public array $active = []; // Add this property

    public string $newDirectoryName = '';

    public int $refreshKey = 0;

    public bool $isUploading = false;

    public int $uploadingCount = 0;

    public ?string $instanceId = null;

    public function mount(bool $selectable = false, bool $singleFile = false, array $active = [], ?string $instanceId = null): void
    {
        $this->selectable = $selectable;
        $this->singleFile = $singleFile;
        $this->active = $active;
        $this->selectedItems = $active;
        $this->instanceId = $instanceId;
        $this->directoryId = (! is_null($this->directoryId)) ? $this->directoryId : null;
    }

    // Add this method to sync selectedItems when active prop changes
    public function updatedActive(): void
    {
        if ($this->selectable) {
            $this->selectedItems = $this->active;
        }
    }

    #[On('change-current-directory')]
    public function changeCurrentDirectory(?int $directoryId = null): void
    {
        $this->directoryId = $directoryId;

        // If in selectable mode (inside modal), don't redirect - just update state
        if ($this->selectable) {
            $this->reset('search');
            $this->refreshKey++;

            return;
        }

        // Force pagination reset by redirecting without the media-page parameter
        $this->redirect(route('daylight.media.index', [
            'directory' => $directoryId,
        ]), navigate: true);
    }

    #[On('search-updated')]
    public function updateSearch(string $search): void
    {
        $this->search = $search;
    }

    #[On('select-file')]
    public function selectFile(int $id): void
    {
        $file = Media::query()->find($id);

        if (! $file) {
            return;
        }

        $payload = [
            'id' => (int) $file->id,
            'name' => (string) $file->name,
            'handle' => (string) $file->handle,
            'type' => (string) $file->type,
            'size' => (int) $file->size,
            'url' => (string) $file->getUrl('thumbnail'),
        ];

        if ($this->singleFile) {
            $this->selectedItems = [$payload];

            return;
        }

        $existsIndex = collect($this->selectedItems)->search(fn ($item) => (int) ($item['id'] ?? 0) === (int) $file->id);

        if ($existsIndex === false) {
            $this->selectedItems[] = $payload;
        } else {
            array_splice($this->selectedItems, (int) $existsIndex, 1);
        }
    }

    public function submitSelectedFiles(): void
    {
        $this->directoryId = null;
        $this->dispatch('media-files-selected', [
            'files' => $this->selectedItems,
            'instanceId' => $this->instanceId,
        ]);
    }

    #[On('media-selector-close')]
    public function resetDirectory(): void
    {
        $this->directoryId = null;
        if ($this->selectable) {
            $this->reset('search');
            $this->refreshKey++;
        }
    }

    #[On('file-deleted')]
    public function onFileDeleted(?int $id = null): void
    {
        $this->refreshKey++;
    }

    #[On('file-uploaded')]
    public function onFileUploaded(): void
    {
        $this->refreshKey++;
    }

    #[On('uploads-started')]
    public function onUploadsStarted(int $count): void
    {
        $this->isUploading = true;
        $this->uploadingCount = $count;
    }

    #[On('uploads-complete')]
    public function onUploadsComplete(): void
    {
        $this->isUploading = false;
        $this->uploadingCount = 0;
    }

    #[On('file-upload-failed')]
    public function onFileUploadFailed(array $error): void
    {
        // Could store errors here to display them
        $this->refreshKey++;
    }

    #[On('directory-updated')]
    public function onDirectoryUpdated(): void
    {
        $this->refreshKey++;
    }

    #[On('directory-deleted')]
    public function onDirectoryDeleted(?int $parentId = null): void
    {
        $this->directoryId = $parentId;
        $this->refreshKey++;
    }

    #[On('sync-media-library-selection')]
    public function syncSelection(array $data): void
    {
        $instanceId = $data['instanceId'] ?? null;
        $selectedItems = $data['selectedItems'] ?? [];

        // Only update if this event is for this instance
        if ($instanceId !== null && $instanceId === $this->instanceId && $this->selectable) {
            $this->selectedItems = $selectedItems;
            $this->active = $selectedItems;

            if (isset($data['singleFile'])) {
                $this->singleFile = (bool) $data['singleFile'];
            }

            $this->refreshKey++;
        }
    }

    public function createDirectory(): void
    {
        $this->validate([
            'newDirectoryName' => ['required', 'string', 'max:255'],
        ]);

        Directory::query()->create([
            'parent_id' => $this->directoryId,
            'name' => $this->newDirectoryName,
        ]);

        $this->newDirectoryName = '';
        $this->dispatch('directory-created');
        $this->refreshKey++;
    }

    public function render(): View
    {
        return view('daylight::livewire.media.media-library', [
            'directoryId' => $this->directoryId,
            'refreshKey' => $this->refreshKey,
            'search' => $this->search,
        ]);
    }
}
