<?php

declare(strict_types=1);

namespace Plugins\Larablog\Membership\Domain;

use App\Models\User;
use Plugins\Larablog\Membership\Models\MembershipPlan;
use Plugins\Larablog\Payment\Domain\OrderService;
use Plugins\Larablog\Payment\Domain\ProductType;
use Plugins\Larablog\Payment\Models\Entitlement;

class MembershipService
{
    public function __construct(
        protected OrderService $orders,
    ) {}

    public function isActive(?User $user): bool
    {
        if ($user === null) {
            return false;
        }

        return $this->orders->hasActiveAny((int) $user->id, ProductType::MEMBERSHIP);
    }

    public function hasPlan(?User $user, int $planId): bool
    {
        if ($user === null) {
            return false;
        }

        return $this->orders->hasEntitlement((int) $user->id, ProductType::MEMBERSHIP, $planId);
    }

    /**
     * @return array{active: bool, plan_id: ?int, plan_slug: ?string, plan_name: ?string, expires_at: ?string}
     */
    public function statusFor(?User $user): array
    {
        if ($user === null) {
            return [
                'active' => false,
                'plan_id' => null,
                'plan_slug' => null,
                'plan_name' => null,
                'expires_at' => null,
            ];
        }

        $entitlement = Entitlement::query()
            ->active()
            ->where('user_id', $user->id)
            ->where('product_type', ProductType::MEMBERSHIP)
            ->orderByRaw('expires_at is null desc')
            ->orderByDesc('expires_at')
            ->first();

        if ($entitlement === null) {
            return [
                'active' => false,
                'plan_id' => null,
                'plan_slug' => null,
                'plan_name' => null,
                'expires_at' => null,
            ];
        }

        $plan = MembershipPlan::query()->find($entitlement->product_id);

        return [
            'active' => true,
            'plan_id' => (int) $entitlement->product_id,
            'plan_slug' => $plan?->slug,
            'plan_name' => $plan?->name,
            'expires_at' => optional($entitlement->expires_at)?->toIso8601String(),
        ];
    }

    public function cheapestEnabledPlan(): ?MembershipPlan
    {
        return MembershipPlan::query()
            ->enabled()
            ->orderBy('price')
            ->orderBy('sort_order')
            ->first();
    }
}
