// retoor <retoor@molodetz.nl>

import { Http } from "./Http.js";

export const TERMS_ACCEPTANCE_CODE = "terms_acceptance_required";

const ACCEPT_URL = "/auth/accept-terms";

const TERMS_LINKS = [
    { href: "/docs/terms.html", label: "Terms of Service" },
    { href: "/docs/community-guidelines.html", label: "Community Guidelines" },
    { href: "/docs/privacy.html", label: "Privacy Policy" },
];

export class TermsGate {
    constructor(dialog) {
        this.dialog = dialog;
        this.prompted = null;
        this.accepted = null;
    }

    matches(payload) {
        const error = payload && payload.error;
        return !!error && error.code === TERMS_ACCEPTANCE_CODE;
    }

    async intercept(error, retry) {
        if (!(await this.confirm(error))) {
            return Http.suspend();
        }
        if (!(await this.accept())) {
            return Http.suspend();
        }
        return retry();
    }

    confirm(error) {
        if (!this.prompted) {
            this.prompted = this.dialog
                .confirm({
                    title: "Terms of Service",
                    message: TermsGate.message(error),
                    links: TERMS_LINKS,
                    confirmLabel: "Accept and continue",
                    cancelLabel: "Not now",
                })
                .then((answer) => {
                    this.prompted = null;
                    return answer === true;
                });
        }
        return this.prompted;
    }

    accept() {
        if (!this.accepted) {
            this.accepted = Http.sendForm(ACCEPT_URL, {}, { silent: true, termsRetry: true })
                .then(() => true)
                .catch(() => {
                    Http.notifyError("Your acceptance could not be recorded. Please try again.");
                    return false;
                })
                .finally(() => {
                    this.accepted = null;
                });
        }
        return this.accepted;
    }

    static message(error) {
        const version = error && error.terms_version;
        const subject = version ? `Version ${version} of the terms` : "The terms";
        return (
            `${subject} is in force and your account has not accepted it yet, ` +
            "so this action was not carried out. Accepting records your agreement and repeats the action. " +
            "Reading the site and deleting your account are never blocked."
        );
    }
}
