import Hostname from "./API/Hostname";
import DatabaseProperty from "./Database/DatabaseProperty";
import BadDataException from "./Exception/BadDataException";
import { ObjectType } from "./JSON";
import Zod from "../Utils/Schema/Zod";
const nonBusinessEmailDomains = [
    "gmail",
    "yahoo",
    "yahoomail",
    "googlemail",
    "ymail",
    "icloud",
    "aol",
    "hotmail",
    "outlook",
    "msn",
    "wanadoo",
    "orange",
    "comcast",
    "facebook",
    "hey.com",
    "protonmail",
    "inbox.com",
    "mail.com",
    "zoho",
    "yandex",
];
export default class Email extends DatabaseProperty {
    get email() {
        return this._email;
    }
    set email(value) {
        if (value && typeof value === "string") {
            value = value.trim();
            value = value.toLowerCase();
        }
        if (Email.isValid(value)) {
            this._email = value;
        }
        else {
            throw new BadDataException(`Email ${value} is not in valid format.`);
        }
    }
    constructor(email) {
        super();
        this._email = "";
        this.email = email;
    }
    static isValid(value) {
        // from https://datatracker.ietf.org/doc/html/rfc5322
        const re = 
        // eslint-disable-next-line no-control-regex
        /(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])/i;
        const isValid = re.test(value);
        if (!isValid) {
            return false;
        }
        return true;
    }
    toJSON() {
        return {
            _type: ObjectType.Email,
            value: this.toString(),
        };
    }
    static fromString(value) {
        return new Email(value);
    }
    static parseList(value) {
        if (!value) {
            return [];
        }
        const seen = new Set();
        const emails = [];
        for (const part of value.split(/[,;\s]+/)) {
            const trimmed = part.trim();
            if (!trimmed) {
                continue;
            }
            const email = new Email(trimmed);
            const key = email.toString();
            if (!seen.has(key)) {
                seen.add(key);
                emails.push(email);
            }
        }
        return emails;
    }
    static isValidList(value) {
        if (!value) {
            return true;
        }
        const parts = value
            .split(/[,;\s]+/)
            .map((p) => {
            return p.trim();
        })
            .filter((p) => {
            return p.length > 0;
        });
        if (parts.length === 0) {
            return false;
        }
        for (const part of parts) {
            if (!Email.isValid(part)) {
                return false;
            }
        }
        return true;
    }
    static fromJSON(json) {
        if (json["_type"] === ObjectType.Email) {
            return new Email(json["value"] || "");
        }
        throw new BadDataException("Invalid JSON: " + JSON.stringify(json));
    }
    toString() {
        return this.email;
    }
    getEmailDomain() {
        return new Hostname(this.email.split("@")[1]);
    }
    isBusinessEmail() {
        const domain = this.getEmailDomain().hostname || "";
        if (domain) {
            for (let i = 0; i < nonBusinessEmailDomains.length; i++) {
                if (domain.includes(nonBusinessEmailDomains[i])) {
                    return false;
                }
            }
        }
        return true;
    }
    static toDatabase(value) {
        if (value) {
            if (typeof value === "string") {
                value = new Email(value);
            }
            return value.toString();
        }
        return null;
    }
    static fromDatabase(_value) {
        if (_value) {
            return new Email(_value);
        }
        return null;
    }
    static getSchema() {
        return Zod.object({
            _type: Zod.literal(ObjectType.Email),
            value: Zod.string().email().openapi({
                type: "string",
                format: "email",
                example: "user@example.com",
            }),
        }).openapi({
            type: "object",
            description: "Email object",
            example: { _type: ObjectType.Email, value: "user@example.com" },
        });
    }
}
//# sourceMappingURL=Email.js.map