<?php

namespace App\Modules\Settings\Onboarding\Services;

use App\Models\User;
use App\Modules\Admin\Operations\Repositories\PlatformAuditRepository;
use App\Modules\Admin\Tenancy\Models\Tenant;
use App\Modules\Admin\Tenancy\Repositories\TenantRepository;
use App\Modules\Admin\Tenancy\Support\TenantLifecycleState;

class TenantOnboardingService
{
    private const CAT = 'onboarding';

    public function __construct(
        private readonly TenantRepository $tenants,
        private readonly PlatformAuditRepository $audit,
    ) {}

    /**
     * @param  array<string, mixed>  $profile
     */
    public function saveCompanyProfile(Tenant $tenant, User $actor, array $profile): Tenant
    {
        $progress = $this->mergeProgress($tenant, ['profile' => true, 'current_step' => 'locale']);
        $updated = $this->tenants->update($tenant, [
            'company_profile' => array_merge($tenant->company_profile ?? [], $profile),
            'onboarding_progress' => $progress,
        ]);
        $this->audit->record((int) $actor->id, (int) $tenant->id, self::CAT, 'step.company_profile', []);

        return $updated;
    }

    public function saveLocale(Tenant $tenant, User $actor, string $localeCode): Tenant
    {
        $progress = $this->mergeProgress($tenant, ['locale' => true, 'current_step' => 'timezone']);
        $updated = $this->tenants->update($tenant, [
            'locale' => $localeCode,
            'onboarding_progress' => $progress,
        ]);
        $this->audit->record((int) $actor->id, (int) $tenant->id, self::CAT, 'step.locale', ['locale' => $localeCode]);

        return $updated;
    }

    public function saveTimezone(Tenant $tenant, User $actor, string $timezone): Tenant
    {
        $progress = $this->mergeProgress($tenant, ['timezone' => true, 'current_step' => 'modules_preview']);
        $updated = $this->tenants->update($tenant, [
            'timezone' => $timezone,
            'onboarding_progress' => $progress,
        ]);
        $this->audit->record((int) $actor->id, (int) $tenant->id, self::CAT, 'step.timezone', ['timezone' => $timezone]);

        return $updated;
    }

    public function acknowledgeModulePreview(Tenant $tenant, User $actor): Tenant
    {
        $progress = $this->mergeProgress($tenant, ['modules_preview' => true, 'current_step' => 'complete']);
        $updated = $this->tenants->update($tenant, ['onboarding_progress' => $progress]);
        $this->audit->record((int) $actor->id, (int) $tenant->id, self::CAT, 'step.modules_preview', []);

        return $updated;
    }

    public function complete(Tenant $tenant, User $actor): Tenant
    {
        $updated = $this->tenants->update($tenant, [
            'lifecycle_state' => TenantLifecycleState::ACTIVE,
            'onboarding_completed_at' => now(),
            'onboarding_progress' => array_merge($this->mergeProgress($tenant, []), ['current_step' => 'done']),
        ]);
        $this->audit->record((int) $actor->id, (int) $tenant->id, self::CAT, 'completed', []);

        return $updated;
    }

    /**
     * @param  array<string, mixed>  $patch
     * @return array<string, mixed>
     */
    private function mergeProgress(Tenant $tenant, array $patch): array
    {
        $base = $tenant->onboarding_progress ?? [
            'profile' => false,
            'locale' => false,
            'timezone' => false,
            'modules_preview' => false,
            'current_step' => 'profile',
        ];

        return array_merge($base, $patch);
    }
}
