<?php

declare(strict_types=1);

namespace App\Services;

use App\Models\Group;
use App\Models\User;
use App\Support\AvatarUrl;
use Illuminate\Support\Str;

class GroupCardService
{
    public function __construct(
        private readonly GroupRecruitmentService $recruitment,
        private readonly GroupReputationService $reputation,
        private readonly GroupFollowService $follows,
        private readonly GroupMembershipService $memberships,
    ) {
    }

    public function mapGroupCard(Group $group, ?User $viewer = null): array
    {
        $owner = $group->relationLoaded('owner') ? $group->owner : $group->owner()->with('profile')->first();
        $recruitment = $this->recruitment->payloadForGroup($group);
        $viewerRole = $viewer ? $group->activeRoleFor($viewer) : null;
        $canManage = $viewer ? $group->canManage($viewer) : false;
        $canManageMembers = $viewer ? $group->canManageMembers($viewer) : false;
        $canPublishArtworks = $viewer ? $group->canPublishArtworks($viewer) : false;
        $canManageCollections = $viewer ? $group->canManageCollections($viewer) : false;
        $canRequestJoin = $viewer ? $group->canRequestJoin($viewer) : false;
        $canReviewJoinRequests = $viewer ? $group->canReviewJoinRequests($viewer) : false;
        $canReviewSubmissions = $viewer ? $group->canReviewSubmissions($viewer) : false;
        $canManageRecruitment = $viewer ? $group->canManageRecruitment($viewer) : false;
        $canManagePosts = $viewer ? $group->canManagePosts($viewer) : false;
        $canPublishPosts = $viewer ? $group->canPublishPosts($viewer) : false;
        $canPinPosts = $viewer ? $group->canPinPosts($viewer) : false;
        $canManageMemberPermissions = $viewer ? $group->canManageMemberPermissions($viewer) : false;
        $canManageProjects = $viewer ? $group->canManageProjects($viewer) : false;
        $canManageReleases = $viewer ? $group->canManageReleases($viewer) : false;
        $canPublishReleases = $viewer ? $group->canPublishReleases($viewer) : false;
        $canManageMilestones = $viewer ? $group->canManageMilestones($viewer) : false;
        $canViewReputationDashboard = $viewer ? $group->canViewReputationDashboard($viewer) : false;
        $canManageBadges = $viewer ? $group->canManageBadges($viewer) : false;
        $canViewInternalTrustMetrics = $viewer ? $group->canViewInternalTrustMetrics($viewer) : false;
        $canManageChallenges = $viewer ? $group->canManageChallenges($viewer) : false;
        $canManageEvents = $viewer ? $group->canManageEvents($viewer) : false;
        $canPublishEventUpdates = $viewer ? $group->canPublishEventUpdates($viewer) : false;
        $canManageAssets = $viewer ? $group->canManageAssets($viewer) : false;
        $canViewInternalAssets = $viewer ? $group->canViewInternalAssets($viewer) : false;
        $canPinActivity = $viewer ? $group->canPinActivity($viewer) : false;
        $trustSignals = $this->reputation->trustSignals($group);
        $badges = $this->reputation->groupBadges($group, 6);

        return [
            'id' => (int) $group->id,
            'entity_type' => 'group',
            'name' => (string) $group->name,
            'slug' => (string) $group->slug,
            'headline' => $group->headline,
            'bio_excerpt' => Str::limit((string) ($group->bio ?? ''), 180),
            'visibility' => (string) $group->visibility,
            'status' => (string) ($group->status ?? Group::LIFECYCLE_ACTIVE),
            'membership_policy' => (string) ($group->membership_policy ?? Group::MEMBERSHIP_INVITE_ONLY),
            'type' => $group->type,
            'is_verified' => (bool) $group->is_verified,
            'is_recruiting' => (bool) ($recruitment['is_recruiting'] ?? false),
            'recruitment_headline' => $recruitment['headline'] ?? null,
            'avatar_url' => $group->avatarUrl(),
            'banner_url' => $group->bannerUrl(),
            'owner' => [
                'id' => (int) ($owner?->id ?? 0),
                'name' => $owner?->name,
                'username' => $owner?->username,
                'avatar_url' => $owner ? AvatarUrl::forUser((int) $owner->id, $owner->profile?->avatar_hash, 72) : null,
                'profile_url' => $owner?->username ? route('profile.show', ['username' => strtolower((string) $owner->username)]) : null,
            ],
            'counts' => [
                'artworks' => (int) $group->artworks_count,
                'collections' => (int) $group->collections_count,
                'followers' => (int) $group->followers_count,
                'members' => $group->relationLoaded('members')
                    ? (int) $group->members->where('status', Group::STATUS_ACTIVE)->count()
                    : (int) $group->members()->where('status', Group::STATUS_ACTIVE)->count(),
            ],
            'permissions' => [
                'can_manage' => $canManage,
                'can_manage_members' => $canManageMembers,
                'can_publish_artworks' => $canPublishArtworks,
                'can_manage_collections' => $canManageCollections,
                'can_request_join' => $canRequestJoin,
                'can_review_join_requests' => $canReviewJoinRequests,
                'can_submit_artwork_for_review' => $viewer ? $group->canSubmitArtworkForReview($viewer) : false,
                'can_review_submissions' => $canReviewSubmissions,
                'can_manage_recruitment' => $canManageRecruitment,
                'can_manage_posts' => $canManagePosts,
                'can_publish_posts' => $canPublishPosts,
                'can_pin_posts' => $canPinPosts,
                'can_manage_member_permissions' => $canManageMemberPermissions,
                'can_manage_projects' => $canManageProjects,
                'can_manage_releases' => $canManageReleases,
                'can_publish_releases' => $canPublishReleases,
                'can_manage_milestones' => $canManageMilestones,
                'can_view_reputation_dashboard' => $canViewReputationDashboard,
                'can_manage_badges' => $canManageBadges,
                'can_view_internal_trust_metrics' => $canViewInternalTrustMetrics,
                'can_manage_challenges' => $canManageChallenges,
                'can_manage_events' => $canManageEvents,
                'can_publish_event_updates' => $canPublishEventUpdates,
                'can_manage_assets' => $canManageAssets,
                'can_view_internal_assets' => $canViewInternalAssets,
                'can_pin_activity' => $canPinActivity,
            ],
            'trust_signals' => $trustSignals,
            'badges' => $badges,
            'badge_keys' => array_values(array_filter(array_map(
                static fn (array $badge): ?string => $badge['key'] ?? null,
                $badges,
            ))),
            'viewer' => [
                'role' => $viewerRole,
                'role_label' => $viewerRole ? Group::displayRole($viewerRole) : null,
                'is_following' => $viewer
                    ? (array_key_exists('viewer_is_following', $group->getAttributes())
                        ? (bool) $group->viewer_is_following
                        : $this->follows->isFollowing($group, $viewer))
                    : false,
                'permission_overrides' => $viewer ? $group->permissionOverridesFor($viewer) : [],
            ],
            'urls' => [
                'public' => $group->publicUrl(),
                'studio' => route('studio.groups.show', ['group' => $group]),
                'studio_artworks' => route('studio.groups.artworks', ['group' => $group]),
                'studio_collections' => route('studio.groups.collections', ['group' => $group]),
                'studio_members' => route('studio.groups.members', ['group' => $group]),
                'studio_invitations' => $canManageMembers ? route('studio.groups.invitations', ['group' => $group]) : null,
                'studio_join_requests' => $canReviewJoinRequests ? route('studio.groups.join-requests', ['group' => $group]) : null,
                'studio_review' => $canReviewSubmissions ? route('studio.groups.review', ['group' => $group]) : null,
                'studio_recruitment' => $canManageRecruitment ? route('studio.groups.recruitment', ['group' => $group]) : null,
                'studio_posts' => $canManagePosts ? route('studio.groups.posts.index', ['group' => $group]) : null,
                'studio_projects' => $canManageProjects ? route('studio.groups.projects.index', ['group' => $group]) : null,
                'studio_releases' => $canManageReleases ? route('studio.groups.releases.index', ['group' => $group]) : null,
                'studio_reputation' => $canViewReputationDashboard ? route('studio.groups.reputation', ['group' => $group]) : null,
                'studio_challenges' => $canManageChallenges ? route('studio.groups.challenges.index', ['group' => $group]) : null,
                'studio_events' => ($canManageEvents || $canPublishEventUpdates) ? route('studio.groups.events.index', ['group' => $group]) : null,
                'studio_assets' => ($canManageAssets || $canViewInternalAssets) ? route('studio.groups.assets.index', ['group' => $group]) : null,
                'studio_activity' => route('studio.groups.activity', ['group' => $group]),
                'studio_settings' => $canManage ? route('studio.groups.settings', ['group' => $group]) : null,
                'upload' => ($canPublishArtworks || ($viewer && $group->canCreateArtworkDrafts($viewer))) ? route('upload', ['group' => $group->slug]) : null,
                'collection_create' => $canManageCollections ? route('settings.collections.create', ['group' => $group->slug]) : null,
                'follow' => route('groups.follow', ['group' => $group]),
                'unfollow' => route('groups.unfollow', ['group' => $group]),
                'join_request_store' => $canRequestJoin ? route('groups.join-requests.store', ['group' => $group]) : null,
                'join_request_withdraw_pattern' => $viewer ? route('groups.join-requests.destroy', ['group' => $group, 'joinRequest' => '__JOIN_REQUEST__']) : null,
                'posts' => route('groups.section', ['group' => $group, 'section' => 'posts']),
                'projects' => route('groups.section', ['group' => $group, 'section' => 'projects']),
                'releases' => route('groups.section', ['group' => $group, 'section' => 'releases']),
                'challenges' => route('groups.section', ['group' => $group, 'section' => 'challenges']),
                'events' => route('groups.section', ['group' => $group, 'section' => 'events']),
                'activity' => route('groups.section', ['group' => $group, 'section' => 'activity']),
            ],
            'pending_invites_count' => $this->memberships->pendingInviteCount($group),
        ];
    }
}