/**
 * @preserve
 * @author    ThemePunch <info@themepunch.com>
 * @link      http://www.themepunch.com/
 * @copyright 2018 ThemePunch
 * @version 6.7.0
 */
/*
╔══════════════════════════════════════════════════════════════════════════════╗
║                                                                              ║
║  PLUGIN:      SLIDER REVOLUTION 7.0                                          ║
║  MODULE:      WEATHER ADDON                                                  ║
║  VERSION:     1.0.0                                                          ║
║  DATE:        2023-03-10                                                     ║
║  AUTHOR:      Krisztian H.                                                   ║
║  COMPANY:     ThemePunch OHG.                                                ║
║                                                                              ║
╠══════════════════════════════════════════════════════════════════════════════╣
║                                                                              ║
║  UPDATES & DOCS:  https://www.themepunch.com/support-center                  ║
║  GET LICENSE:    https://www.themepunch.com/links/slider_revolution_wordpre  ║
║                               ss_regular_license                             ║
║                                                                              ║
╠══════════════════════════════════════════════════════════════════════════════╣
║                                                                              ║
║  LICENSE:                                                                    ║
║  Copyright (c) 2023, ThemePunch. All rights reserved.                        ║
║  This work is subject to the terms at:                                       ║
║  https://www.themepunch.com/links/slider_revolution_wordpress_regular_licen  ║
║                               se (Regular / Extended)                        ║
║                                                                              ║
╚══════════════════════════════════════════════════════════════════════════════╝
*/
(function() {
	"use strict";

	window.SR7 ??=  {};
	window._tpt ??= {};
	SR7.A ??= {};
	SR7.F ??= {};
	SR7.D ??= {};

	//Check if File already has been loaded, and if so, quit...
	if (SR7.A.weather !== undefined) return;

	// Update Required Setings
	let get = {
		pI : (v) => parseInt(v),
		pF : (v) => parseFloat(v),
		s : (v) => String(v),
		b : (v) => v === 'on' || v === true || v===1? true : v === 'off' || v === false || v===0 ? false : v,
		k : (v) => v,
	}

	let dO = {"timeZone": "UTC", "year": "numeric", "month": "long", "day": "numeric"};
	let wO = {"timeZone": "UTC", "weekday": "short"};

	const unit_pressure = 'hPa';
	const unit_humidity = '%';

	SR7.A.weather = {
		cache: {},
		promises: {},
		layers: {},
		style: 'span.revslider-weather-data {transition: inherit!important; text-align: inherit!important; line-height: inherit!important; border-width: inherit!important; margin: inherit!important; padding: inherit!important; letter-spacing: inherit!important; font-weight: inherit!important; font-size: inherit!important; font-style: inherit;}' ,

		/**
		 * @param {object} o - addon options on module level
		 * @returns {object} options in SR7 format
		 */
		getModuleBasics: (o = {},type) => {
			let r = {
				u: type=="compare" ? undefined : (o.u ?? o.enable ?? true),
				l: o.l ?? o.location ?? 'Cologne',
				unit: o.unit ?? 'c',
				r: o.r ?? o.refresh ?? '0',
			};

			if (type === 'normalize') {
				r.r = Math.max(0, Math.min(500, get.pI(r.r))) * 60000 || 0;
			}

			return r;
		},

		/**
		 * @param {object} o - addon options on module level
		 * @returns {object} options in SR7 format
		 */
		getLayerBasics: (o = {},type) => ({
			l: o.l ?? o.location ?? 'Cologne',
			unit: o.unit ?? 'c',
		}),

		/**
		 * @param {string} id - module ID
		 */
		init : (id) => {
			let M = SR7.M[id],
				W = M.settings.addOns.weather;

			if (""+(W.u??false)==="false") return;

			if (SR7.A.weather.css===undefined) {
				_tpt.injectCssJs(SR7.A.weather.style,undefined,undefined,"weather_global_styles");
				SR7.A.weather.css = true;
			}

			M.c.addOns??={};
			M.c.addOns.weather = SR7.A.weather.getModuleBasics(W, 'normalize');

			// add refresh
			if (M.c.addOns.weather.r) {
				M.c.addOns.weather.timer = setInterval(() => {
					let promises = [];
					for (let layerid in SR7.A.weather.layers[id]) {
						if (!_tpt.hop(SR7.A.weather.layers[id],layerid) || !SR7.A.weather.layers[id][layerid]) continue;
						promises.push(SR7.A.weather.prepareLayer(id, SR7.A.weather.layers[id][layerid], layerid,true));
					}
					Promise.all(promises).then(() => {SR7.F.drawRawLayers(id, M.current.id,"update");});
				}, M.c.addOns.weather.r);
			}
		},

		/**
		 * @param {string} id - module ID
		 * @param {object} layer - layer object
		 * @param {string} lid - layer id
		 * @return {Promise}
		 */
		prepareLayer: (id,layer,lid,reset) => {
			let M = SR7.M[id],
				W = M.c?.addOns?.weather;
			if (""+(W?.u??false)==="false") return;

			const o = layer?.addOns?.weather;
			if (!o || !o.l || !o.unit || layer.type!=="text" || !(layer.content?.text??"").includes('{{weather_')) return;
			SR7.A.weather.layers[id] ??= {};
			SR7.A.weather.layers[id][lid] = layer;
			return SR7.A.weather.getWeather(id, o, lid,reset);
		},

		updateMeta: (lid) => {
			let {layer, c,el} = SR7.F.getLayer(lid);
			const o = layer?.addOns?.weather;
			if (layer.type!='text' || !o || !o.l || !o.unit) return;
			const data = SR7.A.weather.cache?.[o.l]?.[o.unit];
			if (!data) return;
			c.elIHCache ??= el.innerHTML;
			let content = c.elIHCache;
			const regex = /{{weather_([a-z_]+?)(?:_forecast:(\d+))?}}/gi;
			const statics = ['date', 'day', 'city', 'country', 'region', 'units_temp', 'units_pressure', 'units_speed', 'alt_unit'];
			content = content.replace(regex, (_, key, forecast) => {
				forecast = forecast || 0;
				const conversionFunc = convert[`weather_${key}`];
				if (conversionFunc)	{
					return '<span data-day="' + (forecast) + '" class="revslider-weather-data revslider_data_weather' +
						'_' + key + (statics.indexOf[key]>=0 ? ' revslider-weather-static' : '')+ '">' +
						(key=="icon" ? '<i class="wi wi-owm-'+conversionFunc(data, forecast, o.unit)+'"></i>' : conversionFunc(data, forecast, o.unit))
						+ '</span>';
				}
				return '';
			});
			el.innerHTML = content;
			return;
		},

		getWeather: (id, o, lid,reset) => {
			return new Promise((resolve,reject) => {
				if (SR7.A.weather.cache?.[o.l]?.[o.unit]) {
					if (reset) {
						delete SR7.A.weather.cache[o.l][o.unit];
					} else {
						SR7.A.weather.updateMeta(lid);
						resolve();
						return;
					}
				}
				const url =  _tpt.urlProtocol(window.SR7.E.resturl) + 'sliderrevolution/weather/'+'l/'+(o.l)+'/unit/'+(o.unit)+'/id/';
				if (SR7.A.weather.pendingPromises?.[o.l]?.[o.unit]) {
					SR7.A.weather.pendingPromises[o.l][o.unit].then(() => {
						SR7.A.weather.updateMeta(lid);
						resolve();
					}).catch((error) => {
						console.log('weather restAPI error', error);
						reject(error);
					});
					return;
				}
				SR7.A.weather.pendingPromises ??= {};
				SR7.A.weather.pendingPromises[o.l] ??= {};
				SR7.A.weather.pendingPromises[o.l][o.unit] = _tpt.restAPILoad({url, id}).then((response) => {
					if (typeof response!=="object") response = JSON.parse(response);
					if (response.success==false) {
						console.log(id + " module weather could not be Loaded from DB");
						reject();
						return;
					}
					SR7.A.weather.cache[o.l]??={};
					SR7.A.weather.cache[o.l][o.unit] = JSON.parse(response.message);
					SR7.A.weather.updateMeta(lid);
					resolve();
				}).catch((error) => {
					console.log('weather restAPI error', error);
					reject(error);
				})
				SR7.A.weather.pendingPromises[o.l][o.unit].finally(() => {
					delete SR7.A.weather.pendingPromises[o.l][o.unit];
				});
			});
		},




		getAltTemp: (unit, temp) => {
			if (unit === 'F') {
				return SR7.A.weather.fahrenheitToCelsius(temp);
			} else {
				return SR7.A.weather.celsiusToFahrenheit(temp);
			}
		},
		fahrenheitToCelsius: (givenValue) => {
			const celsius = (5 / 9) * (givenValue - 32);
			return celsius;
		},
		celsiusToFahrenheit: (givenValue) => {
			const fahrenheit = givenValue * (9 / 5) + 32;
			return fahrenheit;
		}
	}

	let formatDate = (timestamp, options) => new Date(timestamp * 1000).toLocaleDateString("en-US", options);

	let convert = {
		weather_title : (data,f) => data.data[f].weather.description,
		weather_temp : (data,f) => get.pI(data.data[f].temp),
		weather_code : (data,f) => data.data[f].weather.code,
		weather_todayCode : (data,f) => data.data[f].weather.code,
		weather_date : (data,f) => formatDate(data.data[f].ts, dO),
		weather_day : (data,f) => formatDate(data.data[f].ts,wO),
		weather_currently : (data,f) => data.data[f].weather.description,
		weather_high : (data,f) => get.pI(data.data[f].max_temp),
		weather_low : (data,f) => get.pI(data.data[f].min_temp),
		weather_text : (data,f) => data.data[f].weather.description,
		weather_humidity : (data,f) => data.data[f].rh + unit_humidity,
		weather_pressure : (data,f) => data.data[f].pres + unit_pressure,
		weather_rising : (data,f) => formatDate(data.data[f].sunrise_ts,wO),
		weather_visbility : (data,f) => data.data[f].vis,
		weather_sunrise : (data,f) => formatDate(data.data[f].sunrise_ts,wO),
		weather_sunset : (data,f) => formatDate(data.data[f].sunset_ts,wO),
		weather_city : (data) => data.city_name,
		weather_country : (data) => data.country_code,
		weather_region : (data) => data.state_code,
		weather_thumbnail : (data,f) => 'https://www.weatherbit.io/static/img/icons/' + data.data[f].weather.icon + '.png',
		weather_image : (data,f) => 'https://www.weatherbit.io/static/img/icons/' + data.data[f].weather.icon + '.png',
		weather_units_temp : (data,f,unit) => unit=='c' ? 'C' : 'F',
		weather_units_pressure : (data,f) => data.data[f].unit_pressure,
		weather_units_speed : (data,f,unit) => unit=='c' ? 'm/s' : 'mph',
		weather_wind_direction : (data,f) => data.data[f].wind_cdir,
		weather_wind_speed : (data,f) => data.data[f].wind_spd,
		weather_alt_temp : (data,f,unit) => SR7.A.weather.getAltTemp(unit, data.data[f].temp),
		weather_alt_high : (data,f) => SR7.A.weather.getAltTemp(unit, data.data[f].max_temp),
		weather_alt_low : (data,f) => SR7.A.weather.getAltTemp(unit, data.data[f].min_temp),
		weather_alt_unit : (data,f,unit) => unit == "f" ? "C" : "F",
		weather_description : (data,f) => data.data[f].weather.description,
		weather_icon : (data,f) => data.data[f].weather.code
	}

	// Update Required Settings
	_tpt.R ??= {};
	_tpt.R.weather =  _tpt.extend ?  _tpt.extend(_tpt.R.weather, { status: 2, version: '1.0'}) : { status: 2, version: '1.0'};
	window.dispatchEvent(new CustomEvent('SR7WeatherReady'));
})();