<?php

namespace GriffinForms\Includes\Ai\PromptRegistry;

class SchemaDiffAnalyzer
{
    public function analyze(array $before, array $after): array
    {
        $page_diff = $this->analyzeEntries((array) ($before['pages'] ?? []), (array) ($after['pages'] ?? []), 'page');
        $field_diff = $this->analyzeEntries((array) ($before['fields'] ?? []), (array) ($after['fields'] ?? []), 'field');

        return [
            'pages' => $page_diff,
            'fields' => $field_diff,
            'summary' => [
                'added_pages' => count($page_diff['added']),
                'preserved_pages' => count($page_diff['preserved']),
                'removed_pages' => count($page_diff['removed']),
                'ambiguous_pages' => count($page_diff['ambiguous']),
                'added_fields' => count($field_diff['added']),
                'preserved_fields' => count($field_diff['preserved']),
                'removed_fields' => count($field_diff['removed']),
                'ambiguous_fields' => count($field_diff['ambiguous']),
            ],
        ];
    }

    protected function analyzeEntries(array $before_entries, array $after_entries, string $type): array
    {
        $before_counts = $this->signatureCounts($before_entries);
        $after_counts = $this->signatureCounts($after_entries);

        $ambiguous_signatures = [];
        foreach ($before_counts as $signature => $count) {
            if ($count > 1) {
                $ambiguous_signatures[$signature] = true;
            }
        }
        foreach ($after_counts as $signature => $count) {
            if ($count > 1) {
                $ambiguous_signatures[$signature] = true;
            }
        }

        $preserved = [];
        $added = [];
        $removed = [];
        $ambiguous = [];

        foreach ($before_entries as $entry) {
            $signature = (string) ($entry['signature'] ?? '');
            if ($signature === '' || isset($ambiguous_signatures[$signature])) {
                $ambiguous[] = $this->compactEntry($entry, $type);
                continue;
            }

            if (($after_counts[$signature] ?? 0) > 0) {
                $preserved[] = $this->compactEntry($entry, $type);
            } else {
                $removed[] = $this->compactEntry($entry, $type);
            }
        }

        foreach ($after_entries as $entry) {
            $signature = (string) ($entry['signature'] ?? '');
            if ($signature === '' || isset($ambiguous_signatures[$signature])) {
                $ambiguous[] = $this->compactEntry($entry, $type);
                continue;
            }

            if (($before_counts[$signature] ?? 0) === 0) {
                $added[] = $this->compactEntry($entry, $type);
            }
        }

        return [
            'added' => $this->dedupeCompactedEntries($added),
            'preserved' => $this->dedupeCompactedEntries($preserved),
            'removed' => $this->dedupeCompactedEntries($removed),
            'ambiguous' => $this->dedupeCompactedEntries($ambiguous),
        ];
    }

    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 compactEntry(array $entry, string $type): array
    {
        if ($type === 'page') {
            return [
                'signature' => (string) ($entry['signature'] ?? ''),
                'shadow_uid' => sanitize_text_field((string) ($entry['shadow_uid'] ?? '')),
                'name' => sanitize_text_field((string) ($entry['name'] ?? '')),
                'page_label' => sanitize_text_field((string) ($entry['page_label'] ?? '')),
            ];
        }

        return [
            'signature' => (string) ($entry['signature'] ?? ''),
            'shadow_uid' => sanitize_text_field((string) ($entry['shadow_uid'] ?? '')),
            'field_type' => sanitize_key((string) ($entry['field_type'] ?? '')),
            'label' => sanitize_text_field((string) ($entry['label'] ?? '')),
            'page_name' => sanitize_text_field((string) ($entry['page_name'] ?? '')),
            'page_label' => sanitize_text_field((string) ($entry['page_label'] ?? '')),
            'row_label' => sanitize_text_field((string) ($entry['row_label'] ?? '')),
            'column_label' => sanitize_text_field((string) ($entry['column_label'] ?? '')),
            'placeholder' => sanitize_text_field((string) ($entry['placeholder'] ?? '')),
        ];
    }

    protected function dedupeCompactedEntries(array $entries): array
    {
        $deduped = [];
        foreach ($entries as $entry) {
            $key = md5(wp_json_encode($entry));
            $deduped[$key] = $entry;
        }

        return array_values($deduped);
    }
}
