const { Model, DataTypes, Op } = require('sequelize');
const sequelize = require('../config/db.js');
const Entity = require('./entity.js');
const { sanitizeSort, sanitizePagination } = require('./querySafety.js');

class Tax extends Model {

    static associate(models) {

        Tax.belongsToMany(models.Billable, { 
            through: "billable_tax"
        }); 

        Tax.belongsTo(models.Entity, {
            as: "entity",
            foreignKey: "ent_id"
        });
    }

    async createTax(data, creatorId) {
        try {
            const tax = await Tax.create({...data, creatorId});
            console.log(tax.toJSON());
            return tax.toJSON();
        }
        catch (err) {
            console.log(err);
            return err;
        }
    }
    
    async getTax(id) {
        try {
            const tax = await Tax.findAll(
                {
                    include: [
                        {
                            model: Entity,
                            as: "entity",
                            where: {
                                id: id
                            },
                            attributes: []
                        }
                    ],
                    attributes: ["id", "name", "perc"]
                }
            );
            console.log(tax.map(t => t.toJSON()));
            return tax.map(t => t.toJSON());
        }
        catch (err) {
            console.log(err);
            return err;
        }
    }

    async readTax(ordCol, ordDir, offsetVal, limitVal, id, searhTerm) {
        try {
            const [safeOrderCol, safeOrderDir] = sanitizeSort(ordCol, ordDir, [
                'id', 'name', 'description', 'shortcode', 'taxcode', 'perc', 'start_date', 'end_date', 'ent_id', 'creatorId', 'createdAt', 'updatedAt'
            ]);
            const { safeOffset, safeLimit } = sanitizePagination(offsetVal, limitVal);
            const tax = await Tax.findAll(
                {
                    where: searhTerm
                        ? {
                            [Op.or]: [
                                { name: { [Op.like]: `%${searhTerm}%` } },
                                { shortcode: { [Op.like]: `%${searhTerm}%` } },
                                { taxcode: { [Op.like]: `%${searhTerm}%` } },
                            ]
                        }
                    : {},
                    include: [
                        {
                            model: Entity,
                            as: "entity",
                            where: {
                                id: id
                            },
                            attributes: []
                        }
                    ],
                    order: [[safeOrderCol, safeOrderDir]],
                    offset: safeOffset,
                    limit: safeLimit,
                }
            );
            console.log(tax);
            return tax;
        }
        catch (err) {
            console.log(err);
            return err;
        }
    }

    async readTaxRow(data) {
        try {
            const tax = await Tax.findOne(
                {
                    where: {
                        id: data.id
                    }
                }
            )
            console.log(tax.toJSON());
            return tax.toJSON();
        }
        catch (err) {
            console.log(err);
            return err;
        }
    } 

    async updateTax(data) {
        try {
            const result = await Tax.update(data, {where: {id: data.id}});
            console.log(`Tax with ${data.id} updated`, result[0]);
            return result[0];
        }
        catch (err) {
            console.log(err);
            return err;
        }
    }

    async deleteTax(data) {
        try {
            const result = await Tax.destroy(
                {
                    where: {id: data.id}
                }
            );

            if (result) {
                console.log(`Tax ${data.id} deleted`);
                return `Tax ${data.id} deleted`;
            }
            else {
                console.log(`Tax ${data.id} not found`);
                return `Tax ${data.id} not found`;
            }
        }
        catch (err) {
            console.log(err);
            return err;
        }
    }

    async countTax(id) {
        try {
            const count = await Tax.count(
                {
                    include: [
                        {
                            model: Entity,
                            as: "entity",
                            where: {
                                id: id
                            },
                        }
                    ]
                }
            );
            console.log(count);
            return count;
        }
        catch (err) {
            console.log(err);
            return err;
        }
    }
}

Tax.init(
    {
        name: {
            type: DataTypes.STRING(50),
            allowNull: false
        },
        description: {
            type: DataTypes.TEXT,
            allowNull: true
        },
        shortcode: {
            type: DataTypes.STRING(25),
            allowNull: false
        },
        taxcode: {
            type: DataTypes.STRING(25),
            allowNull: false
        },
        perc: {
            type: DataTypes.STRING(25),
            allowNull: false
        },
        start_date: {
            type: DataTypes.DATE,
            allowNull: false
        },
        end_date: {
            type: DataTypes.DATE,
            allowNull: false
        },
        ent_id: {
            type: DataTypes.INTEGER,
            allowNull: true,
            references: {
                model: 'entity',
                key: 'id'
            }
        },
        creatorId: {
            type: DataTypes.INTEGER,
            allowNull: false
        }
    },
    {
        sequelize,
        modelName: "Tax",
        tableName: "tax"
    }
)

module.exports = Tax;