<?php

namespace GriffinForms\Includes\Ai\PromptRegistry;

class ShadowUidRegistry
{
    public function hydrateSnapshots(array $before_snapshot, array $target_snapshot, array $stored_registry = []): array
    {
        $before_snapshot = $this->assignSnapshotUids($before_snapshot, (array) ($stored_registry['pages'] ?? []), (array) ($stored_registry['fields'] ?? []));
        $target_snapshot = $this->inheritOrAssignSnapshotUids($target_snapshot, $before_snapshot);

        return [$before_snapshot, $target_snapshot];
    }

    public function buildRegistryFromSnapshot(array $snapshot): array
    {
        return [
            'pages' => $this->buildRegistrySection((array) ($snapshot['pages'] ?? [])),
            'fields' => $this->buildRegistrySection((array) ($snapshot['fields'] ?? [])),
            'updated_at' => current_time('mysql', true),
        ];
    }

    protected function assignSnapshotUids(array $snapshot, array $page_registry, array $field_registry): array
    {
        $page_counts = $this->signatureCounts((array) ($snapshot['pages'] ?? []));
        foreach ((array) ($snapshot['pages'] ?? []) as $index => $page) {
            $signature = (string) ($page['signature'] ?? '');
            if ($signature !== '' && ($page_counts[$signature] ?? 0) === 1 && !empty($page_registry[$signature])) {
                $snapshot['pages'][$index]['shadow_uid'] = sanitize_text_field((string) $page_registry[$signature]);
            } else {
                $snapshot['pages'][$index]['shadow_uid'] = $this->generateUid('page');
            }
        }

        $field_counts = $this->signatureCounts((array) ($snapshot['fields'] ?? []));
        foreach ((array) ($snapshot['fields'] ?? []) as $index => $field) {
            $signature = (string) ($field['signature'] ?? '');
            if ($signature !== '' && ($field_counts[$signature] ?? 0) === 1 && !empty($field_registry[$signature])) {
                $snapshot['fields'][$index]['shadow_uid'] = sanitize_text_field((string) $field_registry[$signature]);
            } else {
                $snapshot['fields'][$index]['shadow_uid'] = $this->generateUid('field');
            }
        }

        return $snapshot;
    }

    protected function inheritOrAssignSnapshotUids(array $target_snapshot, array $before_snapshot): array
    {
        $page_map = $this->nonAmbiguousUidMap((array) ($before_snapshot['pages'] ?? []));
        $field_map = $this->nonAmbiguousUidMap((array) ($before_snapshot['fields'] ?? []));

        $page_counts = $this->signatureCounts((array) ($target_snapshot['pages'] ?? []));
        foreach ((array) ($target_snapshot['pages'] ?? []) as $index => $page) {
            $signature = (string) ($page['signature'] ?? '');
            if ($signature !== '' && ($page_counts[$signature] ?? 0) === 1 && !empty($page_map[$signature])) {
                $target_snapshot['pages'][$index]['shadow_uid'] = $page_map[$signature];
            } else {
                $target_snapshot['pages'][$index]['shadow_uid'] = $this->generateUid('page');
            }
        }

        $field_counts = $this->signatureCounts((array) ($target_snapshot['fields'] ?? []));
        foreach ((array) ($target_snapshot['fields'] ?? []) as $index => $field) {
            $signature = (string) ($field['signature'] ?? '');
            if ($signature !== '' && ($field_counts[$signature] ?? 0) === 1 && !empty($field_map[$signature])) {
                $target_snapshot['fields'][$index]['shadow_uid'] = $field_map[$signature];
            } else {
                $target_snapshot['fields'][$index]['shadow_uid'] = $this->generateUid('field');
            }
        }

        return $target_snapshot;
    }

    protected function buildRegistrySection(array $entries): array
    {
        $registry = [];
        $counts = $this->signatureCounts($entries);

        foreach ($entries as $entry) {
            $signature = (string) ($entry['signature'] ?? '');
            $shadow_uid = (string) ($entry['shadow_uid'] ?? '');
            if ($signature === '' || $shadow_uid === '' || ($counts[$signature] ?? 0) !== 1) {
                continue;
            }

            $registry[$signature] = $shadow_uid;
        }

        return $registry;
    }

    protected function nonAmbiguousUidMap(array $entries): array
    {
        $map = [];
        $counts = $this->signatureCounts($entries);

        foreach ($entries as $entry) {
            $signature = (string) ($entry['signature'] ?? '');
            $shadow_uid = (string) ($entry['shadow_uid'] ?? '');
            if ($signature === '' || $shadow_uid === '' || ($counts[$signature] ?? 0) !== 1) {
                continue;
            }

            $map[$signature] = $shadow_uid;
        }

        return $map;
    }

    protected function signatureCounts(array $entries): array
    {
        $counts = [];
        foreach ($entries as $entry) {
            $signature = (string) ($entry['signature'] ?? '');
            if ($signature === '') {
                continue;
            }

            $counts[$signature] = ($counts[$signature] ?? 0) + 1;
        }

        return $counts;
    }

    protected function generateUid(string $prefix): string
    {
        return 'gf_shadow_' . sanitize_key($prefix) . '_' . str_replace('-', '', wp_generate_uuid4());
    }
}
