<?php
namespace App\Policies;

use App\Models\Artwork;
use App\Models\User;

class ArtworkPolicy
{
    /**
     * Global before hook: admins can do everything.
     * Accepts null $user to allow public checks to continue.
     */
    public function before($user, $ability)
    {
        if (! $user) {
            return null;
        }

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

        return null;
    }

    protected function isAdmin(User $user): bool
    {
        if (isset($user->is_admin)) {
            return (bool) $user->is_admin;
        }

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

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

        return false;
    }

    protected function isModerator(User $user): bool
    {
        foreach (['is_moderator', 'is_mod', 'moderator'] as $prop) {
            if (isset($user->{$prop})) {
                return (bool) $user->{$prop};
            }
        }

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

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

        return false;
    }

    /**
     * Public view: only approved + public + not-deleted artworks.
     */
    public function view(?User $user, Artwork $artwork): bool
    {
        return $artwork->is_public && $artwork->is_approved && ! $artwork->trashed();
    }

    /**
     * Any authenticated user can create artworks.
     */
    public function create(?User $user): bool
    {
        return (bool) $user;
    }

    /**
     * Owner can update their own artwork.
     */
    public function update(User $user, Artwork $artwork): bool
    {
        if ((int) ($artwork->group_id ?? 0) > 0) {
            if ((int) $artwork->user_id === (int) $user->id && (string) ($artwork->artwork_status ?? '') === 'draft') {
                return true;
            }

            return $artwork->group?->canPublishArtworks($user) ?? false;
        }

        return $user->id === $artwork->user_id;
    }

    /**
     * Tag edits: owner or moderator or admin (admin handled by before()).
     */
    public function updateTags(User $user, Artwork $artwork): bool
    {
        return $user->id === $artwork->user_id || $this->isModerator($user);
    }

    /**
     * Owner can delete their own artwork (soft delete).
     */
    public function delete(User $user, Artwork $artwork): bool
    {
        if ((int) ($artwork->group_id ?? 0) > 0) {
            if ((int) $artwork->user_id === (int) $user->id && (string) ($artwork->artwork_status ?? '') === 'draft') {
                return true;
            }

            return $artwork->group?->canPublishArtworks($user) ?? false;
        }

        return $user->id === $artwork->user_id;
    }

    /**
     * Restore: owner or admin can restore soft-deleted artwork.
     */
    public function restore(User $user, Artwork $artwork): bool
    {
        if ((int) ($artwork->group_id ?? 0) > 0) {
            return ($artwork->group?->canPublishArtworks($user) ?? false) || $this->isAdmin($user);
        }

        return $user->id === $artwork->user_id || $this->isAdmin($user);
    }

    /**
     * Force delete reserved for admins only.
     */
    public function forceDelete(User $user, Artwork $artwork): bool
    {
        return $this->isAdmin($user);
    }
}
