"use strict";

const striptags = require("striptags");

const slugify = require("slugify");
const tool = require("../tools/main");

const config = require("../config/main.js");
const txt = require("../lang/"+config.adminLang+"/questionnaire");
const txtGeneral = require("../lang/"+config.adminLang+"/general");

module.exports = (sequelize, DataTypes) =>
{
    const Questionnaire = sequelize.define("Questionnaire",
    {
        title:
        {
            type: DataTypes.STRING(255), allowNull: false,
            set(value)
            {
                this.setDataValue("title", tool.trimIfNotNull(striptags(value)));
            },
            validate:
            {
                notNull: { msg: txt.needTitle },
                len:
                {
                    args: [1, 255],
                    msg: txt.needNotTooLongTitle
                }                
            }
        },
        slug:
        {
            type: DataTypes.STRING(150), allowNull: false,
            unique:
            {
                args: true,
                msg: txt.needUniqueUrl
            },
            set(value)
            {
                value=tool.trimIfNotNull(striptags(value));
                if(value!==null)
                    this.setDataValue("slug", slugify(value.substring(0,150), { lower:true, strict:true }));
                else if(this.title!==null)
                    this.setDataValue("slug", slugify(this.title.substring(0,150), { lower:true, strict:true }));
            },
            validate:
            {
                notNull: { msg: txt.needUrl }
            }            
        },
        introduction:
        {
            type: DataTypes.TEXT, allowNull: false,
            set(value) { this.setDataValue("introduction", tool.trimIfNotNull(striptags(value,"<h3><h4><h5><p><b><i><em><strong><ul><li><div><a><br>"))); },
            validate:
            {
                notNull: { msg: txt.needIntroduction }
            }
        },
        keywords:
        {
            type: DataTypes.TEXT, allowNull: true,
            set(value) { this.setDataValue("keywords", tool.trimIfNotNull(striptags(value))); },
            comment : "Not published but only used for research."
        },
        publishingAt:
        {
            type: DataTypes.DATE, comment: "If null, the questionnaire is not published (=draft).",
            set(value) { this.setDataValue("publishingAt", tool.trimIfNotNull(value)); },
            validate:
            {   
                isDate: { msg: txt.needCorrectPublishingDate }
            }
        },
       isPublished:// valeur non saisie et validée par le code
        {
            type: DataTypes.BOOLEAN, allowNull: false, defaultValue:false,
            comment: "May depend on factors other than the date of publication.",
            validate:
            {
                notNull: { msg: txt.needKnowIfIsPublished },
                isIn:
                {
                    args: [[true, false]],
                    msg: txt.needKnowIfIsPublished+" "+txtGeneral.notValidFormat
                }
            }
        },        
        language: // liste des langues dispo dans un fichier de configuration fourni par l'API au client
        {
            type: DataTypes.STRING(4), allowNull: false, defaultValue: "fr",
            validate:
            {
                notNull: { msg: txt.needLanguage },
                len:
                {
                    args: [2, 4],
                    msg: txt.needLanguage+" "+txtGeneral.notValidFormat
                } // en fait, il faudra vérifier l'existence du fichier de la langue choisie.
            }
        },
        estimatedTime:
        {
            type: DataTypes.ENUM("short", "medium", "long"), allowNull: false, defaultValue: "medium",
            comment: "Provides an estimate of the time required to complete this questionnaire.",
            validate:
            {
                notNull: { msg: txt.needEstimatedTime },  
                isIn:
                {
                    args: [["short", "medium", "long"]],
                    msg: txt.needEstimatedTime+" "+txtGeneral.notValidFormat
                }
            }
        },
        rankInGroup:
        {
            type: DataTypes.INTEGER(2).UNSIGNED, allowNull: true,
            comment: "Allows you to classify the questionnaire if it belongs to a group.",
            set(value) { this.setDataValue("rankInGroup", tool.trimIfNotNull((value))); },
            validate:
            {
                isInt: { msg: txt.needNumberForRank },
                min:
                {
                    args: [1],
                    msg: txt.needNumberForRank
                }
            }
        },
        GroupId:
        {
            type: DataTypes.INTEGER(11).UNSIGNED, allowNull: true,
            set(value) { this.setDataValue("GroupId", tool.trimIfNotNull((value))); }
        }
    },
    {
        charset: "utf8mb4",
        collate: "utf8mb4_unicode_ci"
    }
    );
    Questionnaire.associate = function(models)
    {
        Questionnaire.hasMany(models.Question);
        Questionnaire.hasMany(models.Illustration);
        Questionnaire.hasMany(models.Link);
        Questionnaire.hasMany(models.Answer);
        Questionnaire.belongsTo(models.User, { as: "Creator", foreignKey: { name: "CreatorId", allowNull: false } });
        Questionnaire.belongsTo(models.Group, { foreignKey: { name: "GroupId", allowNull: true }, onDelete: 'RESTRICT', onUpdate: 'RESTRICT' });    
        Questionnaire.belongsToMany(models.Tag, { through: models.QuestionnaireClassification });
        Questionnaire.belongsToMany(models.User, { through: models.QuestionnaireAccess });
    };
    return Questionnaire;
};