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

class BankBranch extends Model {

    static associate(models) {

        BankBranch.hasMany(models.BankAccount, { 
            as: "bank_accounts", 
            foreignKey: "branch_id"
        });

        BankBranch.belongsTo(models.Bank, { 
            as: "bank", 
            foreignKey: "bank_id"
        });
    }

    async createBranch(data, creatorId) {
        try {
            const branch = await BankBranch.create({...data, creatorId});
            console.log(branch.toJSON());
            return branch.toJSON();
        }
        catch (err) {
            console.log(err);
            return err;
        }
    }

    async getBranchesList(id) {
        try {
            const branches = await BankBranch.findAll({
                where: {
                    bank_id: id  
                },
                attributes: ["id", "name", "ifsc"] 
            });
    
            console.log(branches.map(b => b.toJSON()));
            return branches.map(b => b.toJSON());
        } catch (err) {
            console.log(err);
            return err;
        }
    }    
    
    async readBranch(ordCol, ordDir, offsetVal, limitVal, searchTerm) {
        try {
            const [safeOrderCol, safeOrderDir] = sanitizeSort(ordCol, ordDir, [
                'id', 'name', 'bank_id', 'ent_id', 'code', 'ifsc', 'other_details', 'location', 'address', 'status', 'creatorId', 'createdAt', 'updatedAt'
            ]);
            const { safeOffset, safeLimit } = sanitizePagination(offsetVal, limitVal);
            const branch = await BankBranch.findAll(
                {
                    where: searchTerm 
                        ? {
                            [Op.or]: [
                                {name: {[Op.like]: `%${searchTerm}%`}},
                                {ifsc: {[Op.like]: `%${searchTerm}%`}},
                            ]
                        }
                    : {},
                    include: [
                        {
                            model: Bank,
                            as: "bank",
                            attributes: ["name"]
                        }
                    ],
                    order: [[safeOrderCol, safeOrderDir]],
                    offset: safeOffset,
                    limit: safeLimit,
                    raw: true,
                    nest: false
                }
            );
            console.log(branch);
            return branch;
        }
        catch (err) {
            console.log(err);
            return err;
        }
    }

    async readBranchRow(data) {
        try {
            const branch = await BankBranch.findOne(
                {
                    where: {
                        id: data.id
                    }
                }
            )
            console.log(branch.toJSON());
            return branch.toJSON();
        }
        catch (err) {
            console.log(err);
            return err;
        }
    } 

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

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

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

    async countBranch() {
        try {
            const count = await BankBranch.count();
            console.log(count);
            return count;
        }
        catch (err) {
            console.log(err);
            return err;
        }
    }
}

BankBranch.init(
    {
        name: {
            type: DataTypes.STRING(100),
            allowNull: false
        },
        bank_id: {
            type: DataTypes.INTEGER,
            allowNull: false,
            references: {
                model: 'banks',
                key: 'id'
            }
        },
        ent_id: {
            type: DataTypes.INTEGER,
            allowNull: false,
            references: {
                model: 'entity',
                key: 'id'
            }
        },
        code: {
            type: DataTypes.STRING(25),
            allowNull: false
        },
        ifsc: {
            type: DataTypes.STRING(25),
            allowNull: false
        },
        other_details: {
            type: DataTypes.TEXT,
            allowNull: true
        },
        location: {
            type: DataTypes.STRING(250),
            allowNull: false
        },
        address: {
            type: DataTypes.STRING(250),
            allowNull: false
        },
        status: {
            type: DataTypes.STRING(25),
            allowNull: false
        },
        creatorId: {
            type: DataTypes.INTEGER,
            allowNull: false
        }
    },
    {
        sequelize,
        modelName: "BankBranch",
        tableName: "bank_branch"
    }
)

module.exports = BankBranch;