const path = require('path');
const fs = require('fs');
const gconnect = require('gulp-connect');
const puppeteer = require('puppeteer');
const gulp = require('gulp');
const imageResize = require('gulp-image-resize');
const rename = require("gulp-rename");

var current_section = "posts";

let dir = process.env.npm_config_path;
if (dir) {
	console.log('Starting directory: ' + process.cwd());
	try {
	  process.chdir(dir);
	  console.log('New directory: ' + process.cwd());
	}
	catch (err) {
	  console.log('chdir: ' + err);
	}
}

themeName = path.basename(process.cwd());

async function connect() {
	 return await gconnect.server({
        port: 8008,
		root: './',
    });
}

async function disconnect() {
	return await gconnect.serverClose();
}

async function screenshots(type = "sections", dirs = []) {
	let sectionsDir = path.resolve("./" + type);
	let screenshotDir = path.resolve("./screenshots/" + type + "/");
	let styleCss = path.resolve("./css/style.bundle.css");
	let selector = "body > section";
	let sections = [];
	let baseDir = path.resolve(".");
	let json = {};
	let themeColor = "light";

	if (fs.existsSync(path.resolve('./theme.json'))) {
		let data = fs.readFileSync(path.resolve('./theme.json'));
		if (data) {
			json = JSON.parse(data); 
		}
	}

	if (json.dark) {
		themeColor = "dark";
	}

	if (!dirs.length) {
		dirs = fs.readdirSync(sectionsDir).map(fileName => {
		  let filePath = `${sectionsDir}/${fileName}`;
		  let stat = fs.statSync(filePath)

			if (stat.isDirectory()) {
				let files = fs.readdirSync(filePath).map(sectionFile => {
					//if (filePath.indexOf(current_section) > 0) 
					{
						sections.push(`${filePath}/${sectionFile}`);
					}
					
				});
			}
				
		});	 	
	}

	const browser = await puppeteer.launch({
		args: [
		  '--start-maximized',
		 //'--font-render-hinting=none'
		],
		//headless: false,
		//slowMo: 250,
		//devtools: true, 
	});
	const page = await browser.newPage();
	await page.setUserAgent(
	  "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36",
	);
	
	let viewport = {
		width: 1500,
		height: 800,
		//deviceScaleFactor: 2
	};
	
	if (type == "styles") viewport = {
		width: 80,
		height: 60,
	};
	//await page.setRequestInterception(true);
	await page.setViewport(viewport);

	page.on('console', (msg) => console.log('PAGE LOG:', msg.text));

	await page.evaluate(() => console.log(`url is ${location.href}`));
	/*
	page.on('request', (request) => {
	if (request.resourceType() === 'image') request.abort();
	else request.continue();
	});
	*/ 

	let tempFiles = [];
	
	for (i in sections) {
		section = sections[i];
		if (section.endsWith("-screenshot.html")) continue;
		
		screenshot = section.replace(sectionsDir, screenshotDir).replace('.html', '.webp');
		tempFiles.push(screenshot);
		sectionScreenshot = section.replace('.html', '-screenshot.html');
		tempFiles.push(sectionScreenshot);
		
		//gutil.log(`Start screenshot for '${gutil.colors.cyan(section)}' to '${gutil.colors.magenta(screenshot)}'`);
		console.log(`Start screenshot for '${section}' to '${screenshot}'`);
		
		folderName = path.dirname(screenshot);
		if (!fs.existsSync(folderName)) {
			fs.mkdirSync(folderName)
		}			

		let content = fs.readFileSync(section,'utf8');
		let html = `<html data-vvvebjs-editor data-bs-theme="${themeColor}"><head><base href="../../"><link href="/css/style.bundle.css" rel="stylesheet"><link href="/css/screenshots.css" rel="stylesheet"><style>[data-reveal], [data-section] > * {
    opacity: 1;
    transform: translate(0);
}</style></head><body>${content}</body></html>`;
		//if (type == "styles") html = content;

		fs.writeFileSync(sectionScreenshot, html);
		
		//await page.setContent(html, {"waitUntil":"networkidle0"});

		url = "http://127.0.0.1:8008" + sectionScreenshot.replace(baseDir, '');
		/*	
		await Promise.all([ page.goto(url, { waitUntil: "load", timeout: 10000 }).catch(e => {
		  if (e.message.includes('net::ERR_ABORTED')) { console.log('PAGE LOG:', e.message) }
		}), page.waitForNavigation() ]);
		*/ 
		
		await page.goto(url, { waitUntil: "load", timeout: 10000 }).catch(e => {
		  console.log('PAGE LOG:', e.message);
		  //if (e.message.includes('net::ERR_ABORTED')) { console.log('PAGE LOG:', e.message) }
		});
		//await page.goto("file://" + section);
		/*
		await page.addStyleTag({url: `file://${styleCss}`})
		const result = await page.evaluate((baseHref) => {
			let head = document.querySelector('head');
			let base = document.createElement("base");
			base.href= `file://${baseHref}/`;
			head.append(base);
		}, baseHref);
		*/
		//await page.waitForNavigation();

	    await page.waitForSelector("body > div, body > section, body > header, body > footer, body > *");
		const element = await page.$$("body > div, body > section, body > header, body > footer, body > *");
		//await page.screenshot({ path: screenshot, fullPage: false, type: 'png' });
		await element[0].screenshot({ path: screenshot, type: 'webp' });
		
		gulp.src(screenshot)
		.pipe(imageResize({
		  width : 480,
		  format: "webp",
		  quality:0,
		}))
		.pipe(rename(function (path) { path.basename += "-thumb"; }))
		.pipe(gulp.dest(folderName)).on('end', () => {
			//remove original screenshot and keep only thumb
			 
		});
		
		
	}

	await browser.close();

	tempFiles.map(screenshot => {
		
		fs.stat(screenshot, function (err, stats) {

			   if (err) {
				   return console.error(err);
			   }

			   fs.unlink(screenshot,function(err){
					if(err) {
						return console.log(err);
					}
					//console.log('file deleted successfully');
			   });  
			})
	});
	
	return true;
}

let templates = {
'section':{
	'group':`
	Vvveb.SectionsGroup["{{group}}"] = [{{groupList}}];
`,
	'section':
`Vvveb.Sections.add("{{id}}", {
    name: "{{name}}",
    image: Vvveb.themeBaseUrl + "/{{image}}",
    html: \`{{html}}\`
});`
},
'block': {
	'group':`
	Vvveb.BlocksGroup['{{group}}'] = [{{groupList}}];
`,
	'section':
`Vvveb.Blocks.add("{{id}}", {
    name: "{{name}}",
    image: Vvveb.themeBaseUrl + "/{{image}}",
    html: \`{{html}}\`
});`
},
'style': {
	'group':`
	Vvveb.StylesGroup['{{group}}'] = [{{groupList}}];
`,
	'style':
`Vvveb.Styles.add("{{id}}", {
    name: "{{name}}",
    image: Vvveb.themeBaseUrl + "/{{image}}",
    html: "",
    style: \`{{style}}\`
});`
}};

function template(template, data) {
	return template.replace(/{{(.+?)}}/gm, function(match,  p1) {
		return data[p1];
	})
}

function prettify(str) {
  return str.charAt(0).toUpperCase() + str.slice(1).replace(/[-_]/g,' ');
}

let sectionsSortOrder = [ "hero", "features",  "banner", "services"];

//generate sections for VvvebJs
function sections(type = "section", dirs = []) {
	let sectionsDir = path.resolve(`./${type}s/`);
	let styleCss = path.resolve("./css/style.bundle.css");
	let baseDir = path.resolve(".");
	let dir = [];
	let sectionsJs = '';

	if (!dirs.length) {
		dirs = fs.readdirSync(sectionsDir).map(fileName => {
			let stat = fs.statSync(`${sectionsDir}/${fileName}`);

			if (stat.isDirectory()) {
				dir.push(fileName);
			}
		});
	}
	//console.dir(dir);
	sectionsSortOrder.reverse();
	//sort sections
	dir.sort((a, b) => sectionsSortOrder.indexOf(b) - sectionsSortOrder.indexOf(a));
	
	//set theme sections first if available
	const index = dir.indexOf(themeName);
	if (index > -1) {
	  dir.splice(index, 1);
	  dir.unshift(themeName);
	  
	}	

	for (i in dir) {
	  let fileName =  dir[i];		
	  let filePath = `${sectionsDir}/${fileName}`;


		let group = fileName;
		let name;
		let id;
		let html;
		let sectionsHtml = `<html data-vvvebjs-editor><head><base src="../"><link href="../css/style.bundle.css" rel="stylesheet"><link href="../css/screenshots.css" rel="stylesheet"><style>[data-reveal], [data-section] > * {
    opacity: 1;
    transform: translate(0);
}</style><link href="../css/screenshots.css" rel="stylesheet"></head><body>`;
		let image = '';
		
		let sections = [];
		let files = fs.readdirSync(filePath).
		sort((a, b) => parseInt(a.replace( /^\D+/g, '')) - parseInt(b.replace( /^\D+/g, ''))).
		map(sectionFile => {
			
			name = sectionFile.replace(".html","");
			id = `${group}/${name}`;
			name = prettify(name);
			image = `screenshots/${type}s/${group}/` + sectionFile.replace(".html", "-thumb.webp");
			html = fs.readFileSync(`${filePath}/${sectionFile}`,'utf8');
			sections.push(id);
			
			sectionsJs += template(templates[type]['section'], {id, name, image, html});
			sectionsHtml += html.replace('<section', '<section title="' + name + '"');
		});
		
		fs.writeFileSync(filePath + ".html", sectionsHtml + "</body></html>");
		
		let groupList = '"' + sections.join('","') + '"';
		group = prettify(group);
		sectionsJs += template(templates[type]['group'], {group, groupList});
	}
	
	return fs.writeFileSync(/*path.resolve(".") + *//*`${sectionsDir}/${type}s.js`*/path.resolve(".") + `/${type}s/${type}s.js`, sectionsJs);
}

//generate styles for VvvebJs
function styles(dirs = []) {
	let stylesDir = path.resolve(`./css/styles`);
	let previewDir = path.resolve(`./styles`);
	let styleCss = path.resolve("./css/style.bundle.css");
	let htmlPreview = path.resolve("./src/style-preview.html");
	let baseDir = path.resolve(".");
	let dir = [];
	let stylesJs = '';

	if (!dirs.length) {
		dirs = fs.readdirSync(stylesDir).map(fileName => {
			let stat = fs.statSync(`${stylesDir}/${fileName}`);

			if (stat.isDirectory()) {
				dir.push(fileName);
			}
		});
	}

	for (i in dir) {
		let group =  dir[i];		
		let filePath = `${stylesDir}/${group}/`;
		let name;
		let id;
		let html;
		let stylesHtml = fs.readFileSync(htmlPreview,'utf8');;
		let image = '';
	
		if (!fs.existsSync(previewDir + "/" + group)) {
			fs.mkdirSync(previewDir + "/" + group)
		}		
		
		let styles = [];
		let files = fs.readdirSync(filePath).
		sort((a, b) => parseInt(a.replace( /^\D+/g, '')) - parseInt(b.replace( /^\D+/g, ''))).
		map(styleFile => {
			
			let name = styleFile.replace(".css","");
			let darkTheme = name.endsWith("-dark");
			let style = `css/styles/${group}/${styleFile}`;
			let id = `${group}/${name}`;
			let image = `screenshots/styles/${group}/` + styleFile.replace(".css", "-thumb.webp");
			let html = fs.readFileSync(`${filePath}/${styleFile}`,'utf8');
			let previewHtml = stylesHtml.replace('id="style-css" href=""', `id="style-css" href="../../${style}"`);
			if (darkTheme) {
				previewHtml = previewHtml.replace('<html lang="en">', '<html lang="en" data-bs-theme="dark">');
			}
			
			styles.push(id);		
			
			stylesJs += template(templates['style']['style'], {id, name:prettify(name), image, style});
			fs.writeFileSync(previewDir + "/" +  group + "/" + styleFile.replace(".css", ".html"), previewHtml);
		});
		
		
		let groupList = '"' + styles.join('","') + '"';
		group = prettify(group);
		stylesJs += template(templates['style']['group'], {group, groupList});
	}
	
	return fs.writeFileSync(/*path.resolve(".") + *//*`${stylesDir}/${type}s.js`*/path.resolve(".") + `/styles/styles.js`, stylesJs);
}


module.exports = { screenshots, sections, styles, connect, disconnect };
