const { DataTypes, Sequelize } = require("sequelize");

const defaultKeys = (name) => {
    return {
        id: {
            allowNull: false,
            autoIncrement: true,
            primaryKey: true,
            type: DataTypes.INTEGER
        },
        [name]: {
            type: DataTypes.STRING,
            unique: true,
            allowNull: false,
            defaultValue: DataTypes.UUIDV4,
        },
    };
};


const migrationDefaults = (options = { withUser: true, isUser: false, paranoid: true }) => {
    const withUser = options.withUser ?? true;
    const isUser = options.isUser ?? false;
    const paranoid = options.paranoid ?? true;

    const defaultColumns = {
        created_at: {
            type: 'TIMESTAMP',
            allowNull: false,
            defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'),
        },
        updated_at: {
            type: 'TIMESTAMP',
            allowNull: false,
            defaultValue: Sequelize.literal('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'),
        },
    };

    if (paranoid) {
        defaultColumns['deleted_at'] = {
            type: DataTypes.DATE,
            allowNull: true,
            defaultValue: null,
        };
    }

    if (withUser) {
        defaultColumns['created_by'] = {
            type: DataTypes.STRING,
            allowNull: isUser,
            references: {
                key: 'user_id',
                model: 'users',
            },
        };
        defaultColumns['updated_by'] = {
            type: DataTypes.STRING,
            allowNull: true,
            defaultValue: null,
            references: {
                key: 'user_id',
                model: 'users',
            },
        };
        if (paranoid) {
            defaultColumns['deleted_by'] = {
                type: DataTypes.STRING,
                allowNull: true,
                defaultValue: null,
                references: {
                    key: 'user_id',
                    model: 'users',
                },
            };
        }
    }

    return defaultColumns;
};

const actionUsers = (model, models, isUser = false) => {
    model.belongsTo(models.User, {
        targetKey: 'user_id',
        foreignKey: {
            name: 'created_by',
            allowNull: isUser,
        },
        as: 'user_created',
    });
    model.belongsTo(models.User, {
        targetKey: 'user_id',
        foreignKey: {
            name: 'updated_by',
            allowNull: true,
        },
        as: 'user_updated',
    });
    model.belongsTo(models.User, {
        targetKey: 'user_id',
        foreignKey: {
            name: 'deleted_by',
            allowNull: true,
        },
        as: 'user_deleted',
    });
}

const modelDefaults = (sequelize, tableName, paranoid = true) => {
    const initConfig = {
        sequelize,
        tableName,
        createdAt: "created_at",
        updatedAt: "updated_at",
    };

    if (paranoid) {
        initConfig.paranoid = true;
        initConfig.deletedAt = 'deleted_at';
    }

    return initConfig;
};


const relationShip = ({ modelName, key, allowNull = false, unique = false, onDelete = "CASCADE", onUpdate = "CASCADE" }) => {
    return {
        type: DataTypes.STRING,
        allowNull: allowNull,
        onDelete: onDelete,
        onUpdate: onUpdate,
        references: {
            key: key,
            model: modelName,
        },
        unique: unique,
    };
};

module.exports = {
    defaultKeys,
    migrationDefaults,
    modelDefaults,
    relationShip,
    actionUsers,
};