
let resourceCache = {};


function loadPage(url) {

    if (resourceCache[url]) {
        return resourceCache[url];
    }

    resourceCache[url] = new Promise((resolve, reject) => {

        const uri = new URL(url), locale = uri.searchParams.get('locale');

        let options = {
            filter: {_id: uri.host},
            limit: 1
        };

        if (locale && App._locales[locale]) {
            options.locale = locale;
        }

        App.request('/pages/utils/find', {options}).then(rsp => {

            if (rsp.items && rsp.items[0]) {
                resolve(rsp.items[0]);
            }

        }).catch(res => {
            reject(res.error || 'Loading page failed!');
        });

    });

    return resourceCache[url];
}

function loadAsset(url) {

    if (resourceCache[url]) {
        return resourceCache[url];
    }

    resourceCache[url] = new Promise((resolve, reject) => {

        const uri = new URL(url);

        App.request('/assets/assets', {
            options: {
                filter: [{_id: uri.host}],
                limit: 1
            }
        }).then(rsp => {
            const asset = rsp.assets[0] ?? null;

            if (asset) {
                resolve(asset);
            } else {
                reject(asset);
            }

        }).catch(res => {
            reject(res)
        });

    });

    return resourceCache[url];
}


export default {

    _meta: {
        label: 'Page Link / Url',
        info: 'Url or page link',
        icon: 'pages:assets/icons/link.svg',
        settings: [
            {name: 'link', type: 'text'},
        ],
        render(value, field, context) {

            if (typeof(value) === 'string' && value.match(/^(assets|pages):\/\//)) {

                let resource, rid = `fpu-${App.utils.nanoid()}`;

                if (value.match(/^pages:\/\//)) {
                    resource = 'page';

                    loadPage(value).then(page => {

                        const ele = document.getElementById(rid);

                        if (ele) {
                            ele.innerHTML = (!page._state ? '<icon class="kiss-color-danger">trip_origin</icon> ':'') + page.title;
                        }

                    }).catch(res => {
                        console.error(res.error || 'Loading page failed!', 'error');
                        const ele = document.getElementById(rid);
                        if (ele) {
                            ele.innerHTML = value;
                        }
                    });
                }

                if (value.match(/^assets:\/\//)) {
                    resource = 'asset';

                    loadAsset(value).then(asset => {
                        const ele = document.getElementById(rid);
                        if (ele) {

                            let html = '';
                            let mediaSize = 30;
                            let media = `<kiss-svg width="${mediaSize}" height="${mediaSize}" src="${App.base(asset.type === 'video' ? 'assets:assets/icons/video.svg' : 'assets:assets/icons/file.svg')}"><canvas width="${mediaSize}" height="${mediaSize}"></canvas></kiss-svg>`;

                            if (asset.type === 'image') {
                                const src = App.route(`/assets/thumbnail/${asset._id}?m=bestFit&mime=auto&h=${(mediaSize * 2)}&t=${asset._modified}`);
                                media = `<img loading="lazy" class="kiss-responsive-height kiss-margin-auto" src="${src}" title="${asset.title}" style="height:${mediaSize}px;object-fit:contain;object-position:center;">`;
                            }

                            ele.innerHTML = /*html*/ `
                                <kiss-row class="kiss-flex-middle" gap="small">
                                    <div class="kiss-position-relative">
                                        <canvas width="${mediaSize}" height="${mediaSize}"></canvas>
                                        <div class="kiss-cover ${ asset.type === 'image' ? 'kiss-bgcolor-transparentimage' : '' }" style="--kiss-bgcolor-transparentimage-size:10px">${media}</div>
                                    </div>
                                    <div class="kiss-flex-1 kiss-size-xsmall">
                                        <div class="kiss-text-truncate" title="${asset.title}">${asset.title}</div>
                                        <div class="kiss-color-muted">${App.utils.formatSize(asset.size) }</div>
                                    </div>
                                </kiss-row>
                            `;
                        }
                    }).catch(() => {
                        console.error('Loading asset failed!', 'error');
                        const ele = document.getElementById(rid);
                        if (ele) {
                            ele.innerHTML = value;
                        }
                    });
                }

                return `<div class="kiss-flex kiss-flex-middle" gap="small">
                    <div id="${rid}" class="kiss-flex-1 kiss-text-truncate"><app-loader class="kiss-display-inline-block" size="small" mode="dots"></app-loader></div>
                    <span class="kiss-badge kiss-badge-outline kiss-color-muted kiss-text-upper">${resource}</span>
                </div> `;
            }

            return value;
        }
    },

    data() {
        return {
            page: null,
            asset: null,
            val: this.modelValue
        }
    },

    props: {
        modelValue: {
            type: String,
            default: ''
        },
        placeholder: {
            type: String,
            default: 'https://...'
        },
        locale: {
            type: String,
            default: null
        }
    },

    mounted() {

        if (this.val && this.val.match(/^pages:\/\//)) {
            this.loadPage();
        }

        if (this.val && this.val.match(/^assets:\/\//)) {
            this.loadAsset();
        }
    },

    computed: {
        hasLinkedPage() {
            return this.page && this.val && this.val.indexOf(this.page._id) !== -1;
        },

        hasLinkedAsset() {
            return this.asset && this.val && this.val.indexOf(this.asset._id) !== -1;
        },

        assetPreview() {

            if (!this.asset) {
                return null;
            }

            let mediaSize = 50;
            let media = `<kiss-svg width="${mediaSize}" height="${mediaSize}" src="${App.base(this.asset.type === 'video' ? 'assets:assets/icons/video.svg' : 'assets:assets/icons/file.svg')}"><canvas width="${mediaSize}" height="${mediaSize}"></canvas></kiss-svg>`;

            if (this.asset.type === 'image') {

                const src = App.route(`/assets/thumbnail/${this.asset._id}?m=bestFit&mime=auto&h=${(mediaSize * 2)}&t=${this.asset._modified}`);

                media = `<img loading="lazy" class="kiss-responsive-height kiss-margin-auto" src="${src}" title="${this.asset.title}" style="height:${mediaSize}px;object-fit:contain;object-position:center;">`;
            }

            return media;

        }
    },

    watch: {
        modelValue() {
            this.val = this.modelValue;
            this.update();
        }
    },

    methods: {

        selectPage() {

            VueView.ui.offcanvas('pages:assets/dialogs/page-picker.js', {page: this.val, locale: this.locale}, {

                select: (page, locale) => {
                    this.page = page;
                    this.val = `pages://${page._id}`+((locale && locale != 'default' && `?locale=${locale}`) || '');
                    this.update();
                }

            });

        },

        selectAsset() {

            App.utils.selectAsset(asset => {
                this.asset = asset;
                this.val = `assets://${asset._id}`
                this.update();
            });
        },

        loadPage() {

            if (!this.val || !this.val.match(/^pages:\/\//)) {
                return;
            }

            loadPage(this.val).then(page => {
                this.page = page;
            }).catch(res => {
                this.page = null;
                App.ui.notify(res.error || 'Loading page failed!', 'error');
            });
        },

        loadAsset() {

            if (!this.val || !this.val.match(/^assets:\/\//)) {
                return;
            }

            loadAsset(this.val).then(asset => {
                this.asset = asset;
            }).catch(() => {
                this.asset = null;
            });
        },

        update() {
            this.$emit('update:modelValue', this.val)
        }
    },

    template: /*html*/`
        <div field="page-url">

            <kiss-card class="kiss-padding-small kiss-size-small kiss-position-relative kiss-margin-small" v-if="hasLinkedPage" theme="bordered contrast" :style="{borderColor: page._state !== 1 ? 'var(--kiss-color-danger)':''}">
                <div class="kiss-text-bold">{{ page.title }}</div>
                <div class="kiss-color-muted kiss-size-xsmall kiss-text-truncate">{{page._r}}</div>
                <a class="kiss-cover" :href="$routeUrl('/pages/page/'+page._id)" target="_blank"></a>
            </kiss-card>

            <kiss-card class="kiss-size-small kiss-position-relative kiss-margin-small" v-if="hasLinkedAsset" theme="bordered contrast">
                <kiss-row class="kiss-flex-middle" gap="small">
                    <div class="kiss-position-relative">
                        <canvas width="50" height="50"></canvas>
                        <div class="kiss-cover" :class="{'kiss-bgcolor-transparentimage': asset.type === 'image'}" style="--kiss-bgcolor-transparentimage-size:10px" v-html="assetPreview"></div>
                    </div>
                    <div class="kiss-flex-1 kiss-size-xsmall">
                        <div class="kiss-text-truncate" :title="asset.title">{{asset.title}}</div>
                        <div class="kiss-color-muted">{{ App.utils.formatSize(asset.size) }}</div>
                    </div>
                </kiss-row>
                <a class="kiss-cover" :href="$baseUrl('#uploads:'+asset.path)" target="_blank"></a>
            </kiss-card>

            <kiss-navlist class="kiss-flex">
                <input type="text" class="kiss-input kiss-flex-1 kiss-margin-small-end" :class="{'kiss-color-muted': hasLinkedPage}" v-model="val" @input="update" :placeholder="placeholder">
                <kiss-dropdown>
                    <button class="kiss-button" type="button">Pick</button>
                    <kiss-dropdownbox>
                        <kiss-navlist>
                            <ul>
                                <li class="kiss-nav-header">{{ t('Resource') }}</li>
                                <li><a @click="selectPage"><icon>link</icon> {{ t('Page') }}</a></li>
                                <li><a @click="selectAsset"><icon>attach_file</icon> {{ t('Asset') }}</a></li>
                            </ul>
                        </kiss-navlist>
                    </kiss-dropdownbox>
                </kiss-dropdown>
            </div>
        </div>
    `,
}
