<?php

namespace App\Livewire;

use App\Enums\UserRole;
use App\Models\Downloads;
use Livewire\Attributes\Url;
use Livewire\Component;
use Livewire\WithPagination;

class DownloadsSearch extends Component
{
    use WithPagination;

    #[Url(history: true)]
    public $fileSearch;

    public $order = 'created_at_desc';

    public $options = [
        'FHD' => true,
        'FHD 48fps' => true,
    ];

    public $isOpen = false;

    #[Url(history: true)]
    public $studios = [];

    public $studiosCopy = [];

    // To toggle individual option selection
    public function toggleOption($option)
    {
        $this->options[$option] = ! $this->options[$option];
        $this->resetPage();
    }

    // To toggle dropdown visibility
    public function toggleDropdown()
    {
        $this->isOpen = ! $this->isOpen;
    }

    protected $queryString = [
        'fileSearch' => ['except' => '', 'as' => 'fS'],
        'order' => ['except' => '', 'as' => 'order'],
    ];

    public function updatingFileSearch()
    {
        $this->resetPage();
    }

    public function applyFilters(): void
    {
        $this->studiosCopy = $this->studios;
        $this->resetPage();
    }

    public function revertFilters(): void
    {
        $this->studios = $this->studiosCopy;
    }

    // Map the selected options to database types
    private function getSelectedTypes()
    {
        $types = [];

        // Map the options to their corresponding database values
        foreach ($this->options as $label => $selected) {
            if ($selected) {
                if ($label === 'FHD') {
                    $types[] = 'FHD';
                } elseif ($label === 'FHD 48fps') {
                    $types[] = 'FHDi';
                } elseif ($label === 'UHD' && auth()->user()->hasRole(UserRole::SUPPORTER)) {
                    $types[] = 'UHD';
                } elseif ($label === 'UHD 48fps' && auth()->user()->hasRole(UserRole::SUPPORTER)) {
                    $types[] = 'UHDi';
                }
            }
        }

        return $types;
    }

    public function clicked($downloadId)
    {
        $download = Downloads::find($downloadId);
        if (! $download) {
            return;
        }

        $download->count++;
        $download->save();
        cache()->forget("episode_{$download->episode->id}_download_{$download->type}");
    }

    public function mount()
    {
        if (! auth()->user()->hasRole(UserRole::SUPPORTER)) {
            return;
        }

        // Add patreon options
        $this->options['UHD'] = true;
        $this->options['UHD 48fps'] = true;
    }

    public function render()
    {
        $orderby = 'created_at';
        $orderdirection = 'desc';

        switch ($this->order) {
            case 'az':
                $orderby = 'url';
                $orderdirection = 'asc';
                break;
            case 'za':
                $orderby = 'url';
                $orderdirection = 'desc';
                break;
            case 'created_at_desc':
                $orderby = 'created_at';
                $orderdirection = 'desc';
                break;
            case 'created_at_asc':
                $orderby = 'created_at';
                $orderdirection = 'asc';
                break;
            case 'size_asc':
                $orderby = 'size';
                $orderdirection = 'asc';
                break;
            case 'size_desc':
                $orderby = 'size';
                $orderdirection = 'desc';
                break;
            default:
                $orderby = 'created_at';
                $orderdirection = 'desc';
        }

        $downloads = Downloads::when($this->fileSearch != '', fn ($query) => $query->where('url', 'like', '%'.$this->fileSearch.'%'))
            ->whereIn('type', $this->getSelectedTypes())
            ->when($this->studios !== [], fn ($q) => $q->whereHas('episode', fn ($query) => $query->whereHas('studio', function ($query) {
                $query->whereIn('slug', $this->studios);
            })))
            ->whereNotNull('size')
            ->orderBy($orderby, $orderdirection)
            ->paginate(20);

        return view('livewire.downloads-search', [
            'downloads' => $downloads,
            'query' => $this->fileSearch,
            'studiocount' => is_array($this->studios) ? count($this->studios) : 0,
        ]);
    }
}
