<?php

namespace App\Livewire\Pages\Analytics;

use App\Domains\Analytics\Models\Click;
use App\Domains\Link\Models\Link;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\View\View;
use Livewire\Attributes\On;
use Livewire\Attributes\Url;
use Livewire\Component;

class Index extends Component
{
    #[Url(as: 'range')]
    public string $range = '7d';

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

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

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

    public int $totalToday = 0;

    public int $workspaceId = 0;

    /** @var array<int, array<string, mixed>> */
    public array $recentClicks = [];

    public function mount(): void
    {
        $workspace = require_workspace();
        $this->workspaceId = $workspace->id;
        $this->totalToday = Click::where('workspace_id', $workspace->id)
            ->whereDate('clicked_at', today())
            ->count();
    }

    public function setRange(string $range): void
    {
        $this->range = in_array($range, ['24h', '7d', '30d', '90d']) ? $range : '7d';
    }

    public function clearFilters(): void
    {
        $this->country = '';
        $this->device = '';
        $this->linkId = '';
    }

    private function rangeStart(): Carbon
    {
        return match ($this->range) {
            '24h' => now()->subHours(24),
            '30d' => now()->subDays(30),
            '90d' => now()->subDays(90),
            default => now()->subDays(7),
        };
    }

    /** @return Builder<Click> */
    private function baseQuery(): Builder
    {
        $wsId = $this->workspaceId;

        $q = Click::where('workspace_id', $wsId)
            ->where('clicked_at', '>=', $this->rangeStart());

        if ($this->country) {
            $q->where('country', $this->country);
        }
        if ($this->device) {
            $q->where('device', $this->device);
        }
        if ($this->linkId) {
            $link = Link::where('workspace_id', $wsId)->where('ulid', $this->linkId)->first();
            if ($link) {
                $q->where('link_id', $link->id);
            }
        }

        return $q;
    }

    /** @param array<string, mixed> $data */
    #[On('echo:workspace.{workspaceId}.analytics,click.recorded')]
    public function handleNewClick(array $data): void
    {
        array_unshift($this->recentClicks, $data);
        $this->recentClicks = array_slice($this->recentClicks, 0, 10);
        $this->totalToday++;
    }

    public function render(): View
    {
        $wsId = $this->workspaceId;

        $totalFiltered = $this->baseQuery()->count();

        $allTime = Click::where('workspace_id', $wsId)->count();

        $byCountry = (clone $this->baseQuery())
            ->whereNotNull('country')
            ->selectRaw('country, COUNT(*) as total')
            ->groupBy('country')
            ->orderByDesc('total')
            ->limit(10)
            ->get();

        $byDevice = (clone $this->baseQuery())
            ->selectRaw('device, COUNT(*) as total')
            ->groupBy('device')
            ->orderByDesc('total')
            ->get();

        $countries = Click::where('workspace_id', $wsId)
            ->whereNotNull('country')
            ->distinct()
            ->pluck('country')
            ->sort()
            ->values();

        $devices = Click::where('workspace_id', $wsId)
            ->whereNotNull('device')
            ->distinct()
            ->pluck('device')
            ->values();

        $links = Link::where('workspace_id', $wsId)
            ->orderBy('slug')
            ->get(['ulid', 'slug', 'title']);

        return view('livewire.pages.analytics.index', compact(
            'totalFiltered',
            'allTime',
            'byCountry',
            'byDevice',
            'countries',
            'devices',
            'links',
        ))->layout('layouts.nimuli-app', ['title' => 'Analytics']);
    }
}
