<?php

namespace App\Modules\Customization\CustomFields\Services;

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\CustomFieldEntity;
use App\Modules\Customization\CustomFields\Support\CustomFieldType;
use App\Modules\HR\Employees\Models\Employee;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Http\UploadedFile;

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

    public function syncForEmployee(
        Employee $employee,
        array $valueBag,
        array $fileBag,
    ): void {
        $employee->loadMissing('tenant');
        $tenant = $employee->tenant;
        if ($tenant === null || ! $this->plan->isEnabledForTenant($tenant)) {
            return;
        }
        $tenantId = (int) $employee->tenant_id;
        /** @var Collection<int, CustomField> $defs */
        $defs = $this->fields->activeDefinitionsFor($tenantId, 'hr', 'employees');
        if ($defs->isEmpty()) {
            return;
        }

        foreach ($defs as $field) {
            $this->syncOne($employee, $field, $valueBag, $fileBag, $tenantId);
        }
    }

    /**
     * @param  array<string, mixed>  $valueBag
     * @param  array<string, mixed>  $fileBag
     */
    private function syncOne(
        Employee $employee,
        CustomField $field,
        array $valueBag,
        array $fileBag,
        int $tenantId,
    ): void {
        if ($field->field_type === CustomFieldType::FILE) {
            $upload = $fileBag[$field->slug] ?? null;
            if ($upload instanceof UploadedFile) {
                $map = $this->values->valuesBySlugForEntity($tenantId, CustomFieldEntity::EMPLOYEE, $employee->id);
                $existing = $map[$field->slug] ?? null;
                $this->storage->deleteIfExists($existing);
                $path = $this->storage->store($upload, $tenantId, $field->id);
                $this->values->upsertValue($tenantId, $field->id, CustomFieldEntity::EMPLOYEE, $employee->id, $path);
            }

            return;
        }

        $raw = $valueBag[$field->slug] ?? null;
        if ($field->field_type === CustomFieldType::CHECKBOX) {
            $stored = ($raw === true || $raw === 1 || $raw === '1' || $raw === 'on') ? '1' : '0';
        } elseif (is_array($raw)) {
            $stored = json_encode($raw);
        } else {
            $stored = $raw === null || $raw === '' ? null : (string) $raw;
        }

        $this->values->upsertValue($tenantId, $field->id, CustomFieldEntity::EMPLOYEE, $employee->id, $stored);
    }
}
