

const Encoder = require('./lib/encoder');
const embeddings = require('./data/embeddings.min.json');
const chapters = require('./data/chapters.json');
const math = require('mathjs');
const fs = require('fs');

/**
 * Compute dot product of two vectors
 * @param {*} a 
 * @param {*} b 
 */
const dot = (a,b) => math.dot(math.matrix(a),math.matrix(b));

/**
 * 
 */
class SearchEngine {
    constructor() {
        this.encoder = new Encoder();
    }

    /**
     * 
     */
    load() {
        return this.encoder.load();
    }

    /**
     * 
     * @param {*} query 
     * @param {*} n 
     */
    async search(query, n=10) {
        let target = (await this.encoder.encode([query.toUpperCase()]))[0];
        let similarity = [];
    
        for (var i=0; i< embeddings.length; i++) {
            let data = embeddings[i];
            let embedding = data.shortEncoding;
            let sim = dot(target, embedding);
            similarity.push([sim, data]);
        }
    
        similarity = similarity.sort((a,b) => {
            return b[0] - a[0]
        });

        let result = [];
        for (var i=0; i<n; i++) {
            let { htsCode, shortDescription, longDescription } = similarity[i][1];
            let chapter = chapters.find(x => x.includes(`Chapter ${htsCode.substring(0,2)}:`))
            result.push({
                htsCode, shortDescription, longDescription, chapter
            });
        }

        return result;
    }
}


module.exports = SearchEngine;


/*
let e = new SearchEngine();
e.load()
    .then(() => {
        e.search('Diesel truck', 2).then(console.log)
    });
*/