/**
 * Birthday Notification Scheduler
 *
 * Automated scheduler untuk generate notifikasi ulang tahun karyawan.
 * Default behavior: hanya berjalan untuk company yang mengaktifkan setting
 * `birthday_notification_enabled=true` (default: disabled untuk safety).
 *
 * Configuration via CompanySetting (per company):
 * - birthday_notification_enabled: boolean (default: false)
 * - birthday_notification_send_email: boolean (default: true)
 * - birthday_notification_send_system: boolean (default: true)
 * - birthday_notification_email_group_ids: JSON array (optional)
 * - birthday_notification_additional_recipients: JSON array (optional)
 * - birthday_notification_template_id: string (classic|confetti|spotlight)
 */

const notificationService = require("./notification.service");
const dbSAPPS = require("../../helpers/db");

let schedulerInterval = null;
let isRunning = false;

function parseBool(val, defaultValue) {
	if (val == null) return defaultValue;
	if (typeof val === "boolean") return val;
	if (typeof val === "number") return val === 1;
	if (typeof val === "string") {
		const s = val.trim().toLowerCase();
		return s === "true" || s === "1" || s === "yes";
	}
	return defaultValue;
}

async function getEnabledCompanies() {
	try {
		const enabledSettings = await dbSAPPS.CompanySetting.findAll({
			where: { key: "birthday_notification_enabled" },
			attributes: ["company_id", "value"],
		});

		const enabledCompanyIds = new Set();
		(enabledSettings || []).forEach((setting) => {
			const isEnabled = parseBool(setting.value, false);
			if (isEnabled) enabledCompanyIds.add(setting.company_id);
		});

		// Safety-first: if no explicit enabled setting, return []
		return Array.from(enabledCompanyIds);
	} catch (error) {
		console.error("[Birthday Scheduler] Error getting enabled companies:", error);
		return [];
	}
}

async function runBirthdayNotificationCheck(options = {}) {
	try {
		console.log(`[Birthday Scheduler] Running check at ${new Date().toISOString()}`);

		let companiesId = options.companiesId || null;
		if (!companiesId) {
			companiesId = await getEnabledCompanies();
			if (!companiesId || companiesId.length === 0) {
				console.log("[Birthday Scheduler] No enabled companies, skipping");
				return {
					success: true,
					message: "No enabled companies",
					birthdays: 0,
					notificationsCreated: 0,
					emailsSent: 0,
				};
			}
			console.log(`[Birthday Scheduler] Enabled companies: ${companiesId.length}`);
		}

		const params = {
			companiesId,
			modified_by: options.modified_by || 1,
			owner: options.owner || 1,
			// Use company settings by default; you can override via options if needed
		};

		const result = await notificationService.generateBirthdayNotifications(params);

		if (result.success) {
			console.log(
				`[Birthday Scheduler] Success: birthdays=${result.birthdays}, notificationsCreated=${result.notificationsCreated}, emailsSent=${result.emailsSent}`,
			);
			if (result.errors && result.errors.length > 0) {
				console.warn(`[Birthday Scheduler] Warnings: ${result.errors.length} errors occurred`);
			}
		} else {
			console.error(`[Birthday Scheduler] Error: ${result.message}`);
		}

		return result;
	} catch (error) {
		console.error("[Birthday Scheduler] Fatal error:", error);
		return {
			success: false,
			message: error.message || "Failed to run birthday notification check",
		};
	}
}

function startScheduler(options = {}) {
	if (schedulerInterval) {
		console.log("[Birthday Scheduler] Scheduler already running");
		return;
	}

	const intervalHours = Number(options.intervalHours || 24);
	const intervalMs = Math.max(1, intervalHours) * 60 * 60 * 1000;

	console.log(`[Birthday Scheduler] Starting scheduler, interval=${intervalHours}h`);

	if (options.runImmediately !== false) {
		runBirthdayNotificationCheck(options).catch((e) => console.error("[Birthday Scheduler] Immediate run failed:", e));
	}

	schedulerInterval = setInterval(async () => {
		if (isRunning) {
			console.log("[Birthday Scheduler] Previous run still in progress, skipping");
			return;
		}
		isRunning = true;
		try {
			await runBirthdayNotificationCheck(options);
		} finally {
			isRunning = false;
		}
	}, intervalMs);

	if (schedulerInterval && schedulerInterval.unref) {
		schedulerInterval.unref();
	}
}

function stopScheduler() {
	if (schedulerInterval) {
		clearInterval(schedulerInterval);
		schedulerInterval = null;
		console.log("[Birthday Scheduler] Stopped");
	}
}

module.exports = {
	startScheduler,
	stopScheduler,
	runBirthdayNotificationCheck,
};
