/*
2.7.5 - Метод отправки документов по Сделке на проверку
POST /lk/document
*/
import fs from 'fs';
import axios from 'axios';
import { Cookies } from 'react-cookie';
import cookie from 'cookie';
import moment from 'moment';
import jwt from 'jsonwebtoken';
import { inspect } from 'util';
import FormData from 'form-data';
import multer from 'multer';
import { eachLimit, eachSeries } from 'async';
import archiver from 'archiver';

import { cors } from '../../../lib/cors';
import RedisClient from '../../../lib/RedisClient';

const uploads = `${ __dirname }/../../../../../uploads/deals/`;

/*
function uploadFiles() 
{
	return new Promise(() => )
}
*/

function createZipFile(zip_filename, files)
{
	return new Promise(async (resolve) => 
	{
		const output = fs.createWriteStream(zip_filename);
		const archive = archiver('zip', {
			zlib: { level: 9 } // Sets the compression level.
		});

		output.on('close', function() 
		{
			console.log('archive on close');
			resolve();
		});

		output.on('end', function() 
		{
			console.log('archive on end');
		});

		archive.on('warning', function(err) 
		{
			if (err.code === 'ENOENT') 
			{
			} else {
				throw err;
			}
		});

		archive.on('error', function(err) 
		{
			throw err;
		});

		archive.pipe(output);

		for(let i in files)
		{
			archive.append(fs.createReadStream(files[i].path), { name: files[i].name });			
		}
		archive.finalize();
	});
}

function uploadFile({ deal_id, local_filename, filename, name, id, crm_jwt }) 
{
	return new Promise((resolve) => 
	{
		if(fs.existsSync(`${ uploads }${ local_filename }`))
		{
			const path = `${ uploads }${ local_filename }`;

			const file_to_send_data = fs.readFileSync(path);
			console.log("uploadFile", { filename, len: file_to_send_data.length, path });

			const data = new FormData();
			data.append("file", file_to_send_data, filename);

			const payload = new URLSearchParams({
				name: deal_id, 
				entity: "opportunity", 
				documentTypeNumber: id, 
				documentName: name, 
			});

			console.log("uploadFile", { payload });

			const payload_string = new URLSearchParams(payload).toString();

			const file_upload_url = `${ process.env.CRM_API_HOST }/lk/document/upload?${ payload_string }`;
			console.log( file_upload_url );

			axios.post(file_upload_url, data, 
			{
				headers: {
					"Content-Type": `multipart/form-data; boundary=${ data._boundary }`, 
					"Authorization": `Bearer ${ crm_jwt }`, 
				}, 
				withCredentials: true, 
			})
			.then(() => 
			{
				console.log("FILE", filename, "SENT");
				resolve();
			})
			.catch((error) => 
			{
				console.error("FILE", filename, "ERROR");
				console.error(error);

				resolve();
			});
		}
		else
		{
			resolve();
		}
	});
}

export default async function handler(req, res) 
{
	console.log("\n\n", "API", "DEALS", "upload");

	await cors(req, res);

//	const { number, entity, id, filename } = req.query;
	const { deal_id } = req.body;

	return new Promise(async (resolve) => 
	{
		if(req.headers.cookie !== undefined)
		{
			const cookies = cookie.parse(req.headers?.cookie ? req.headers?.cookie : "");

			if(cookies.jwt !== undefined && cookies.jwt !== null)
			{
				var client_jwt_decoded = jwt.verify(cookies.jwt, process.env.JWT_SECRET_CLIENT);
				var crm_jwt = jwt.sign({ acc_number: client_jwt_decoded.acc_number }, process.env.JWT_SECRET_CRM, { noTimestamp: true });

				const key = `deals_${ client_jwt_decoded.acc_number }`;
				var deals = await RedisClient.get(key);

				var files = [];
				if(deals !== null)
				{
					deals = JSON.parse(deals);

					if(deals[ deal_id ] !== undefined)
					{
						//for(let i in deals[ deal_id ].uploaded.files)
						//{
						//	files.push(deals[ deal_id ].uploaded.files[i]);
						//}

						eachSeries(Object.keys(deals[ deal_id ].uploaded), (group, callback) => 
						{
							const document = deals[ deal_id ].uploaded[ group ];
							console.log({ group, document, });

							if(document.files.length === 1)
							{
								const file = document.files[0];

								uploadFile({ deal_id, local_filename: file.filename, filename: file.name, name: document.name, id: document.id, crm_jwt })
								.then(() => 
								{
									callback();
								});
							}
							else
							{
								let files_to_zip = [];
								for(let f in document.files)
								{
									const file = document.files[f];
									const ext_regex = new RegExp("\.([0-9a-z]+)$", "i");
									const ext = file.name.match(ext_regex);

									files_to_zip.push({
										name: `${ file.name }`, 
										path: `${ uploads }${ file.filename }`, 
									});
								}

								const zip_filename = `${ client_jwt_decoded.acc_number }_${ deal_id }_${ group }.zip`;

								console.log({ files_to_zip });

								createZipFile(`${ uploads }${ zip_filename }`, files_to_zip)
								.then(() => 
								{
									uploadFile({ deal_id, local_filename: zip_filename, filename: zip_filename, name: document.name, id: document.id, crm_jwt })
									.then(() => 
									{
										callback();
									});	
								})
							}
						}, async () => 
						{
							console.log("ALL FILES SENT");
							delete deals[ deal_id ];
							await RedisClient.set(key, JSON.stringify(deals));

							res.status(200).json({});

							axios.post(`${ process.env.CRM_API_HOST }/lk/ConsiderationOpportunity/documentdone?opp_number=${ deal_id }`, {}, {
								headers: {
									"Authorization": `Bearer ${ crm_jwt }`, 
								}, 
								withCredentials: true, }
							)
							.then(() => {})
							.catch((error) => 
							{
								console.error(error);
							});

							resolve();
						});
					}
					else
					{
						res.status(403).json({});
						resolve();
					}
				}
				else
				{
					res.status(403).json({});
					resolve();
				}
			}
			else
			{
				res.status(403).json({});
				resolve();
			}
		}
		else
		{
			res.status(403).send();
			resolve();
		}
	});
}