<?php

namespace App\Modules\Customization\CustomFields\Repositories;

use App\Modules\Customization\CustomFields\Models\CustomField;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Support\Facades\Cache;

class CustomFieldRepository
{
    private const CACHE_TTL = 3600;

    public function forgetDefinitionsCache(int $tenantId, string $module, string $entity): void
    {
        Cache::forget($this->cacheKey($tenantId, $module, $entity));
    }

    /**
     * @return Collection<int, CustomField>
     */
    public function activeDefinitionsFor(int $tenantId, string $module, string $entity): Collection
    {
        $key = $this->cacheKey($tenantId, $module, $entity);

        /** @var Collection<int, CustomField> */
        return Cache::remember($key, self::CACHE_TTL, function () use ($tenantId, $module, $entity): Collection {
            return CustomField::query()
                ->where('tenant_id', $tenantId)
                ->where('module', $module)
                ->where('entity', $entity)
                ->where('is_active', true)
                ->with(['options' => fn ($q) => $q->orderBy('sort_order')])
                ->orderBy('sort_order')
                ->orderBy('id')
                ->get();
        });
    }

    public function countActiveForTenant(int $tenantId): int
    {
        return CustomField::query()
            ->where('tenant_id', $tenantId)
            ->where('is_active', true)
            ->count();
    }

    public function findOrFail(int $id): CustomField
    {
        return CustomField::query()->with('options')->findOrFail($id);
    }

    /**
     * @param  array<string, mixed>  $data
     */
    public function create(array $data): CustomField
    {
        return CustomField::query()->create($data);
    }

    /**
     * @param  array<string, mixed>  $data
     */
    public function update(CustomField $field, array $data): CustomField
    {
        $field->update($data);

        return $field->fresh(['options']);
    }

    /**
     * @param  list<int>  $orderedIds
     */
    public function reorder(int $tenantId, string $module, string $entity, array $orderedIds): void
    {
        $pos = 0;
        foreach ($orderedIds as $id) {
            CustomField::query()
                ->where('tenant_id', $tenantId)
                ->where('module', $module)
                ->where('entity', $entity)
                ->whereKey((int) $id)
                ->update(['sort_order' => $pos]);
            $pos++;
        }
    }

    private function cacheKey(int $tenantId, string $module, string $entity): string
    {
        return 'custom-fields:'.$tenantId.':'.$module.':'.$entity;
    }
}
