const db = require('../models');
const FileDBApi = require('./file');
const crypto = require('crypto');
const Utils = require('../utils');

const Sequelize = db.Sequelize;
const Op = Sequelize.Op;

module.exports = class Lead_matchesDBApi {
    static async findAll(filter, options) {
        const limit = filter.limit || 0;
        let offset = 0;
        let where = {};
        const currentPage = +filter.page;
        offset = currentPage * limit;

        const currentUser = options?.currentUser;
        const transaction = (options && options.transaction) || undefined;

        // Data Isolation for Fix-It-Local™
        if (currentUser && currentUser.app_role) {
            const roleName = currentUser.app_role.name;
            if (roleName === 'Verified Business Owner') {
                // Business owners only see matches for THEIR businesses
                where['$business.owner_userId$'] = currentUser.id;
            } else if (roleName === 'Consumer') {
                // Consumers only see matches for THEIR leads
                where['$lead.userId$'] = currentUser.id;
            }
        }

        let include = [
            { model: db.leads, as: 'lead' },
            { model: db.businesses, as: 'business' }
        ];

        if (filter) {
            if (filter.id) where.id = Utils.uuid(filter.id);
            if (filter.status) where.status = filter.status;
        }

        const queryOptions = {
            where,
            include,
            distinct: true,
            limit: options?.countOnly ? undefined : (limit ? Number(limit) : undefined),
            offset: options?.countOnly ? undefined : (offset ? Number(offset) : undefined),
            order: [['createdAt', 'desc']],
            transaction
        };

        const { rows, count } = await db.lead_matches.findAndCountAll(queryOptions);

        return {
            rows: options?.countOnly ? [] : rows,
            count: count
        };
    }

    static async findBy(where, options) {
        const transaction = (options && options.transaction) || undefined;
        const lead_matches = await db.lead_matches.findOne({ 
            where,
            include: [
                { model: db.leads, as: 'lead' },
                { model: db.businesses, as: 'business' }
            ],
            transaction 
        });
        return lead_matches ? lead_matches.get({plain: true}) : null;
    }

    static async update(id, data, options) {
        const currentUser = (options && options.currentUser) || {id: null};
        const transaction = (options && options.transaction) || undefined;
        const record = await db.lead_matches.findByPk(id, {transaction});
        if (!record) return null;

        const updatePayload = { ...data, updatedById: currentUser.id };
        await record.update(updatePayload, {transaction});
        return record;
    }

    static async create(data, options) {
        const currentUser = (options && options.currentUser) || { id: null };
        const transaction = (options && options.transaction) || undefined;
        const record = await db.lead_matches.create({
            ...data,
            createdById: currentUser.id,
            updatedById: currentUser.id
        }, { transaction });
        return record;
    }

    static async remove(id, options) {
        const currentUser = (options && options.currentUser) || {id: null};
        const transaction = (options && options.transaction) || undefined;
        const record = await db.lead_matches.findByPk(id, options);
        await record.update({ deletedBy: currentUser.id }, { transaction });
        await record.destroy({ transaction });
        return record;
    }
};