import{SCORE_FIELD as e,SCORE_FIELD_ORIGINAL as t}from"../../data/Feature.js";import{AsyncQueue as r}from"../../utilities/asyncIterable.js";import{map as s}from"../../utilities/promise.js";import{QueryService as a}from"../query/QueryService.js";import{SearchError as i}from"./SearchError.js";import{SearchOptions as o}from"./SearchOptions.js";import{SearchProviderBase as n}from"./SearchProviderBase.js";import{getSearchableValue as c}from"./_utilities.js";import{expandSearchArea as u,getSearchableFields as l,getWhereClause as m,initializeElasticlunrIndex as f,normalizeScores as p,separatorRegex as h}from"./support/_querySearchProviderUtils.js";export class QuerySearchProvider extends n{queryService=new a;quotedTermsRegex=/(?:"(.*?)")|(?:“(.*?)”)|(?:«(.*?)»)|(?:„(.*?)”)|(?:„(.*?)“)|(?:»(.*?)«)/g;isSupported(e){return this.queryService.isSupported(e)}getSearchTerms(e,t){const r=e.match(this.quotedTermsRegex),s=t(e.replace(this.quotedTermsRegex,""));return r?s.concat(r.map((e=>e.replace(/"|“|”|«|»|„/g,"")))):s}_search(s,a,n){const S=new r,d=new Map,x="__id";let g=0;const y=f(h),R=new i([]);return s.forEach((r=>{(async()=>{try{const{index:s,tokenizer:i}=await y;s.setRef(x);const f={...o.DEFAULTS,...o.fromFeatureSource(r),spatialFilter:n?.initialSearchArea,tokenizeSearchString:!0,...n},h=f.tokenizeSearchString?s.pipeline.run(this.getSearchTerms(a,i)):[a],g=l(r),R=m(r,h,g,f);if(!h.length||!g.length||!R)return;let{maxResults:w}=f;null!=f.maxQueryResults&&null!=f.maxResults&&(w=Math.max(f.maxQueryResults,f.maxResults));const F={...f,maxResults:w};let b=0,k=F.currentScale;const v=new Map,j=r.getFullExtent();for(const e of g)s.addField(e.name.toLowerCase());for(;;){if(S.isDone)return;const i=this.queryService.query(r,R,F),o=new Map;for await(const e of i){if(S.isDone)return;const t={};for(const r of g)t[r.name.toLowerCase()]=c(e,r);const a=`${r.id}-${e.primaryKey}`;t[x]=a,s.addDoc(t),o.set(a,e),d.set(a,e)}const n=s.search(a,{expand:!0});p(n);for(const r of n){const s=d.get(r.ref);if(s&&(s.attributes.set(e,r.score),s.attributes.set(t,r.score),o.has(r.ref)&&!v.has(r.ref)&&(v.set(r.ref,s),o.delete(r.ref),S.add(s),b++)),null!=f.maxResults&&b>=f.maxResults)break}for(const[r,s]of o){if(null!=f.maxResults&&b>=f.maxResults)break;s.attributes.set(e,50),s.attributes.set(t,50),v.has(r)||(v.set(r,s),S.add(s),b++)}if(null!=f.maxResults&&b>=f.maxResults)break;const{scale:l,geometry:m}=await u(F.spatialFilter?.extent??void 0,j,k,0===b?3:1);if(!m)break;F.spatialFilter=m,k=l}}catch(e){R.errors.set(r,e)}finally{++g===s.length&&(0===R.errors.size?S.done():S.reject(R))}})()})),S}async _count(e,t,r){return s(e,(async e=>{const{index:s,tokenizer:a}=await f(h),i={...o.fromFeatureSource(e),tokenizeSearchString:!0,...r,spatialFilter:r?.initialSearchArea,returnGeometry:!1},n=i.tokenizeSearchString?s.pipeline.run(this.getSearchTerms(t,a)):[t],c=l(e);if(!n.length||!c.length)return{source:e,count:0};const p=m(e,n,c,i);let S=i.currentScale;const d=e.getFullExtent();let x;for(;;){if(x=await this.queryService.count(e,p,i),x.count>=(i.maxResults??Number.MAX_SAFE_INTEGER))break;const{scale:t,geometry:r}=await u(i.spatialFilter?.extent??void 0,d,S,0===x.count?3:1);if(!r)break;i.spatialFilter=r.extent??void 0,S=t}return x}))}async _suggest(e,t,r){return[]}}