/* COPYRIGHT Esri - https://js.arcgis.com/5.0.18/LICENSE.txt */
import e from"../../../request.js";import{unique as t}from"../../../core/arrayUtils.js";import r from"../../../core/Error.js";import i from"../../../core/Logger.js";import{whenOrAbort as o,eachAlways as s}from"../../../core/promiseUtils.js";import{isNumericField as n}from"../../../layers/support/fieldUtils.js";import{executeQueryJSON as l}from"../../../rest/query/executeQueryJSON.js";import a from"../../../rest/support/Query.js";import u from"../../../rest/support/RelationshipQuery.js";import c from"../../../rest/support/StatisticDefinition.js";import{isRelatedField as f}from"./featureUtils.js";const d="esri.widgets.Feature.support.relatedFeatureUtils",p=()=>i.getLogger(d),m=new Map;function h(e){if(!f(e))return null;const[t,r]=e.split("/").slice(1);return{layerId:t,fieldName:r}}function y(e,t){if(!t.relationships)return null;let r=null;const{relationships:i}=t;return i.some(t=>t.id===parseInt(e,10)&&(r=t,!0)),r}function I({originRelationship:e,relationships:t,layerId:r}){return t.find(({relatedTableId:t,id:i})=>`${t}`===r&&i===e?.id)??null}function F(e,t){const r=t.toLowerCase();for(const i in e)if(i.toLowerCase()===r)return e[i];return null}function b(e,t){const r=y(e,t);if(!r)return;return{url:`${t.url}/${r.relatedTableId}`,sourceSpatialReference:t.spatialReference,relation:r,relatedFields:[],outStatistics:[]}}function g(e,t){if(!t)return;if(!e)return;const{features:r,statsFeatures:i}=e,o=r?.value;t.relatedFeatures=o?o.features:[];const s=i?.value;t.relatedStatsFeatures=s?s.features:[]}function S(e,t,r,i){const o=new u;return o.outFields=["*"],o.relationshipId="number"==typeof t.id?t.id:parseInt(t.id,10),o.objectIds=[e.attributes[r.objectIdField]],o.gdbVersion=r.gdbVersion??null,o.historicMoment=r.historicMoment??null,r.queryRelatedFeatures?.(o,i)??Promise.resolve({})}function w(e,t,r){let i=0;const o=[];for(;i<t.length;)o.push(`${e} IN (${t.slice(i,r+i)})`),i+=r;return o.join(" OR ")}function j(e){return e?t(e):void 0}function R(e){return e?t(e,(e,t)=>JSON.stringify(e.toJSON())===JSON.stringify(t.toJSON())):void 0}async function $(e,t,r,i){const o=r.layerId.toString(),{layerInfo:u,relation:c,relatedFields:f,outStatistics:d,url:p,sourceSpatialReference:m}=t,h=j(f),y=R(d);if(!u||!c)return null;const b=I({originRelationship:c,relationships:u.relationships,layerId:o});if(b?.relationshipTableId&&b.keyFieldInRelationshipTable){const t=(await S(e,b,r,i))[e.attributes[r.objectIdField]];if(!t)return null;const o=t.features.map(e=>e.attributes[u.objectIdField]);if(y?.length&&u.supportsStatistics){const e=new a;e.where=w(u.objectIdField,o,1e3),e.outFields=h,e.outStatistics=y,e.sourceSpatialReference=m;const r={features:Promise.resolve(t),statsFeatures:l(p,e)};return s(r)}}const g=b?.keyField;if(g){const t=n(L(u.fields,g)),o=F(e.attributes,c.keyField),f=t?`${g}=${o}`:`${g}='${o}'`,d=r.historicMoment,I=r.gdbVersion,b=l(p,new a({where:f,outFields:h,sourceSpatialReference:m,historicMoment:d,gdbVersion:I}),i),S=!!y?.length&&u.supportsStatistics?l(p,new a({where:f,outFields:h,outStatistics:y,sourceSpatialReference:m}),i):null,w={features:b};return S&&(w.statsFeatures=S),s(w)}return null}function N(t,r){return e(t,{query:{f:"json"},signal:r?.signal})}function v({relatedInfos:e,layer:t},i){const n={};return e.forEach((e,i)=>{const{relation:o}=e;if(!o){const e=new r("editor:relation-required","A relation is required on a layer to retrieve related records.");throw p().error(e),e}const{relatedTableId:s}=o;if("number"!=typeof s){const e=new r("editor:related-table","A related table ID is required on a layer to retrieve related records.");throw p().error(e),e}const l=`${t.url}/${s}`,a=m.get(l),u=a??N(l);a||m.set(l,u),n[i]=u}),o(s(n),i)}function T({graphic:e,relatedInfos:t,layer:r},i){const o={};return t.forEach((t,s)=>{t.layerInfo&&(o[s]=$(e,t,r,i))}),s(o)}function q({relatedInfo:e,fieldName:t,fieldInfo:r}){if(e.relatedFields?.push(t),r.statisticType){const i=new c({statisticType:r.statisticType,onStatisticField:t,outStatisticFieldName:t});e.outStatistics?.push(i)}}function L(e,t){if(null!=e){t=t.toLowerCase();for(const r of e)if(r&&r.name.toLowerCase()===t)return r}return null}export{b as createRelatedInfo,I as getDestinationRelation,h as getRelatedFieldInfo,j as getUniqueOutFields,R as getUniqueOutStatistics,v as queryLayerInfos,T as queryRelatedFeatures,g as setRelatedFeatures,q as updateRelatedInfo};
