<?php

declare(strict_types=1);

namespace App\Services;

use App\Models\MemberLevel;
use App\Models\User;
use App\Notifications\LevelUp;

class MemberLevelService
{
    /**
     * Recalculate the user's level based on their current point balance.
     * Returns the new level if it changed, otherwise null.
     */
    public function recalculate(User $user): ?int
    {
        $levels = MemberLevel::query()
            ->where('tenant_id', $user->tenant_id)
            ->orderBy('min_points', 'desc')
            ->get();

        if ($levels->isEmpty()) {
            return null;
        }

        $newLevel = 1;
        foreach ($levels as $lvl) {
            if ($user->points >= $lvl->min_points) {
                $newLevel = $lvl->level;
                break;
            }
        }

        if ($newLevel !== (int) $user->level) {
            $oldLevel = (int) $user->level;
            $user->level = $newLevel;
            $user->last_level_up_at = now();
            $user->save();

            if ($newLevel > $oldLevel) {
                try {
                    $user->notify(new LevelUp($newLevel, $oldLevel));
                } catch (\Throwable $e) {
                    // best-effort notification
                }
            }
            return $newLevel;
        }

        return null;
    }

    public function currentLevel(User $user): ?MemberLevel
    {
        return MemberLevel::query()
            ->where('tenant_id', $user->tenant_id)
            ->where('level', $user->level)
            ->first();
    }

    public function nextLevel(User $user): ?MemberLevel
    {
        return MemberLevel::query()
            ->where('tenant_id', $user->tenant_id)
            ->where('level', '>', $user->level)
            ->orderBy('level', 'asc')
            ->first();
    }
}
