"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Embed = void 0;
const tslib_1 = require("tslib");
const ow_1 = tslib_1.__importDefault(require("ow"));
const Assertions_1 = require("./Assertions");
/**
 * Represents an embed in a message (image/video preview, rich embed, etc.)
 */
class Embed {
    constructor(data = {}) {
        /**
         * An array of fields of this embed.
         */
        Object.defineProperty(this, "fields", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: void 0
        });
        /**
         * The embed title.
         */
        Object.defineProperty(this, "title", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: void 0
        });
        /**
         * The embed description.
         */
        Object.defineProperty(this, "description", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: void 0
        });
        /**
         * The embed url.
         */
        Object.defineProperty(this, "url", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: void 0
        });
        /**
         * The embed color.
         */
        Object.defineProperty(this, "color", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: void 0
        });
        /**
         * The timestamp of the embed in the ISO format.
         */
        Object.defineProperty(this, "timestamp", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: void 0
        });
        /**
         * The embed thumbnail data.
         */
        Object.defineProperty(this, "thumbnail", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: void 0
        });
        /**
         * The embed image data.
         */
        Object.defineProperty(this, "image", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: void 0
        });
        /**
         * Received video data.
         */
        Object.defineProperty(this, "video", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: void 0
        });
        /**
         * The embed author data.
         */
        Object.defineProperty(this, "author", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: void 0
        });
        /**
         * Received data about the embed provider.
         */
        Object.defineProperty(this, "provider", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: void 0
        });
        /**
         * The embed footer data.
         */
        Object.defineProperty(this, "footer", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: void 0
        });
        this.title = data.title;
        this.description = data.description;
        this.url = data.url;
        this.color = data.color;
        this.thumbnail = data.thumbnail;
        this.image = data.image;
        this.video = data.video;
        this.author = data.author;
        this.provider = data.provider;
        this.footer = data.footer;
        this.fields = data.fields ?? [];
        if (data.timestamp)
            this.timestamp = new Date(data.timestamp).toISOString();
    }
    /**
     * The accumulated length for the embed title, description, fields, footer text, and author name.
     */
    get length() {
        return ((this.title?.length ?? 0) +
            (this.description?.length ?? 0) +
            this.fields.reduce((prev, curr) => prev + curr.name.length + curr.value.length, 0) +
            (this.footer?.text.length ?? 0) +
            (this.author?.name?.length ?? 0));
    }
    /**
     * Adds a field to the embed (max 25).
     * @param field The field to add.
     */
    addField(field) {
        return this.addFields(field);
    }
    /**
     * Adds fields to the embed (max 25).
     * @param fields The fields to add.
     */
    addFields(...fields) {
        // Data assertions
        ow_1.default(fields, 'fields', Assertions_1.embedFieldsArrayPredicate);
        // Ensure adding these fields won't exceed the 25 field limit
        Assertions_1.validateFieldLength(this.fields, fields.length);
        this.fields.push(...Embed.normalizeFields(...fields));
        return this;
    }
    /**
     * Removes, replaces, or inserts fields in the embed (max 25).
     * @param index The index to start at.
     * @param deleteCount The number of fields to remove.
     * @param fields The replacing field objects.
     */
    spliceFields(index, deleteCount, ...fields) {
        // Data assertions
        ow_1.default(fields, 'fields', Assertions_1.embedFieldsArrayPredicate);
        // Ensure adding these fields won't exceed the 25 field limit
        Assertions_1.validateFieldLength(this.fields, fields.length - deleteCount);
        this.fields.splice(index, deleteCount, ...Embed.normalizeFields(...fields));
        return this;
    }
    /**
     * Sets the author of this embed.
     * @param options The options for the author.
     */
    setAuthor(options) {
        if (options === null) {
            this.author = undefined;
            return this;
        }
        const { name, iconURL, url } = options;
        // Data assertions
        ow_1.default(name, 'name', Assertions_1.authorNamePredicate);
        ow_1.default(iconURL, 'iconURL', Assertions_1.urlPredicate);
        ow_1.default(url, 'url', Assertions_1.urlPredicate);
        this.author = { name, url, icon_url: iconURL };
        return this;
    }
    /**
     * Sets the color of this embed.
     * @param color The color of the embed.
     */
    setColor(color) {
        // Data assertions
        ow_1.default(color, 'color', Assertions_1.colorPredicate);
        this.color = color ?? undefined;
        return this;
    }
    /**
     * Sets the description of this embed.
     * @param description The description.
     */
    setDescription(description) {
        // Data assertions
        ow_1.default(description, 'description', Assertions_1.descriptionPredicate);
        this.description = description ?? undefined;
        return this;
    }
    /**
     * Sets the footer of this embed.
     * @param options The options for the footer.
     */
    setFooter(options) {
        if (options === null) {
            this.footer = undefined;
            return this;
        }
        const { text, iconURL } = options;
        // Data assertions
        ow_1.default(text, 'text', Assertions_1.footerTextPredicate);
        ow_1.default(iconURL, 'iconURL', Assertions_1.urlPredicate);
        this.footer = { text, icon_url: iconURL };
        return this;
    }
    /**
     * Sets the image of this embed.
     * @param url The URL of the image.
     */
    setImage(url) {
        // Data assertions
        ow_1.default(url, 'url', Assertions_1.urlPredicate);
        this.image = url ? { url } : undefined;
        return this;
    }
    /**
     * Sets the thumbnail of this embed.
     * @param url The URL of the thumbnail.
     */
    setThumbnail(url) {
        // Data assertions
        ow_1.default(url, 'url', Assertions_1.urlPredicate);
        this.thumbnail = url ? { url } : undefined;
        return this;
    }
    /**
     * Sets the timestamp of this embed.
     * @param timestamp The timestamp or date.
     */
    setTimestamp(timestamp = Date.now()) {
        // Data assertions
        ow_1.default(timestamp, 'timestamp', Assertions_1.timestampPredicate);
        this.timestamp = timestamp ? new Date(timestamp).toISOString() : undefined;
        return this;
    }
    /**
     * Sets the title of this embed.
     * @param title The title.
     */
    setTitle(title) {
        // Data assertions
        ow_1.default(title, 'title', Assertions_1.titlePredicate);
        this.title = title ?? undefined;
        return this;
    }
    /**
     * Sets the URL of this embed.
     * @param url The URL.
     */
    setURL(url) {
        // Data assertions
        ow_1.default(url, 'url', Assertions_1.urlPredicate);
        this.url = url ?? undefined;
        return this;
    }
    /**
     * Transforms the embed to a plain object.
     */
    toJSON() {
        return { ...this };
    }
    /**
     * Normalizes field input and resolves strings.
     * @param fields Fields to normalize.
     */
    static normalizeFields(...fields) {
        return fields.flat(Infinity).map((field) => {
            ow_1.default(field.name, 'field name', Assertions_1.fieldNamePredicate);
            ow_1.default(field.value, 'field value', Assertions_1.fieldValuePredicate);
            ow_1.default(field.inline, 'field inline', Assertions_1.fieldInlinePredicate);
            return { name: field.name, value: field.value, inline: field.inline ?? undefined };
        });
    }
}
exports.Embed = Embed;
//# sourceMappingURL=Embed.js.map