import { UmbTiptapToolbarElementApiBase } from '../tiptap-toolbar-element-api-base.js';
import { UmbLink } from './link.tiptap-extension.js';
import { UMB_LINK_PICKER_MODAL } from '../../../multi-url-picker/index.js';
import { umbOpenModal } from '../../../core/modal/index.js';
export default class UmbTiptapToolbarLinkExtensionApi extends UmbTiptapToolbarElementApiBase {
    async execute(editor) {
        const attrs = editor?.getAttributes(UmbLink.name) ?? {};
        const link = this.#getLinkData(attrs);
        const data = { config: {}, index: null, isNew: link?.url === undefined };
        const value = { link };
        const overlaySize = this.configuration?.getValueByAlias('overlaySize') ?? 'small';
        const result = await umbOpenModal(this, UMB_LINK_PICKER_MODAL, { data, value, modal: { size: overlaySize } }).catch(() => undefined);
        if (!result?.link)
            return;
        const linkAttrs = this.#parseLinkData(result.link);
        if (linkAttrs) {
            editor?.chain().focus().extendMarkRange(UmbLink.name).setUmbLink(linkAttrs).run();
        }
        else {
            editor?.chain().focus().extendMarkRange(UmbLink.name).unsetLink().run();
        }
    }
    #getLinkData(attrs) {
        const queryString = attrs['data-anchor'];
        const culture = attrs['data-culture'];
        const url = attrs.href?.substring(0, attrs.href.length - (queryString?.length ?? 0));
        const unique = url?.includes('localLink:') ? url.substring(url.indexOf(':') + 1, url.indexOf('}')) : null;
        return {
            name: attrs.title,
            queryString,
            target: attrs.target,
            type: attrs.type,
            unique,
            url,
            culture,
        };
    }
    #parseLinkData(link) {
        const { name, target, type, unique, culture } = link;
        let { queryString, url } = link;
        // If an anchor exists, check that it is appropriately prefixed
        queryString = this.#queryStringFromUrl(queryString);
        // The href might be an external url, so check the value for an anchor/querystring;
        // `href` has the anchor re-appended later, hence the reset here to avoid duplicating the anchor
        if (!queryString) {
            const extractedInfo = this.#extractUrlAndQueryString(url, queryString);
            url = extractedInfo.url;
            queryString = extractedInfo.queryString;
        }
        // If we have a unique id, it must be a `/{localLink:guid}`
        if (unique) {
            url = `/{localLink:${unique}}`;
        }
        else {
            // If it's an email address and not `//user@domain.com` and protocol (e.g. mailto:, sip:) is not specified;
            // then we'll assume it should be a "mailto" link.
            url = this.#transformURLToMailto(url);
            url = this.#ensureHttpProtocol(url);
        }
        const anchor = this.#getAnchorFromQueryString(queryString);
        if (anchor) {
            url = (url ?? '') + anchor;
        }
        if (!url)
            return null;
        return {
            type: type ?? 'external',
            href: url,
            'data-anchor': anchor,
            target,
            title: name ?? url,
            'data-culture': culture,
        };
    }
    #extractUrlAndQueryString(url, queryString) {
        const urlParts = url?.split(/([#?])/);
        if (urlParts?.length === 3) {
            url = urlParts[0];
            queryString = urlParts[1] + urlParts[2];
        }
        return { url, queryString };
    }
    /**
     * If the URL is prefixed "www.", then prepend "http://" protocol scheme.
     * @param url
     */
    #ensureHttpProtocol(url) {
        if (!url)
            return null;
        if (/^\s*www\./i.test(url)) {
            url = `http://${url}`;
        }
        return url;
    }
    /**
     * If the URL is an email address, then prepend "mailto:" protocol scheme.
     * @param url
     */
    #transformURLToMailto(url) {
        if (!url)
            return null;
        if (url?.includes('@') && !url.includes('//') && !url.includes(':')) {
            url = `mailto:${url}`;
        }
        return url;
    }
    /**
     * If the URL contains an anchor, then return the anchor.
     * @param queryString
     */
    #getAnchorFromQueryString(queryString) {
        if (!queryString)
            return null;
        return queryString.startsWith('#') || queryString.startsWith('?') ? queryString : null;
    }
    /**
     * If the query string does not start with "?" or "#", then prepend it.
     * @param queryString
     */
    #queryStringFromUrl(queryString) {
        if (!queryString)
            return null;
        if (!queryString.startsWith('?') && !queryString.startsWith('#')) {
            queryString = (queryString.startsWith('=') ? '#' : '?') + queryString;
        }
        return queryString;
    }
}
