/**
 * ANUNAKI Search Engine v1.0.0
 * Advanced fuzzy search with Fuse.js + diacritics normalization
 * Improvements over INTRO_1:
 * - Smarter postal code detection (supports EU formats)
 * - Locker ID auto-detection
 * - City+Street split with separator awareness
 * - Fuse.js integration with optimized thresholds
 */
;(function(window) {
    'use strict';

    var DIACRITICS_MAP = {
        'ą':'a','ć':'c','ę':'e','ł':'l','ń':'n','ó':'o','ś':'s','ź':'z','ż':'z',
        'à':'a','â':'a','ä':'a','é':'e','è':'e','ê':'e','ë':'e','ï':'i','î':'i',
        'ô':'o','ö':'o','ù':'u','û':'u','ü':'u','ÿ':'y','ç':'c','ñ':'n',
        'á':'a','í':'i','ú':'u','ő':'o','ű':'u','ř':'r','š':'s','č':'c','ž':'z',
        'ý':'y','ď':'d','ť':'t','ň':'n','ě':'e','ů':'u'
    };

    function normalize(text) {
        if (!text) return '';
        return String(text).toLowerCase()
            .replace(/[ąćęłńóśźżàâäéèêëïîôöùûüÿçñáíúőűřšč žýďťňěů]/g, function(c) {
                return DIACRITICS_MAP[c] || c;
            })
            .replace(/\s+/g, ' ').trim();
    }

    function sanitize(raw) {
        if (!raw) return '';
        return String(raw)
            .replace(/[\r\n\t]+/g, ' ')
            .replace(/['"\\<>]+/g, '')
            .replace(/[,;|\s]+$/g, '')
            .replace(/\s+/g, ' ').trim();
    }

    function detectPostalCode(raw) {
        var patterns = [
            /\b(\d{2})[-\s]?(\d{3})\b/,
            /\b(\d{4})\s?([A-Z]{2})\b/i,
            /\b(\d{5})\b/,
            /\b([A-Z]{1,2}\d{1,2})\s?(\d[A-Z]{2})\b/i
        ];
        for (var i = 0; i < patterns.length; i++) {
            var m = raw.match(patterns[i]);
            if (m) return { original: m[0], normalized: m[0].replace(/[\s-]/g, '').toUpperCase() };
        }
        return null;
    }

    function detectLockerId(raw) {
        if (!raw) return null;
        var compact = raw.replace(/\s+/g, '').toUpperCase();
        if (/^[A-Z]{2,4}\d{2,6}[A-Z]?$/.test(compact)) return compact;
        var tokens = raw.split(/\s+/);
        for (var i = 0; i < tokens.length; i++) {
            var t = tokens[i].toUpperCase();
            if (/^[A-Z]{2,4}\d{2,6}[A-Z]?$/.test(t)) return t;
        }
        return null;
    }

    var AnunakiSearch = {
        _fuse: null,
        _points: [],

        init: function(points) {
            this._points = points || [];
            if (typeof Fuse !== 'undefined' && this._points.length > 0) {
                var searchData = this._points.map(function(p) {
                    return {
                        n: p.n || '',
                        a: p.a || '',
                        l: p.l || '',
                        _norm_a: normalize(p.a || ''),
                        _norm_l: normalize(p.l || ''),
                        _norm_n: normalize(p.n || ''),
                        _ref: p
                    };
                });
                // NS-29 fix 2026-04-30: API zwraca:
                //   n = locker ID ("ADA01M") — rzadko szukane przez user
                //   l = nazwa sklepu/lokacji ("Przy sklepie Lewiatan") — NIE miasto
                //   a = adres + kod + MIASTO ("Kosciuszki 27, 21-412 Adamow") — TU jest miasto
                // User wpisuje miasto -> musi trafic w _norm_a (najwyzsza waga).
                // Plus threshold 0.35 + distance 100 byly za restrykcyjne -> zwiekszone.
                this._fuse = new Fuse(searchData, {
                    keys: [
                        { name: '_norm_a', weight: 0.5 },   // adres+miasto (gdzie miasto JEST)
                        { name: '_norm_l', weight: 0.3 },   // nazwa sklepu/lokacji
                        { name: '_norm_n', weight: 0.2 }    // locker ID
                    ],
                    threshold: 0.4,
                    distance: 200,
                    minMatchCharLength: 2,
                    includeScore: true,
                    ignoreLocation: true                    // miasto moze byc na koncu stringa adresu
                });
            }
        },

        search: function(query, limit) {
            limit = limit || 50;
            var q = sanitize(query);
            if (!q || q.length < 2) return [];

            var lockerId = detectLockerId(q);
            if (lockerId) {
                var exact = this._points.filter(function(p) {
                    return (p.n || '').toUpperCase() === lockerId;
                });
                if (exact.length > 0) return exact.slice(0, limit);
            }

            if (this._fuse) {
                var normQ = normalize(q);
                var results = this._fuse.search(normQ, { limit: limit });
                return results.map(function(r) { return r.item._ref; });
            }

            var qLower = normalize(q);
            return this._points.filter(function(p) {
                return normalize(p.n || '').indexOf(qLower) !== -1 ||
                       normalize(p.l || '').indexOf(qLower) !== -1 ||
                       normalize(p.a || '').indexOf(qLower) !== -1;
            }).slice(0, limit);
        }
    };

    window.AnunakiSearch = AnunakiSearch;
})(window);
