<?php

namespace App\Modules\Customization\CustomFields\Services;

use App\Modules\Admin\Tenancy\Models\Tenant;
use App\Modules\Admin\Tenancy\Services\CustomFieldsPlanService;
use App\Modules\Customization\CustomFields\Models\CustomField;
use App\Modules\Customization\CustomFields\Repositories\CustomFieldRepository;
use App\Modules\Customization\CustomFields\Repositories\CustomFieldValueRepository;
use App\Modules\Customization\CustomFields\Support\CustomFieldType;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Validation\Rule;

class CustomFieldRendererService
{
    public function __construct(
        private readonly CustomFieldRepository $fields,
        private readonly CustomFieldValueRepository $values,
        private readonly CustomFieldsPlanService $plan,
    ) {}

    /**
     * @return Collection<int, CustomField>
     */
    public function definitionsFor(?Tenant $tenant, string $module, string $entity): Collection
    {
        if ($tenant === null || ! $this->plan->isEnabledForTenant($tenant)) {
            return new Collection;
        }

        return $this->fields->activeDefinitionsFor((int) $tenant->id, $module, $entity);
    }

    /**
     * @return array<string, list<mixed>>
     */
    public function validationRules(?Tenant $tenant, string $module, string $entity): array
    {
        $defs = $this->definitionsFor($tenant, $module, $entity);
        if ($defs->isEmpty()) {
            return [
                'custom_fields' => ['nullable', 'array'],
            ];
        }

        $out = ['custom_fields' => ['nullable', 'array']];
        foreach ($defs as $field) {
            $key = 'custom_fields.'.$field->slug;
            $rules = CustomFieldRuleBuilder::rulesForInput($field)[$key];
            if (in_array($field->field_type, [CustomFieldType::SELECT, CustomFieldType::RADIO], true)) {
                $allowed = $field->options->pluck('value')->all();
                if ($allowed !== []) {
                    $rules[] = Rule::in($allowed);
                }
            }
            $out[$key] = $rules;
        }

        return $out;
    }

    /**
     * @return array<string, string|null>
     */
    public function valuesMapFor(?Tenant $tenant, string $entityType, int $entityId): array
    {
        if ($tenant === null) {
            return [];
        }

        return $this->values->valuesBySlugForEntity((int) $tenant->id, $entityType, $entityId);
    }
}
