<?php

declare(strict_types=1);

namespace App\Policies;

use App\Models\Group;
use App\Models\User;

class GroupPolicy
{
    public function before($user, $ability)
    {
        if (! $user) {
            return null;
        }

        if ($this->isAdmin($user)) {
            return true;
        }

        return null;
    }

    public function view(?User $user, Group $group): bool
    {
        return $group->canBeViewedBy($user);
    }

    public function create(?User $user): bool
    {
        return (bool) $user;
    }

    public function update(User $user, Group $group): bool
    {
        return $group->canManage($user);
    }

    public function delete(User $user, Group $group): bool
    {
        return $group->isOwnedBy($user);
    }

    public function manageMembers(User $user, Group $group): bool
    {
        return $group->canManageMembers($user);
    }

    public function inviteMembers(User $user, Group $group): bool
    {
        return $group->canManageMembers($user);
    }

    public function changeRoles(User $user, Group $group): bool
    {
        return $group->canManageMembers($user);
    }

    public function archive(User $user, Group $group): bool
    {
        return $group->canArchive($user);
    }

    public function viewStudio(User $user, Group $group): bool
    {
        return $group->canViewStudio($user);
    }

    public function publishArtworks(User $user, Group $group): bool
    {
        return $group->canPublishArtworks($user);
    }

    public function manageCollections(User $user, Group $group): bool
    {
        return $group->canManageCollections($user);
    }

    public function requestJoin(User $user, Group $group): bool
    {
        return $group->canRequestJoin($user);
    }

    public function reviewJoinRequests(User $user, Group $group): bool
    {
        return $group->canReviewJoinRequests($user);
    }

    public function submitArtworkForReview(User $user, Group $group): bool
    {
        return $group->canSubmitArtworkForReview($user);
    }

    public function reviewSubmissions(User $user, Group $group): bool
    {
        return $group->canReviewSubmissions($user);
    }

    public function manageRecruitment(User $user, Group $group): bool
    {
        return $group->canManageRecruitment($user);
    }

    public function managePosts(User $user, Group $group): bool
    {
        return $group->canManagePosts($user);
    }

    public function publishPosts(User $user, Group $group): bool
    {
        return $group->canPublishPosts($user);
    }

    public function pinPosts(User $user, Group $group): bool
    {
        return $group->canPinPosts($user);
    }

    public function manageMemberPermissions(User $user, Group $group): bool
    {
        return $group->canManageMemberPermissions($user);
    }

    public function manageEvents(User $user, Group $group): bool
    {
        return $group->canManageEvents($user);
    }

    public function manageChallenges(User $user, Group $group): bool
    {
        return $group->canManageChallenges($user);
    }

    public function manageProjects(User $user, Group $group): bool
    {
        return $group->canManageProjects($user);
    }

    public function manageReleases(User $user, Group $group): bool
    {
        return $group->canManageReleases($user);
    }

    public function publishReleases(User $user, Group $group): bool
    {
        return $group->canPublishReleases($user);
    }

    public function moveReleaseStage(User $user, Group $group): bool
    {
        return $group->canManageReleases($user);
    }

    public function manageMilestones(User $user, Group $group): bool
    {
        return $group->canManageMilestones($user);
    }

    public function viewReputationDashboard(User $user, Group $group): bool
    {
        return $group->canViewReputationDashboard($user);
    }

    public function manageBadges(User $user, Group $group): bool
    {
        return $group->canManageBadges($user);
    }

    public function viewInternalTrustMetrics(User $user, Group $group): bool
    {
        return $group->canViewInternalTrustMetrics($user);
    }

    public function featureRelease(User $user, Group $group): bool
    {
        return $group->canFeatureReleases($user);
    }

    public function assignReleaseLead(User $user, Group $group): bool
    {
        return $group->canAssignReleaseLead($user);
    }

    public function manageAssets(User $user, Group $group): bool
    {
        return $group->canManageAssets($user);
    }

    public function viewInternalAssets(User $user, Group $group): bool
    {
        return $group->canViewInternalAssets($user);
    }

    public function featureChallengeEntries(User $user, Group $group): bool
    {
        return $group->canFeatureChallengeEntries($user);
    }

    public function participateInChallenge(User $user, Group $group): bool
    {
        return $group->isOperational() && $group->canViewStudio($user);
    }

    public function publishEventUpdates(User $user, Group $group): bool
    {
        return $group->canPublishEventUpdates($user);
    }

    public function attachAssetsToProjects(User $user, Group $group): bool
    {
        return $group->canAttachAssetsToProjects($user);
    }

    public function viewInternalEvents(User $user, Group $group): bool
    {
        return $group->canViewStudio($user);
    }

    public function viewPrivateProject(User $user, Group $group): bool
    {
        return $group->canViewStudio($user);
    }

    public function pinActivity(User $user, Group $group): bool
    {
        return $group->canPinActivity($user);
    }

    private function isAdmin(User $user): bool
    {
        if (method_exists($user, 'isAdmin')) {
            return (bool) $user->isAdmin();
        }

        if (method_exists($user, 'hasRole')) {
            return (bool) $user->hasRole('admin');
        }

        return false;
    }
}