/*
 * This mixin is used by most of the subscription related screens to select plans
 * and send subscription plan changes to the server. This contains helpers for
 * the active subscription, trial information and other convenience helpers.
 */
module.exports = {
    /**
     * The mixin's data.
     */
    data() {
        return {
            selectingPlan: null,

            planForm: new SparkForm({})
        }
    },


    methods: {
        /**
         * Update the subscription to the given plan.
         *
         * Used when updating or resuming the subscription plan.
         */
        updateSubscription(plan) {
            this.selectingPlan = plan;

            this.planForm.errors.forget();

             // Here we will send the request to the server to update the subscription plan and
             // update the user and team once the request is complete. This method gets used
             // for both updating subscriptions plus resuming any cancelled subscriptions.
            axios.put(this.urlForPlanUpdate, {"plan": plan.id})
                .then(() => {
                    Bus.$emit('updateUser');
                    Bus.$emit('updateTeam');
                })
                .catch(errors => {
                    if (errors.response.status == 422) {
                        this.planForm.errors.set(errors.response.data);
                    } else {
                        this.planForm.errors.set({plan: ["We were unable to update your subscription. Please contact customer support."]});
                    }
                })
                .finally(() => {
                    this.selectingPlan = null;
                });
        },


        /**
         * Determine if the given plan is selected.
         */
        isActivePlan(plan) {
            return this.activeSubscription &&
                   this.activeSubscription.provider_plan == plan.id;
        }
    },


    computed: {
        /**
         * Get the active plan instance.
         */
        activePlan() {
            if (this.activeSubscription) {
                return _.find(this.plans, (plan) => {
                    return plan.id == this.activeSubscription.provider_plan;
                });
            }
        },


        /**
         * Determine if the active plan is a monthly plan.
         */
        activePlanIsMonthly() {
            return this.activePlan && this.activePlan.interval == 'monthly';
        },


        /**
         * Get the active subscription instance.
         */
        activeSubscription() {
            if ( ! this.billable) {
                return;
            }

            const subscription = _.find(
                this.billable.subscriptions,
                subscription => subscription.name == 'default'
            );

            if (typeof subscription !== 'undefined') {
                return subscription;
            }
        },


        /**
         * Determine if the current subscription is active.
         */
        subscriptionIsActive() {
            return this.activeSubscription && ! this.activeSubscription.ends_at;
        },


        /**
         * Determine if the billable entity is on a generic trial.
         */
        onGenericTrial() {
            return this.billable.trial_ends_at &&
                   moment.utc(this.billable.trial_ends_at).isAfter(moment.utc());
        },


        /**
         * Determine if the current subscription is active.
         */
        subscriptionIsOnTrial() {
            if (this.onGenericTrial) {
                return true;
            }

            return this.activeSubscription &&
                   this.activeSubscription.trial_ends_at &&
                   moment.utc().isBefore(moment.utc(this.activeSubscription.trial_ends_at));
        },


        /**
         * Get the formatted trial ending date.
         */
        trialEndsAt() {
            if ( ! this.subscriptionIsOnTrial) {
                return;
            }

            if (this.onGenericTrial) {
                return moment.utc(this.billable.trial_ends_at)
                                        .local().format('MMMM Do, YYYY');
            }

            return moment.utc(this.activeSubscription.trial_ends_at)
                            .local().format('MMMM Do, YYYY');
        },


        /**
         * Determine if the current subscription is active.
         */
        subscriptionIsOnGracePeriod() {
            return this.activeSubscription &&
                   this.activeSubscription.ends_at &&
                   moment.utc().isBefore(moment.utc(this.activeSubscription.ends_at));
        },


        /**
         * Determine if the billable entity has no active subscription.
         */
        needsSubscription() {
            return ! this.activeSubscription ||
                    (this.activeSubscription.ends_at &&
                     moment.utc().isAfter(moment.utc(this.activeSubscription.ends_at)));
        },


        /**
         * Get the URL for the subscription plan update.
         */
        urlForPlanUpdate() {
            return this.billingUser
                            ? '/settings/subscription'
                            : `/settings/${Spark.pluralTeamString}/${this.team.id}/subscription`;
        }
    }
};
