<?php

namespace App\Services\Intune;

use Illuminate\Support\Arr;
use Illuminate\Support\Str;

class TermsAndConditionsNormalizer implements PolicyTypeNormalizer
{
    public function __construct(
        private readonly DefaultPolicyNormalizer $defaultNormalizer,
    ) {}

    public function supports(string $policyType): bool
    {
        return $policyType === 'termsAndConditions';
    }

    /**
     * @return array{status: string, settings: array<int, array<string, mixed>>, warnings: array<int, string>}
     */
    public function normalize(?array $snapshot, string $policyType, ?string $platform = null): array
    {
        $snapshot = is_array($snapshot) ? $snapshot : [];
        $entries = [];

        $this->pushEntry($entries, 'Display name', Arr::get($snapshot, 'displayName'));
        $this->pushEntry($entries, 'Title', Arr::get($snapshot, 'title'));
        $this->pushEntry($entries, 'Description', Arr::get($snapshot, 'description'));
        $this->pushEntry($entries, 'Acceptance statement', Arr::get($snapshot, 'acceptanceStatement'));
        $this->pushEntry($entries, 'Body text', $this->limitText(Arr::get($snapshot, 'bodyText')));
        $this->pushEntry($entries, 'Version', Arr::get($snapshot, 'version'));

        $roleScopeTagIds = Arr::get($snapshot, 'roleScopeTagIds');
        if (is_array($roleScopeTagIds) && $roleScopeTagIds !== []) {
            $this->pushEntry($entries, 'Scope tag IDs', array_values($roleScopeTagIds));
        }

        if ($entries === []) {
            return [
                'status' => 'warning',
                'settings' => [],
                'warnings' => ['Terms & Conditions snapshot contains no readable fields.'],
            ];
        }

        return [
            'status' => 'ok',
            'settings' => [
                [
                    'type' => 'keyValue',
                    'title' => 'Terms & Conditions',
                    'entries' => $entries,
                ],
            ],
            'warnings' => [],
        ];
    }

    public function flattenForDiff(?array $snapshot, string $policyType, ?string $platform = null): array
    {
        $normalized = $this->normalize($snapshot ?? [], $policyType, $platform);

        return $this->defaultNormalizer->flattenNormalizedForDiff($normalized);
    }

    /**
     * @param  array<int, array<string, mixed>>  $entries
     */
    private function pushEntry(array &$entries, string $key, mixed $value): void
    {
        if ($value === null) {
            return;
        }

        if (is_string($value) && $value === '') {
            return;
        }

        $entries[] = [
            'key' => $key,
            'value' => $value,
        ];
    }

    private function limitText(mixed $value): mixed
    {
        if (! is_string($value)) {
            return $value;
        }

        return Str::limit($value, 1000);
    }
}
