<?php

namespace Daylight\Core\Modules\PageBuilder\Livewire;

use Illuminate\Support\Collection;
use Illuminate\View\View;
use Livewire\Component;

class RelatedFieldSelector extends Component
{
    public string|array $selected = [];

    public string $relatedType;

    public string $name;

    public string $placeholder = 'Search...';

    public bool $required = false;

    public string $searchQuery = '';

    public Collection $searchResults;

    public bool $showDropdown = false;

    public function mount(array|string $selected = [], string $relatedType = '', string $name = '', string $placeholder = '', bool $required = false): void
    {
        $this->relatedType = $relatedType;
        $this->name = $name;
        $this->placeholder = $placeholder;
        $this->required = $required;
        $this->searchResults = collect();

        // Handle JSON string (from form old() data) - normalize to array immediately
        if (is_string($selected)) {
            $selected = json_decode($selected, true) ?: [];
        }

        // Hydrate selected items if they only contain IDs
        $this->selected = $this->hydrateSelectedItems($selected);
    }

    private function hydrateSelectedItems(array $selected): array
    {
        if (empty($selected)) {
            return [];
        }

        // Check if first item is already hydrated (has 'name' key)
        $firstItem = reset($selected);
        if (is_array($firstItem) && isset($firstItem['name'])) {
            return $selected;
        }

        // Extract IDs (handle both array format and simple ID format)
        $ids = collect($selected)->map(function ($item) {
            return is_array($item) ? ($item['id'] ?? null) : $item;
        })->filter()->toArray();

        if (empty($ids)) {
            return [];
        }

        // Fetch full data using the Relatable contract
        $modelClass = $this->relatedType;

        if (! class_exists($modelClass) || ! method_exists($modelClass, 'getForRelation')) {
            return [];
        }

        return $modelClass::getForRelation($ids)->toArray();
    }

    public function updatedSearchQuery(): void
    {
        if (strlen($this->searchQuery) < 2) {
            $this->searchResults = collect();
            $this->showDropdown = false;

            return;
        }

        $this->search();
        $this->showDropdown = true;
    }

    public function search(): void
    {
        $modelClass = $this->relatedType;

        if (! class_exists($modelClass)) {
            $this->searchResults = collect();

            return;
        }

        // Get IDs of already selected items
        $selectedIds = collect($this->selected)->pluck('id')->toArray();

        // Use the Relatable contract
        if (method_exists($modelClass, 'searchForRelation')) {
            $this->searchResults = $modelClass::searchForRelation(
                $this->searchQuery,
                $selectedIds,
                10
            );
        } else {
            $this->searchResults = collect();
        }
    }

    public function selectItem(array $item): void
    {
        // Check if already selected
        if (collect($this->selected)->contains('id', $item['id'])) {
            return;
        }

        $this->selected[] = $item;
        $this->searchQuery = '';
        $this->searchResults = collect();
        $this->showDropdown = false;
    }

    public function removeItem(int $index): void
    {
        unset($this->selected[$index]);
        $this->selected = array_values($this->selected);
    }

    public function reorderItems(array $orderedIds): void
    {
        // Reorder selected items based on the new ID order
        $orderedItems = [];

        foreach ($orderedIds as $id) {
            $item = collect($this->selected)->firstWhere('id', $id);
            if ($item) {
                $orderedItems[] = $item;
            }
        }

        $this->selected = $orderedItems;
    }

    public function closeDropdown(): void
    {
        $this->showDropdown = false;
    }

    public function render(): View
    {
        return view('daylight::livewire.page-builder.related-field-selector');
    }
}
