import{getElement,toArray}from"../../common/util";import{definePlugin}from"../../core/extension";import{createUnityColor}from"../../unity/tool";import{NOTIFICATION_TYPE,REQUEST_TYPE}from"../../unity/model-api";import{generateUUID}from"three/src/math/MathUtils";import upperFirst from"lodash/upperFirst";export let TemplateType=function(a){return a.symbol_1="\u56FE\u6807_\u6587\u5B57_1",a.symbol_2="\u56FE\u6807_\u6587\u5B57_2",a.symbol_3="\u56FE\u6807_\u6587\u5B57_3",a.text_1="\u65E0\u56FE\u6807_1",a.text_2="\u65E0\u56FE\u6807_2",a.icon_1="\u7EAF\u56FE\u6807_1",a.icon_2="\u7EAF\u56FE\u6807_2",a.icon_radius="\u7EAF\u56FE\u6807_\u5706\u5F62\u906E\u7F69_0",a}({});async function createEmptyObject(a,b){let c=a.offset?{X:a.position.x+a.offset.x,Y:a.position.y+a.offset.y,Z:a.position.z+a.offset.z}:a.position;let d={SpaceId:a.parentId,Position:c,TargetPolymerizationSystemIs:a.polyIds||[]};a.objectId&&(d.ObjectId=a.objectId);let e=await b.invoke(REQUEST_TYPE.AddCustomObject,d);return e}async function removeEmptyObject(a,b){return await b.invoke(REQUEST_TYPE.RemoveSceneObject,{ObjectIds:toArray(a)})}function createCustomeObjectId(){return`CustomObject_`+generateUUID()}async function createTextPoi(a,b,c){if(!b||!b.text)throw Error("options.text is undefined");let d=b.text;b.color&&(d=`<color=${b.color}>${d}</color>`),b.fontWeight&&(d=`<b>${d}</b>`),("italic"===b.fontStyle||"oblique"===b.fontStyle)&&(d=`<i>${d}</i>`),b.fontSize&&(d=`<size=${+b.fontSize}>${d}</size>`);let e,f=b.scale||1;b.backgroundColor&&(e=createUnityColor(b.backgroundColor));let g=b.modelId?b.modelId:await createEmptyObject({objectId:b.poiId,parentId:a,position:b.position,offset:b.offsets,polyIds:b.polyIds||[]},c);let h=-1;return!0===(null===b||void 0===b?void 0:b.fixed)?h=1:"number"==typeof b.fixed&&(h=b.fixed),c.invoke(REQUEST_TYPE.SetObjectIconById,{ObjectId:g,FixedScale:h,ObjectScale:f,RichText:d,BackgroundColor:e,IsShow:!0}).then(()=>g)}async function createImagePoi(a,b,c){if(!b||!b.url)throw Error("options.url is undefined");let d,e=b.url,f=b.scale||1;b.backgroundColor&&(d=createUnityColor(b.backgroundColor));let g;b.modelId&&(g=b.modelId),g=await createEmptyObject({objectId:b.poiId,parentId:a,position:b.position,offset:b.offsets,polyIds:b.polyIds||[]},c);let h=-1;return!0===(null===b||void 0===b?void 0:b.fixed)?h=1:"number"==typeof b.fixed&&(h=b.fixed),c.invoke(REQUEST_TYPE.SetObjectIconById,{ObjectId:g,FixedScale:h,ObjectScale:f,Url_Normal:e,Url_Highlight:e,BackgroundColor:d,IsShow:!0}).then(()=>g)}async function createTemplatePoi(a,b,c){if(!b||!b.template)throw Error("options.template is undefined");let d,e=b.scale||1;b.backgroundColor&&(d=createUnityColor(b.backgroundColor));let f=b.modelId?b.modelId:await createEmptyObject({objectId:b.poiId,parentId:a,position:b.position,offset:b.offsets,polyIds:b.polyIds||[]},c);let g=-1;return!0===(null===b||void 0===b?void 0:b.fixed)?g=1:"number"==typeof b.fixed&&(g=b.fixed),c.invoke(REQUEST_TYPE.SetObjectIconById,{ObjectId:f,FixedScale:g,ObjectScale:e,Url_Normal:b.url,Url_Highlight:b.hoverUrl||b.url,BackgroundColor:d,IsShow:!0,RichText:b.text,Template:b.template,RenderOrder:b.renderOrder,OtherSettings:b.otherSettings}).then(()=>f)}function updatePoiOptions(a,b,c){let d={};for(let e in b)d[upperFirst(e)]=b[e];return c.invoke(REQUEST_TYPE.SetObjectIconById,{ObjectId:a,...d})}function buildHtmlStyle(a){let b=[];const c=(a,d)=>{if(d.style){let c=[];for(let a in d.style){let b=d.style[a];void 0!==b&&""!==b&&c.push(`${a}: ${b}`)}a.push(d.nodeName.toLocaleLowerCase()),b.push(`${a.join(" ")}{${c.join(";")}}`)}return d.children&&0<d.children.length&&Array.from(d.children).forEach(b=>{c([...a],b)}),b};return c([],a).join("")}function createHtmlContent(a){return`
        <!DOCTYPE html>
        <html>
            <head>
                <meta charset="utf-8" />
                <style type="text/css" id="__style__">
                    ${buildHtmlStyle(a)}
                </style>
                <script type="text/javascript">
                    if (window.vuplex) {
                        // 从html 发送到 unity
                        window.onclick = function(event){
                            let target = event.target;
                            if(!target){
                                return;
                            }
                            let current = target, tags = [];
                            while(current.parent && current.parent !== document){
                                tags.push(current.nodeName);
                                current = current.parent;
                            }
                            window.vuplex.postMessage(JSON.stringify({
                                type: 'click',
                                data: {
                                    tags: tags.reverse()
                                }
                            }));
                        }
                        // 监听从 unity 发送到当前html片段，目前只接受直接更新html片段
                        window.vuplex.addMessage(functoin(event){
                            let {type, data} = JSON.parser(event.data);
                            if(type === 'update-html'){
                                let {style, content} = data;
                                document.body.innerHTML = content;
                                document.getElementById('__style__').innerHTML = style;
                            }
                        })
                    }
                </script>
            </head>
            <body>
                ${a.innerHTML}
            </body>
        </html>
    `}async function createHtmlPoi(a,b){let c=getElement(a.el);if(!c)throw Error("options.el is undefined");let d=createHtmlContent(c);return await b.invoke(REQUEST_TYPE.DisplayWeb3DUI,{Width:a.width?+a.width:c.offsetWidth,Height:a.height?+a.height:c.offsetHeight,Scale:a.scale||1,Position:a.position,HtmlContent:d})}export default definePlugin("poi",{setup(a,b){async function c(){return k&&k(),k=void 0,h=void 0,i=void 0,await b.unity.invoke(REQUEST_TYPE.RemoveSceneObject)}function d(){const a=(b,c)=>{let d=b.pop();for(let e=0;e<c.length;e++)if(c[e].nodeName.toLocaleLowerCase()===d)return 0===b.length?c[e]:a(b,Array.from(c[e].children))};let c=b.unity.addNotificationListener(NOTIFICATION_TYPE.Web3DUIInteraction,b=>{let{type:c,data:d}=b;if("click"===c&&i){let b=a(d.tags,[i]);b&&b.click()}});return c}function e(a){const c=new MutationObserver(()=>{b.unity.invoke(REQUEST_TYPE.UpdateHeatMapData,{type:"update-html",data:{style:buildHtmlStyle(a),content:a.innerHTML}})}),d={attributes:!0,childList:!0,subtree:!0};return c.observe(a,d),()=>{c.disconnect()}}let f=[],g=[];let h,i,j,k;const l=async()=>{let a=f.map(a=>a.value);await removeEmptyObject(Array.from(a),b.unity)},m=()=>{l(),j&&j(),g.length&&(g.forEach(a=>{a()}),g=[])},n=(a,c)=>{let d=({params:d})=>{if(!d.modelId)return;let e,g,h=d.modelId;if(f.forEach(({key:a,value:b})=>{b===h&&(e=a)}),e&&b.global&&(g=b.global.modelId===e||b.global.id===e?b.global:b.global.get(e,!1),!g))try{g=JSON.parse(e)}catch(a){}g&&c({modelId:h,eventType:a,target:g})},e=b.addEventListener(a,d);return g.push(e),()=>{e(),g=g.filter(a=>a!==e)}};return{TemplateType:TemplateType,createText:(a={})=>{const c=a=>({text:"",position:{x:0,y:0,z:0},offsets:{x:0,y:0,z:0},isSprite:!0,pointerEvents:"none",fontSize:"10px",backgroundColor:"#333",color:"#fff",...a}),d=async(d,e)=>{let g,h,i=c(a);if(g="isComponent"in d?d.modelId:JSON.stringify({x:d.x,y:d.y,z:d.z}),!0===i.replace&&!i.modelId){var j;i.modelId=null===(j=f.find(a=>a.key===g))||void 0===j?void 0:j.value}if(i.poiId||(i.poiId=i.modelId||createCustomeObjectId()),f.push({key:g,value:i.poiId}),"isComponent"in d){var k,l,m;await(null===(k=(l=d.model).getTransform)||void 0===k?void 0:k.call(l)),i.position=d.model.position,h=null===(m=d.parent)||void 0===m?void 0:m.modelId}else i.position=d;e&&(i=e(d,i));let n=await createTextPoi(h,i,b.unity);return n},e={applyToComponent:async(a,b)=>{let c=[];toArray(a).forEach(a=>{c.push(d(a,b))});let e=await Promise.allSettled(c),f=[];return e.forEach(a=>{"fulfilled"===a.status&&f.push(a.value)}),f},applyToType:async(a,c)=>{let e=[];b.component.search(a).forEach(a=>{e.push(d(a,c))});let f=await Promise.allSettled(e),g=[];return f.forEach(a=>{"fulfilled"===a.status&&g.push(a.value)}),g},applyToPosition:async(a,b)=>{let c=[];toArray(a).forEach(a=>{c.push(d(a,b))});let e=await Promise.allSettled(c),f=[];return e.forEach(a=>{"fulfilled"===a.status&&f.push(a.value)}),f}};return e},createImage:a=>{const c=a=>({url:"",position:{x:0,y:0,z:0},isSprite:!0,pointerEvents:"none",offsets:{x:0,y:0,z:0},...a}),d=async(d,e)=>{let g,h,i=c(a);if(g="isComponent"in d?d.modelId:JSON.stringify({x:d.x,y:d.y,z:d.z}),!0===i.replace&&!i.modelId){var j;i.modelId=null===(j=f.find(a=>a.key===g))||void 0===j?void 0:j.value}if(i.poiId||(i.poiId=i.modelId||createCustomeObjectId()),f.push({key:g,value:i.poiId}),"isComponent"in d){var k,l,m;await(null===(k=(l=d.model).getTransform)||void 0===k?void 0:k.call(l)),i.position=d.model.position,h=null===(m=d.parent)||void 0===m?void 0:m.modelId}else i.position=d;e&&(i=e(d,i));let n=await createImagePoi(h,i,b.unity);return n},e={applyToComponent:async(a,b)=>{let c=[];toArray(a).forEach(a=>{c.push(d(a,b))});let e=await Promise.allSettled(c),f=[];return e.forEach(a=>{"fulfilled"===a.status&&f.push(a.value)}),f},applyToType:async(a,c)=>{let e=[];b.component.search(a).forEach(a=>{e.push(d(a,c))});let f=await Promise.allSettled(e),g=[];return f.forEach(a=>{"fulfilled"===a.status&&g.push(a.value)}),g},applyToPosition:async(a,b)=>{let c=[];toArray(a).forEach(a=>{c.push(d(a,b))});let e=await Promise.allSettled(c),f=[];return e.forEach(a=>{"fulfilled"===a.status&&f.push(a.value)}),f}};return e},createHtml:a=>{const f=a=>({el:"",position:{x:0,y:0,z:0},isSprite:!0,zIndex:"999",offsets:{x:0,y:0,z:0},...a});h&&(c(),h=void 0);let g=a.el&&getElement(a.el);if(!g)throw Error("options.el is undefined");k=e(g),j||(j=d());let i={applyToComponent:async d=>{var e,g;h&&c(),h=d.modelId,await(null===(e=(g=d.model).getTransform)||void 0===e?void 0:e.call(g)),a.position=d.model.position;let i=f(a);await createHtmlPoi(i,b.unity)},applyToPosition:async d=>{let e=JSON.stringify(d);h&&c(),h=e,a.position=d;let g=f(a);return await createHtmlPoi(g,b.unity)}};return i},createTemplate:a=>{const c=a=>({template:TemplateType.symbol_1,url:"",position:{x:0,y:0,z:0},isSprite:!0,pointerEvents:"none",offsets:{x:0,y:0,z:0},...a}),d=async(d,e)=>{let g,h,i=c(a);if(g="isComponent"in d?d.modelId:JSON.stringify({x:d.x,y:d.y,z:d.z}),!0===i.replace&&!i.modelId){var j;i.modelId=null===(j=f.find(a=>a.key===g))||void 0===j?void 0:j.value}if(i.poiId||(i.poiId=i.modelId||createCustomeObjectId()),f.push({key:g,value:i.poiId}),"isComponent"in d){var k,l,m;await(null===(k=(l=d.model).getTransform)||void 0===k?void 0:k.call(l)),i.position=d.model.position,h=null===(m=d.parent)||void 0===m?void 0:m.modelId}else i.position=d;e&&(i=e(d,i));let n=await createTemplatePoi(h,i,b.unity);return n},e={applyToComponent:async(a,b)=>{let c=[];toArray(a).forEach(a=>{c.push(d(a,b))});let e=await Promise.allSettled(c),f=[];return e.forEach(a=>{"fulfilled"===a.status&&f.push(a.value)}),f},applyToType:async(a,c)=>{let e=[];b.component.search(a).forEach(a=>{e.push(d(a,c))});let f=await Promise.allSettled(e),g=[];return f.forEach(a=>{"fulfilled"===a.status&&g.push(a.value)}),g},applyToPosition:async(a,b)=>{let c=[];toArray(a).forEach(a=>{c.push(d(a,b))});let e=await Promise.allSettled(c),f=[];return e.forEach(a=>{"fulfilled"===a.status&&f.push(a.value)}),f}};return e},clearAll:l,clear:async a=>{let d=[];toArray(a).forEach(a=>{let b;b="string"==typeof a?a:"isComponent"in a?a.modelId:JSON.stringify(a);let c=f.findIndex(a=>a.key===b||a.value===b);if(-1<c){let a=f[c].value;d.push(a),f.splice(c,1)}else d.push(b)}),0<d.length&&(await removeEmptyObject(d,b.unity)),h&&d.indexOf(h)&&c()},update:function e(a,c,d){let g=[];return toArray(c).forEach(c=>{let e;e="string"==typeof c?c:"isComponent"in c?c.modelId:JSON.stringify({x:c.x,y:c.y,z:c.z});let h=f.find(a=>a.key===e||a.value===e);if(h)if(d){let e=d(c,{...a});g.push(updatePoiOptions(h.value,e,b.unity))}else g.push(updatePoiOptions(h.value,a,b.unity))}),Promise.allSettled(g)},dispose:m,addEventListener:n}},destroyed(){this.dispose()}});