<?php

namespace App\Services\Subscription;

use App\Models\Company;
use Illuminate\Support\Facades\Cache;

/**
 * Resuelve qué módulos tiene activos una empresa.
 *
 * Reglas de resolución:
 *   1. Si existe override en company_modules para (company, module) → usa override.
 *   2. Si no → usa lo que defina plan_modules para el plan activo de la empresa.
 *   3. Si un módulo no está en el plan ni en overrides, se considera inactivo.
 *
 * El resultado se cachea por empresa para evitar consultar en cada request.
 */
class ModuleAccessService
{
    public const CACHE_TTL = 3600; // 1 hora

    /** Devuelve un array asociativo [module_key => bool]. */
    public function enabledModules(Company $company): array
    {
        return Cache::remember(
            $this->cacheKey($company),
            self::CACHE_TTL,
            fn () => $this->resolve($company),
        );
    }

    public function isEnabled(Company $company, string $moduleKey): bool
    {
        return (bool) ($this->enabledModules($company)[$moduleKey] ?? false);
    }

    public function flush(Company $company): void
    {
        Cache::forget($this->cacheKey($company));
    }

    public static function cacheKey(Company $company): string
    {
        return "company:{$company->id}:modules";
    }

    protected function resolve(Company $company): array
    {
        $result = [];

        // 1) Cargar override de la empresa
        $overrides = $company->moduleOverrides()
            ->with('module:id,key,is_core')
            ->get()
            ->keyBy('module.key');

        // 2) Cargar módulos del plan activo
        $planModules = $company->plan?->modules()
            ->wherePivot('is_enabled', true)
            ->get(['modules.id', 'modules.key', 'modules.is_core']) ?? collect();

        foreach ($planModules as $module) {
            $result[$module->key] = true;
        }

        // 3) Aplicar overrides (gana sobre plan)
        foreach ($overrides as $key => $override) {
            $result[$key] = (bool) $override->is_enabled;
        }

        return $result;
    }
}
