<?php

namespace App\Modules\Admin\Tenancy\Services;

use App\Modules\Admin\Tenancy\Models\PlanLimit;
use App\Modules\Admin\Tenancy\Models\Tenant;
use App\Modules\Admin\Tenancy\Repositories\PlanLimitRepository;
use App\Modules\Admin\Tenancy\Support\PlanLimitKeys;

class CustomFieldsPlanService
{
    public const LIMIT_KEY = 'custom_fields';

    public function __construct(
        private readonly PlanLimitEnforcementService $planLimits,
        private readonly PlanLimitRepository $planLimitRows,
    ) {}

    public function isEnabledForTenant(?Tenant $tenant): bool
    {
        $row = $this->limitRow($tenant);
        if ($row === null) {
            return false;
        }

        return (bool) $row->is_enabled;
    }

    /**
     * @return int|null null when disabled / unlimited; 0+ when capped
     */
    public function maxFieldsCap(?Tenant $tenant): ?int
    {
        if ($tenant === null || ! $this->isEnabledForTenant($tenant)) {
            return null;
        }

        return $this->planLimits->effectiveCap($tenant, PlanLimitKeys::CUSTOM_FIELDS_LIMIT);
    }

    public function isUnlimited(?Tenant $tenant): bool
    {
        if ($tenant === null || ! $this->isEnabledForTenant($tenant)) {
            return false;
        }

        return $this->planLimits->effectiveCap($tenant, PlanLimitKeys::CUSTOM_FIELDS_LIMIT) === null;
    }

    public function canAddField(Tenant $tenant, int $currentActiveFieldCount): bool
    {
        if (! $this->isEnabledForTenant($tenant)) {
            return false;
        }
        $cap = $this->planLimits->effectiveCap($tenant, PlanLimitKeys::CUSTOM_FIELDS_LIMIT);
        if ($cap === null) {
            return true;
        }

        return $currentActiveFieldCount < $cap;
    }

    private function limitRow(?Tenant $tenant): ?PlanLimit
    {
        if ($tenant === null) {
            return null;
        }
        $planId = $this->resolvePlanId($tenant);
        if ($planId === null) {
            return null;
        }

        return $this->planLimitRows->findForPlan($planId, self::LIMIT_KEY);
    }

    private function resolvePlanId(Tenant $tenant): ?int
    {
        $tenant->loadMissing('activeSubscription', 'plan');

        return $tenant->activeSubscription?->plan_id ?? $tenant->plan_id;
    }
}
