<?php

declare(strict_types=1);

namespace App\Services\Studio;

use App\Models\User;
use App\Support\AvatarUrl;
use Illuminate\Support\Facades\DB;

final class CreatorStudioFollowersService
{
    public function list(User $user, array $filters = []): array
    {
        $perPage = 30;
        $search = trim((string) ($filters['q'] ?? ''));
        $sort = (string) ($filters['sort'] ?? 'recent');
        $relationship = (string) ($filters['relationship'] ?? 'all');
        $page = max(1, (int) ($filters['page'] ?? 1));

        $allowedSorts = ['recent', 'oldest', 'name', 'uploads', 'followers'];
        $allowedRelationships = ['all', 'following-back', 'not-followed'];

        if (! in_array($sort, $allowedSorts, true)) {
            $sort = 'recent';
        }

        if (! in_array($relationship, $allowedRelationships, true)) {
            $relationship = 'all';
        }

        $baseQuery = DB::table('user_followers as uf')
            ->join('users as u', 'u.id', '=', 'uf.follower_id')
            ->leftJoin('user_profiles as up', 'up.user_id', '=', 'u.id')
            ->leftJoin('user_statistics as us', 'us.user_id', '=', 'u.id')
            ->leftJoin('user_followers as mutual', function ($join) use ($user): void {
                $join->on('mutual.user_id', '=', 'uf.follower_id')
                    ->where('mutual.follower_id', '=', $user->id);
            })
            ->where('uf.user_id', $user->id)
            ->whereNull('u.deleted_at')
            ->when($search !== '', function ($query) use ($search): void {
                $query->where(function ($inner) use ($search): void {
                    $inner->where('u.username', 'like', '%' . $search . '%')
                        ->orWhere('u.name', 'like', '%' . $search . '%');
                });
            })
            ->when($relationship === 'following-back', fn ($query) => $query->whereNotNull('mutual.created_at'))
            ->when($relationship === 'not-followed', fn ($query) => $query->whereNull('mutual.created_at'));

        $summaryBaseQuery = clone $baseQuery;

        $followers = $baseQuery
            ->when($sort === 'recent', fn ($query) => $query->orderByDesc('uf.created_at'))
            ->when($sort === 'oldest', fn ($query) => $query->orderBy('uf.created_at'))
            ->when($sort === 'name', fn ($query) => $query->orderByRaw('COALESCE(u.username, u.name) asc'))
            ->when($sort === 'uploads', fn ($query) => $query->orderByDesc('us.uploads_count')->orderByRaw('COALESCE(u.username, u.name) asc'))
            ->when($sort === 'followers', fn ($query) => $query->orderByDesc('us.followers_count')->orderByRaw('COALESCE(u.username, u.name) asc'))
            ->select([
                'u.id',
                'u.username',
                'u.name',
                'up.avatar_hash',
                'us.uploads_count',
                'us.followers_count',
                'uf.created_at as followed_at',
                'mutual.created_at as followed_back_at',
            ])
            ->paginate($perPage, ['*'], 'page', $page)
            ->withQueryString();

        return [
            'items' => collect($followers->items())->map(fn ($row): array => [
                'id' => (int) $row->id,
                'name' => $row->name ?: '@' . $row->username,
                'username' => $row->username,
                'avatar_url' => AvatarUrl::forUser((int) $row->id, $row->avatar_hash, 64),
                'profile_url' => '/@' . strtolower((string) ($row->username ?? $row->id)),
                'uploads_count' => (int) ($row->uploads_count ?? 0),
                'followers_count' => (int) ($row->followers_count ?? 0),
                'is_following_back' => $row->followed_back_at !== null,
                'followed_back_at' => $row->followed_back_at,
                'followed_at' => $row->followed_at,
            ])->values()->all(),
            'meta' => [
                'current_page' => $followers->currentPage(),
                'last_page' => $followers->lastPage(),
                'per_page' => $followers->perPage(),
                'total' => $followers->total(),
            ],
            'filters' => [
                'q' => $search,
                'sort' => $sort,
                'relationship' => $relationship,
            ],
            'summary' => [
                'total_followers' => (clone $summaryBaseQuery)->count(),
                'following_back' => (clone $summaryBaseQuery)->whereNotNull('mutual.created_at')->count(),
                'not_followed' => (clone $summaryBaseQuery)->whereNull('mutual.created_at')->count(),
            ],
            'sort_options' => [
                ['value' => 'recent', 'label' => 'Most recent'],
                ['value' => 'oldest', 'label' => 'Oldest first'],
                ['value' => 'name', 'label' => 'Name A-Z'],
                ['value' => 'uploads', 'label' => 'Most uploads'],
                ['value' => 'followers', 'label' => 'Most followers'],
            ],
            'relationship_options' => [
                ['value' => 'all', 'label' => 'All followers'],
                ['value' => 'following-back', 'label' => 'Following back'],
                ['value' => 'not-followed', 'label' => 'Not followed yet'],
            ],
        ];
    }
}