const FileHound = require('FileHound');
const fs = require('fs');
const {shell} = require('electron');
const config = require('../../config.js');
const Extractor = require('./Extractor');
const Result = require('../Results/Result.js');
const ImageResult = require('../Results/ImageResult.js');
const AudioResult = require('../Results/AudioResult.js');
const VideoResult = require('../Results/VideoResult.js');

const FileExtractor = function() {
	Extractor.call(this, 'FileExtractor');
};
FileExtractor.prototype = Object.create(Extractor.prototype);

FileExtractor.prototype.imageTypes = [/\.jpg$/, /\.png$/, /\.jpeg$/, /\.webp$/, /\.gif$/, /\.bmp$/];
FileExtractor.prototype.audioTypes = [/\.mp3$/, /\.wav$/];
FileExtractor.prototype.videoTypes = [/\.mp4$/, /\.webm$/];
FileExtractor.prototype.init = function(callback) {
	const files = localStorage.getItem('files');
	if(files && files.length > 0) {
		try {
			this.files = JSON.parse(files);
			this.ready = true;
			console.log(`FileExtractor loaded ${files.length} files from storage`);
		} catch(err) {
			localStorage.removeItem('files')
			alert('Previous index has been corrupted, please enter "reindex" to reindex your files')
			this.ready = true
		}
	}
	else if(config.file && 
	config.file.extensions && 
	config.file.extensions.length > 0 &&
	config.file.paths &&
	config.file.paths.length > 0) {
		const filehound = FileHound.create();
		filehound
			.paths(config.file.paths)
			.ext(config.file.extensions)
			.find((error, files) => {
				if(files) {
					this.files = files;
					this.ready = true;
					localStorage.setItem('files', JSON.stringify(files));
					if(typeof callback === 'function')
						callback()
					console.log(`FileExtractor finished indexing ${files.length} files`);
				} else {
					alert(`FileExtractor could not properly index your files, please check your paths in config.js`)
				}
			});


	} else
		console.log('Please define file.extensions (Array) and file.paths (Array) in your config.js');
}
FileExtractor.prototype.extract = function(query) {
	this.results = [];
	if(this.ready && query.toLowerCase().trim() === 'reindex') {
		const result = new Result('FileExtractor: Reindex')
		result.subtitle = 'Rebuilds the index to all files in your currently configured file paths'
		const parent = this
		result.primaryAction = function() {
			localStorage.removeItem('files')
			parent.init(_ => {
				document.dispatchEvent(new Event('clearQuery'))
			})
		}
		result.weight = 100
		this.results.push(result)
	}
	if(this.ready && query.trim().length > 2) {
		const subqueries = query.split(' ');
		const targetFiles = this.files.filter(file => this.matchAll(file, subqueries)).slice(0, config.file.resultLimit ? config.file.resultLimit : 12);
		targetFiles.forEach(file => {
			const fileInfo = this.getFileInfo(file);
			let result = null;

			if(this.imageTypes.filter(_ => _.test(file)).length > 0) {
				result = new ImageResult(fileInfo.name, this.getFile(file));
				result.subtitle = fileInfo.path;
			} else if(this.audioTypes.filter(_ => _.test(file)).length > 0) {
				result = new AudioResult(fileInfo.name, this.getFile(file));
				result.subtitle = fileInfo.path;
			} else if(this.videoTypes.filter(_ => _.test(file)).length > 0) {
				result = new VideoResult(fileInfo.name, this.getFile(file));
				result.subtitle = fileInfo.path;
			} else {
				result = new Result(fileInfo.name);
				result.subtitle = fileInfo.path;
			}

			if(result !== null) {
				result.primaryAction = function() {
					shell.openItem(file);
					if(this.player) this.player.pause()
					Result.prototype.primaryAction.call(this);
				};
				result.secondaryAction =  function() {
					shell.showItemInFolder(file);
					if(this.player) this.player.pause()
					Result.prototype.primaryAction.call(this);
				};
				this.results.push(result);
			}
		});
	}
};
FileExtractor.prototype.matchAll = function(filename, queries) {
	filename = filename.toLowerCase();
	for(let i = 0; i < queries.length; i++)
		if(filename.indexOf(queries[i].toLowerCase()) < 0)
			return false;
	return true;
};
FileExtractor.prototype.getFile = function(path) {
	return path.replace(/\\/g, '/');
};
FileExtractor.prototype.getFileInfo = function(path) {
	return {
		'name': path.match(/[\\\/]([^\\\/]+?)$/)[1],
		'path': path.match(/^(.+)[\\\/]/)[1],
		'extension': path.match(/\.([^.]+?)$/)[1]
	};
}

module.exports = FileExtractor;