// Backbone.js Application Model: Certificate

define([
    'underscore',
    'backbone',
    'backbone-relational',
    'backbone.associations',
    'gettext',
    'cms/js/main',
    'js/certificates/models/signatory',
    'js/certificates/collections/signatories'
],
    function(_, Backbone, BackboneRelational, BackboneAssociations, gettext, CoffeeSrcMain,
             SignatoryModel, SignatoryCollection) {
        'use strict';
        var Certificate = Backbone.RelationalModel.extend({
            idAttribute: 'id',
            defaults: {
                // Metadata fields currently displayed in web forms
                course_title: '',

                // Metadata fields not currently displayed in web forms
                name: 'Name of the certificate',
                description: 'Description of the certificate',

                // Internal-use only, not displayed in web forms
                version: 1,
                is_active: false
            },

            // Certificate child collection/model mappings (backbone-relational)
            relations: [{
                type: Backbone.HasMany,
                key: 'signatories',
                relatedModel: SignatoryModel,
                collectionType: SignatoryCollection,
                reverseRelation: {
                    key: 'certificate',
                    includeInJSON: 'id'
                }
            }],

            initialize: function(attributes, options) {
                // Set up the initial state of the attributes set for this model instance
                this.canBeEmpty = options && options.canBeEmpty;
                if (options.add) {
                    // Ensure at least one child Signatory model is defined for any new Certificate model
                    attributes.signatories = new SignatoryModel({certificate: this});
                }
                this.setOriginalAttributes();
                return this;
            },

            parse: function(response) {
                // Parse must be defined for the model, but does not need to do anything special right now
                return response;
            },

            setOriginalAttributes: function() {
                // Remember the current state of this model (enables edit->cancel use cases)
                this._originalAttributes = this.parse(this.toJSON());

                this.get('signatories').each(function(modelSignatory) {
                    modelSignatory.setOriginalAttributes();
                });

                // If no url is defined for the signatories child collection we'll need to create that here as well
                if (!this.isNew() && !this.get('signatories').url) {
                    this.get('signatories').url = this.collection.url + '/' + this.get('id') + '/signatories';
                }
            },

            validate: function(attrs) {
                // Ensure the provided attributes set meets our expectations for format, type, etc.
                if (!attrs.name.trim()) {
                    return {
                        message: gettext('Certificate name is required.'),
                        attributes: {name: true}
                    };
                }
                var allSignatoriesValid = _.every(attrs.signatories.models, function(signatory) {
                    return signatory.isValid();
                });
                if (!allSignatoriesValid) {
                    return {
                        message: gettext('Signatory field(s) has invalid data.'),
                        attributes: {signatories: attrs.signatories.models}
                    };
                }
            },

            reset: function() {
                // Revert the attributes of this model instance back to initial state
                this.set(this._originalAttributes, {parse: true, validate: true});
            }
        });
        return Certificate;
    });
