
module.exports = (sequelize, DataTypes) => {

    // CONNECTION D'ADMIN
    // Table administrateur
    const Admin = sequelize.define("Admnistrators", {
    
        id: {
            type: DataTypes.INTEGER,
            primaryKey: true,
            autoIncrement: true
        },
        matriculeEmployee: {
            type: DataTypes.STRING,
            allowNull: true,
            unique: true
        },
        firstName: {
            type: DataTypes.STRING,
            allowNull: false
        },
        lastName: {
            type: DataTypes.STRING
        },
        email: {
            type: DataTypes.STRING,
            allowNull: false,
            unique: true
        },
        password: {
            type: DataTypes.STRING,
            allowNull: false
        },
        phoneNumber: {
            type: DataTypes.STRING(13)
        },
        role: {
            type: DataTypes.STRING,
            allowNull: true,
        },
        //  S'il est User alors il a aucun ou un leader
        leader: {
            type: DataTypes.INTEGER,
            allowNull: true,
        }
    
    });
    
    //  Table de token d' authentification
    const Token = sequelize.define("AuthTokens", {
    
        id: {
            type: DataTypes.INTEGER,
            autoIncrement: true,
            primaryKey: true
        },
        authToken: {
            type: DataTypes.STRING,
            allowNull: false
        }
    
    });
    
    //  association de table admin et token
    //  un admin a plusieurs tokens
    Admin.hasMany(Token);
    //  un token est associe avec un seul admin
    Token.belongsTo(Admin);


    //  EMPLOYEE
    const Employee = sequelize.define( "employees", {

        id: {
            type: DataTypes.INTEGER,
            autoIncrement: true,
            primaryKey: true
        },

        matricule: {
            type: DataTypes.STRING(10),
            unique: true,
            allowNull: false
        },

        name_employee: {
            type: DataTypes.STRING,
            allowNull: false
        },

        last_name_employee: {
            type: DataTypes.STRING,
            allowNull: true
        },

        sexe_employee: {
            type: DataTypes.STRING(1),
            allowNull: false
        },

        birth_employee: {
            type: DataTypes.DATEONLY,
            allowNull: true
        },

        birth_place_employee: {
            type: DataTypes.STRING(50),
            allowNull: true
        },

        address_employee: {
            type: DataTypes.STRING,
            allowNull: true
        },

        ville_employee: {
            type: DataTypes.STRING,
            allowNull: true
        },

        cinemployee: {
            type: DataTypes.STRING(15),
            allowNull: true
        },

        date_cinemployee: {
            type: DataTypes.DATEONLY,
            allowNull: true
        },        

        cinplace_employee: {
            type: DataTypes.STRING(50),
            allowNull: true
        },

        marital_status_employee: {
            type: DataTypes.STRING(20),
            allowNull: true
        },

        nbr_child: {
            type: DataTypes.INTEGER,
            allowNull: true
        },

        contact_airtel: {
            type: DataTypes.STRING(13),
            allowNull: true
        },

        contact_telma: {
            type: DataTypes.STRING(13),
            allowNull: true
        },

        contact_orange: {
            type: DataTypes.STRING(13),
            allowNull: true
        },

        contact_flotte: {
            type: DataTypes.STRING,
            allowNull: true
        },

        num_cnaps: {
            type: DataTypes.STRING,
            allowNull: true
        },

        driver_licence: {
            type: DataTypes.STRING(10),
            allowNull: true
        },
        
        hereditary_illness: {
            type: DataTypes.STRING,
            allowNull: true
        },

        person_contact_emergency: {
            type: DataTypes.STRING(50),
            allowNull: true
        },

        contact_person_emergency: {
            type: DataTypes.STRING(50),
            allowNull: true
        },
        
        hiring_date: {
            type: DataTypes.DATEONLY,
            allowNull: true
        },
        category: {
            type: DataTypes.STRING(50),
            allowNull: true
        },
        debauch_date: {

            type: DataTypes.DATEONLY,
            allowNull: true
        },       
        nbr_interims: {
            type: DataTypes.INTEGER,
            allowNull: true
        } 
    });

    Admin.hasMany(Employee, { allowNull: true, unique: false});
    Employee.belongsTo(Admin,{ allowNull: true, unique: false });

    //  DEMANDEUR ET VALIDATEUR D'UN EMPLOYEE
    const adminEmployee = sequelize.define("adminEmployee", {
        id : {
            type: DataTypes.INTEGER,
            autoIncrement: true,
            primaryKey: true
        },
        isApplicant: {
            type: DataTypes.BOOLEAN,
            allowNull: true,
            defaultValue: false
        },
        isValidator: {
            type: DataTypes.BOOLEAN,
            allowNull: true,
            defaultValue: false
        }
    });

    Admin.belongsToMany(Employee, { through: adminEmployee, allowNull: true, unique: false });
    Employee.belongsToMany(Admin, { through: adminEmployee, allowNull: true, unique: false }); 

    const ChildEmployee = sequelize.define( "childEmployee", {
        id: {
            type: DataTypes.INTEGER,
            autoIncrement: true,
            primaryKey: true
        },
        birthChild: {
            type: DataTypes.DATEONLY,
            allowNull: false
        },
        sexe: {
            type: DataTypes.STRING(1),
            allowNull: false
        }
    });

    Employee.hasMany(ChildEmployee, { allowNull: true });
    ChildEmployee.belongsTo(Employee);

    //  Interimaire
    const Interim = sequelize.define("interim", {
        id: {
            type: DataTypes.INTEGER,
            autoIncrement: true,
            primaryKey: true
        },
        //  Id de l'employee interimaire
        interimId: {
            type: DataTypes.INTEGER,
            allowNull: true,
            unique: false
        }
    });

    //  Un employee a un ou plusieur interims
    Employee.hasMany(Interim);
    Interim.belongsTo(Employee);    

    //  FICHE DE PASSASSION
    const PassingFile = sequelize.define("passingFile", {
        id: {
            type: DataTypes.INTEGER,
            primaryKey: true,
            autoIncrement: true
        },
        poste: {
            type: DataTypes.STRING,
            allowNull: true
        },
        direction: {
            type: DataTypes.STRING,
            allowNull: true
        },
        holder: {
            type: DataTypes.STRING,
            allowNull: true
        },
        interim: {
            type: DataTypes.STRING,
            allowNull: true
        },        
        vacationId: {
            type: DataTypes.INTEGER,
            allowNull: true,
            unique: false
        },
        permissionId: {
            type: DataTypes.INTEGER,
            allowNull: true,
            unique: false,
        },
        medicalId: {
            type: DataTypes.INTEGER,
            allowNull: true,
            unique: false,
        }
    });    

    const Task = sequelize.define('task', {
        id: {
            type: DataTypes.INTEGER,
            autoIncrement: true,
            primaryKey: true
        },
        description: {
            type: DataTypes.TEXT,
            allowNull: true
        },
        deliverable: {
            type: DataTypes.STRING,
            allowNull: true
        },
        reference: {
            type: DataTypes.STRING,
            allowNull: true
        }
    });

    PassingFile.hasMany(Task, {allowNull: true, unique: false});
    Task.belongsTo(PassingFile, {allowNull: true, unique: false});

    const Personnel = sequelize.define('personnel', {
        id: {
            type: DataTypes.INTEGER,
            primaryKey: true,
            autoIncrement: true
        },
        name_and_last: {
            type: DataTypes.STRING,
            allowNull: true,
        },
        fonction: {
            type: DataTypes.STRING,
            allowNull: true
        }
    });

    PassingFile.hasMany(Personnel, { allowNull:true });
    Personnel.belongsTo(PassingFile, { allowNull: true });

    const Material = sequelize.define('material', {
        id: {
            type: DataTypes.INTEGER,
            primaryKey: true,
            autoIncrement: true
        },
        description: {
            type: DataTypes.STRING,
            allowNull: true
        },
        quantity: {
            type: DataTypes.STRING,
            allowNull: true
        },
        state: {
            type: DataTypes.STRING,
            allowNull: true
        }
    });

    PassingFile.hasMany(Material, { allowNull: true });
    Material.belongsTo(PassingFile, { allowNull: true });

    const Signature = sequelize.define('signature', {
        id: {
            type: DataTypes.INTEGER,
            primaryKey: true,
            autoIncrement: true
        },
        doc_type: {
            type: DataTypes.STRING,
            allowNull: true
        },
        responsability_level: {
            type: DataTypes.STRING,
            allowNull: true
        },        
    });

    PassingFile.hasMany(Signature, { allowNull: true });
    Signature.belongsTo(PassingFile, { allowNull: true });

    const Department = sequelize.define( "departments", {

        id: {
            type: DataTypes.INTEGER,
            autoIncrement: true,
            primaryKey: true
        },

        nameDepartment: {
            type: DataTypes.STRING(50),
            allowNull: false
        },

        descriptionDepartment: {
            type: DataTypes.STRING,
            allowNull: true
        }
    });

    // FONCTION DANS LA SOCIETE
    const Function = sequelize.define( "functions", {

        id: {
            type: DataTypes.INTEGER,
            autoIncrement: true,
            primaryKey: true
        },

        nameFunction: {
            type: DataTypes.STRING(50),
            allowNull: false,
            unique: true
        },        

        baseSalary: {
            type: DataTypes.STRING,
            allowNull: true
        },

    });

    Department.hasMany(Function, { allowNull: true });
    Function.belongsTo(Department, { allowNull: true });


    // FONCTION DE L'EMPLOYEE
    const EmployeeFunction = sequelize.define("employeeFunctions", {
        id: {
            type:DataTypes.INTEGER,
            primaryKey: true,
            autoIncrement: true
        },        
        date: {
            type: DataTypes.DATEONLY,            
        }
    });

    Employee.belongsToMany(Function, { through: EmployeeFunction, unique: false, allowNull: true });
    Function.belongsToMany(Employee, { through: EmployeeFunction, unique: false });

    //  CONGEE DE L'EMPLOYEE
    const Vacation = sequelize.define("vacations", {
        id: {
            type: DataTypes.INTEGER,
            primaryKey: true,
            autoIncrement: true
        },
        totalVacation: {
            type: DataTypes.FLOAT,
            allowNull: true
        },
        startDate: {
            type: DataTypes.DATEONLY,
            allowNull: true
        },
        startHour: {
            type: DataTypes.STRING(2),
            allowNull: true,
        },
        endDate: {
            type: DataTypes.DATEONLY,
            allowNull: true
        },
        endHour: {
            type: DataTypes.STRING(2),
            allowNull: true,
        },               
        reason: {
            type: DataTypes.TEXT,
            allowNull: true
        },
        //  Id du demandeur (user / admin /super admin)
        applicantId: {
            type: DataTypes.INTEGER,
            allowNull: true
        },       
        interimId: {
            type: DataTypes.INTEGER,
            allowNull: true
        } 
    });

    const vacationRejected = sequelize.define('vacationRejected', {
        id: {
            type: DataTypes.INTEGER,
            primaryKey: true,
            autoIncrement: true
        },
        employeeId: {
            type: DataTypes.INTEGER,
            allowNull: true
        },
        startDate: {
            type: DataTypes.DATEONLY,
            allowNull: true
        },
        endDate: {
            type: DataTypes.DATEONLY,
            allowNull: true
        }, 
        //  Reason rejected
        rejectReason: {
            type: DataTypes.STRING,
            allowNull: true
        },
        //  Id du rejecteur (user / admin / super admin)
        rejectedBy: {
            type: DataTypes.INTEGER,
            allowNull: true
        }        
    })

    //  Un employee a plusieurs conges
    //  Un congee enregistree est reserve seulement pour un employee
    Employee.hasMany(Vacation);
    Vacation.belongsTo(Employee);

    // Définir la relation entre Vacation et Admin
    Admin.hasMany(Vacation);
    Vacation.belongsTo(Admin);


    //  LES VARIABLES DE L'APPLICATION
    const Variable = sequelize.define('variables', {
        id: {
            type: DataTypes.INTEGER,
            primaryKey: true,
            autoIncrement: true,            
        },
        variable: {
            type: DataTypes.STRING(50),
            unique: true,
            allowNull: false
        },
        value: {
            type: DataTypes.FLOAT,
            allowNull: true
        }
    });    

    //  TABLE DES CV DES EMPLOYEES
    const Cv = sequelize.define('cv', {
        id: {
            type: DataTypes.INTEGER,
            primaryKey: true,
            autoIncrement: true
        },
        filename: {
            type: DataTypes.STRING,
            allowNull: false
        },
        path: {
            type: DataTypes.STRING,
            allowNull: false
        },
        mimetype: {
            type: DataTypes.STRING,
            allowNull: false
        }
    });
    Employee.hasMany(Cv);
    Cv.belongsTo(Employee);

    //  TABLE DES PHOTOS DES EMPLOYEES
    const Photo = sequelize.define('photo', {
        id: {
            type: DataTypes.INTEGER,
            primaryKey: true,
            autoIncrement: true
        },
        filename: {
            type: DataTypes.STRING,
            allowNull: false
        },
        path: {
            type: DataTypes.STRING,
            allowNull: false
        },
        mimetype: {
            type: DataTypes.STRING,
            allowNull: false
        }
    });
    Employee.hasMany(Photo);
    Photo.belongsTo(Employee);

    const Permission = sequelize.define('permissions', {
        id: {
            type: DataTypes.INTEGER,
            primaryKey: true,
            autoIncrement: true
        },
        nbrDays: {
            type: DataTypes.INTEGER,
            allowNull: true
        },
        startDate: {
            type: DataTypes.DATEONLY,
            allowNull: true
        },
        endDate: {
            type: DataTypes.DATEONLY,
            allowNull: true
        },                
        event: {
            type: DataTypes.TEXT,
            allowNull: true
        },
        //  Id du demandeur (user / admin /super admin)
        applicantId: {
            type: DataTypes.INTEGER,
            allowNull: true
        },       
        interimId: {
            type: DataTypes.INTEGER,
            allowNull: true
        },

    });

    Employee.hasMany(Permission);
    Permission.belongsTo(Employee);

    Admin.hasMany(Permission, { allowNull: true });
    Permission.belongsTo(Admin, { allowNull: true });

    const PermissionJustificative = sequelize.define('permissionJustificative', {
        id: {
            type: DataTypes.INTEGER,
            autoIncrement: true,
            primaryKey: true,
        },
        filename: {
            type: DataTypes.STRING,
            allowNull: false
        },
        path: {
            type: DataTypes.STRING,
            allowNull: false
        },
        mimetype: {
            type: DataTypes.STRING,
            allowNull: false
        }
    });

    Permission.hasMany(PermissionJustificative);
    PermissionJustificative.belongsTo(Permission);

    const PermissionRejected = sequelize.define('permissionRejected', {
        id: {
            type: DataTypes.INTEGER,
            primaryKey: true,
            autoIncrement: true
        },
        employeeId: {
            type: DataTypes.INTEGER,
            allowNull: true
        },
        startDate: {
            type: DataTypes.DATEONLY,
            allowNull: true
        },
        endDate: {
            type: DataTypes.DATEONLY,
            allowNull: true
        }, 
        //  Reason rejected
        rejectReason: {
            type: DataTypes.STRING,
            allowNull: true
        },
        //  Id du rejecteur (user / admin / super admin)
        rejectedBy: {
            type: DataTypes.INTEGER,
            allowNull: true
        }        
    })


    const Medical = sequelize.define('medicals', {
        id: {
            type: DataTypes.INTEGER,
            primaryKey: true,
            autoIncrement: true
        },
        nbrDays: {
            type: DataTypes.INTEGER,
            allowNull: true
        },
        sick: {
            type: DataTypes.STRING,
            allowNull: true,        
        },
        startDate: {
            type: DataTypes.DATEONLY,
            allowNull: true
        },
        endDate: {
            type: DataTypes.DATEONLY,
            allowNull: true
        },                        
        //  Id du demandeur (user / admin /super admin)
        applicantId: {
            type: DataTypes.INTEGER,
            allowNull: true
        },       
        interimId: {
            type: DataTypes.INTEGER,
            allowNull: true
        },

    });

    Employee.hasMany(Medical);
    Medical.belongsTo(Employee);

    Admin.hasMany(Medical, { allowNull: true });
    Medical.belongsTo(Admin, { allowNull: true });

    const MedicalJustificative = sequelize.define('medicalJustificative', {
        id: {
            type: DataTypes.INTEGER,
            autoIncrement: true,
            primaryKey: true,
        },
        filename: {
            type: DataTypes.STRING,
            allowNull: false
        },
        path: {
            type: DataTypes.STRING,
            allowNull: false
        },
        mimetype: {
            type: DataTypes.STRING,
            allowNull: false
        }
    });

    Medical.hasMany(MedicalJustificative);
    MedicalJustificative.belongsTo(Medical);

    const MedicalRejected = sequelize.define('medicalRejected', {
        id: {
            type: DataTypes.INTEGER,
            primaryKey: true,
            autoIncrement: true
        },
        employeeId: {
            type: DataTypes.INTEGER,
            allowNull: true
        },
        startDate: {
            type: DataTypes.DATEONLY,
            allowNull: true
        },
        endDate: {
            type: DataTypes.DATEONLY,
            allowNull: true
        }, 
        //  Reason rejected
        rejectReason: {
            type: DataTypes.STRING,
            allowNull: true
        },
        //  Id du rejecteur (user / admin / super admin)
        rejectedBy: {
            type: DataTypes.INTEGER,
            allowNull: true
        }        
    })

    const Planning = sequelize.define('planning', {
        id: {
            type: DataTypes.INTEGER,
            primaryKey: true,
            autoIncrement: true
        },
        startDate: {
            type: DataTypes.DATEONLY,
            allowNull: true
        },
        startHour: {
            type: DataTypes.STRING(2),
            allowNull: true,
        },
        endDate: {
            type: DataTypes.DATEONLY,
            allowNull: true
        },
        endHour: {
            type: DataTypes.STRING(2),
            allowNull: true,
        },                               
        applicantId: {
            type: DataTypes.INTEGER,
            allowNull: true
        },       
    })

    Employee.hasMany(Planning);
    Planning.belongsTo(Employee);

    const Holiday = sequelize.define('holidays', {
        id: {
            type: DataTypes.INTEGER,
            primaryKey: true,
            autoIncrement: true,
        },
        date: {
            type: DataTypes.DATEONLY,
            allowNull: false,
            unique: true,
        },
        description: {
            type: DataTypes.STRING(100),
            allowNull: true,
        }
    })

    return {
        Admin,
        Token,
        Employee,
        Function,
        EmployeeFunction,
        Vacation,
        Department,
        ChildEmployee,
        Variable,
        Cv,
        vacationRejected,
        adminEmployee,
        Photo,
        Interim,
        PassingFile,
        Task,
        Personnel,
        Material,
        Signature,
        Permission,
        PermissionJustificative,
        PermissionRejected,
        Medical,
        MedicalJustificative,
        MedicalRejected,
        Planning,
        Holiday
    }

}

