<?php

declare(strict_types=1);

namespace App\Policies;

use Illuminate\Auth\Access\Response;
use App\Models\ArtworkAward;
use App\Models\Artwork;
use App\Models\User;

class ArtworkAwardPolicy
{
    /**
     * Admins bypass all checks.
     */
    public function before(User $user, string $ability): ?bool
    {
        if (method_exists($user, 'isAdmin') && $user->isAdmin()) {
            return true;
        }

        return null;
    }

    /**
     * Any authenticated user with a mature account may award any artwork
     * that isn't their own.
     * Returns false (→ 403 or 404 based on caller) when the check fails.
     */
    public function award(User $user, Artwork $artwork): Response
    {
        if (! config('artwork_medals.enabled', true)) {
            return Response::deny('Artwork medals are currently disabled.');
        }

        if (! $artwork->is_public || ! $artwork->is_approved) {
            return Response::deny('This artwork is not eligible for medals.');
        }

        if ($artwork->deleted_at !== null) {
            return Response::deny('This artwork is no longer available for medals.');
        }

        if ($artwork->published_at === null || $artwork->published_at->isFuture()) {
            return Response::deny('This artwork is not published yet.');
        }

        if ($artwork->user_id === $user->id) {
            return Response::deny('You cannot medal your own artwork.');
        }

        return $this->accountIsMature($user);
    }

    /**
     * The user may change a medal they already placed.
     */
    public function change(User $user, ArtworkAward $award): bool
    {
        return $user->id === $award->user_id;
    }

    /**
     * The user may remove a medal they already placed.
     */
    public function remove(User $user, ArtworkAward $award): bool
    {
        return $user->id === $award->user_id;
    }

    // -------------------------------------------------------------------------

    private function accountIsMature(User $user): Response
    {
        if ((bool) config('artwork_medals.require_verified_email', true)) {
            $isVerified = method_exists($user, 'hasVerifiedEmail')
                ? $user->hasVerifiedEmail()
                : ! empty($user->email_verified_at);

            if (! $isVerified) {
                return Response::deny('Verify your email address before giving medals.');
            }
        }

        if (! $user->created_at) {
            return Response::allow(); // cannot verify — allow
        }

        $minimumAgeHours = (int) config('artwork_medals.minimum_account_age_hours', 24);

        if ($user->created_at->diffInHours(now()) < $minimumAgeHours) {
            return Response::deny("Your account must be at least {$minimumAgeHours} hours old before giving medals.");
        }

        return Response::allow();
    }
}
