const express = require("express");
const router = express.Router();
const authorize = require("../../../../middlewares/authorize-sapps");
const dbSAPPS = require("../../helpers/db");
const notificationService = require("./notification.service");

function isTruthyRoleFlag(val) {
	return val === true || val === "true" || val === 1 || val === "1";
}

async function resolveUserRole(req) {
	const user = req.user || {};
	const roleObj = user.role && typeof user.role === "object" ? user.role : null;
	if (roleObj) return roleObj;

	const roleId = user.role_id || user.roleId || user.role?.id;
	if (!roleId) return {};

	try {
		const roleRow = await dbSAPPS.Role.findByPk(roleId, {
			attributes: ["id", "access_read_all_data", "administrator_of_hr"],
		});
		const role = roleRow ? roleRow.get() : {};
		// Attach for downstream usage in this request
		req.user = user;
		req.user.role = role;
		return role;
	} catch {
		return {};
	}
}

async function canManageBirthdayNotifications(req) {
	const user = req.user || {};
	const role = (await resolveUserRole(req)) || user.role || {};
	const readAll = isTruthyRoleFlag(role.access_read_all_data) || isTruthyRoleFlag(user.access_read_all_data);
	const adminHr = isTruthyRoleFlag(role.administrator_of_hr) || isTruthyRoleFlag(user.administrator_of_hr);
	return readAll || adminHr;
}

/**
 * Get all notifications with permission-based filtering
 * @route GET /sapps/notifications
 */
router.get("/", authorize(), async (req, res, next) => {
	try {
		// Extract user info from request (set by authorize middleware)
		const user = req.user || {};
		const userRole = user.role || {};
		const userEmployee = user.employee || {};

		const params = {
			...req.query,
			user_employee_id: userEmployee.id || null,
			access_read_all_data: userRole.access_read_all_data || false,
			administrator_of_hr: userRole.administrator_of_hr || false,
		};

		const result = await notificationService.getAll(params);
		return res.status(result.success ? 200 : 400).json(result);
	} catch (error) {
		next(error);
	}
});

/**
 * Get notifications by employee
 * @route GET /sapps/notifications/employee/:employee_id
 */
router.get("/employee/:employee_id", authorize(), async (req, res, next) => {
	try {
		const user = req.user || {};
		const userRole = user.role || {};
		const userEmployee = user.employee || {};

		const params = {
			...req.query,
			employee_id: req.params.employee_id,
			user_employee_id: userEmployee.id || null,
			access_read_all_data: userRole.access_read_all_data || false,
			administrator_of_hr: userRole.administrator_of_hr || false,
		};

		const result = await notificationService.getByEmployee(params);
		return res.status(result.success ? 200 : 400).json(result);
	} catch (error) {
		next(error);
	}
});

/**
 * Create a notification
 * @route POST /sapps/notifications
 */
router.post("/", authorize(), async (req, res, next) => {
	try {
		const params = {
			...req.body,
			modified_by: req.user?.id || req.body.modified_by || 1,
			owner: req.user?.id || req.body.owner || 1,
		};
		const result = await notificationService.create(params);
		return res.status(result.success ? 201 : 400).json(result);
	} catch (error) {
		next(error);
	}
});

/**
 * Mark notification as read
 * @route PATCH /sapps/notifications/:id/read
 */
router.patch("/:id/read", authorize(), async (req, res, next) => {
	try {
		const params = {
			modified_by: req.user?.id || req.body.modified_by || 1,
		};
		const result = await notificationService.markAsRead(req.params.id, params);
		return res.status(result.success ? 200 : 400).json(result);
	} catch (error) {
		next(error);
	}
});

/**
 * Mark notification as sent
 * @route PATCH /sapps/notifications/:id/sent
 */
router.patch("/:id/sent", authorize(), async (req, res, next) => {
	try {
		const params = {
			modified_by: req.user?.id || req.body.modified_by || 1,
		};
		const result = await notificationService.markAsSent(req.params.id, params);
		return res.status(result.success ? 200 : 400).json(result);
	} catch (error) {
		next(error);
	}
});

/**
 * Delete notification
 * @route DELETE /sapps/notifications/:id
 */
router.delete("/:id", authorize(), async (req, res, next) => {
	try {
		const result = await notificationService.delete(req.params.id);
		return res.status(result.success ? 200 : 400).json(result);
	} catch (error) {
		next(error);
	}
});

/**
 * Generate PKWT expiration notifications
 * @route POST /sapps/notifications/generate-pkwt
 */
router.post("/generate-pkwt", authorize(), async (req, res, next) => {
	try {
		const params = {
			...req.body,
			modified_by: req.user?.id || req.body.modified_by || 1,
			owner: req.user?.id || req.body.owner || 1,
		};
		const result = await notificationService.generatePKWTNotifications(params);
		return res.status(result.success ? 200 : 400).json(result);
	} catch (error) {
		next(error);
	}
});

/**
 * Get birthday notification settings (per company)
 * @route GET /sapps/notifications/birthday/settings
 */
router.get("/birthday/settings", authorize(), async (req, res, next) => {
	try {
		if (!(await canManageBirthdayNotifications(req))) {
			return res.status(403).json({ success: false, message: "Forbidden" });
		}
		const result = await notificationService.getBirthdayCompanySettings(req.query);
		return res.status(result.success ? 200 : 400).json(result);
	} catch (error) {
		next(error);
	}
});

/**
 * Update birthday notification settings (per company)
 * @route PUT /sapps/notifications/birthday/settings
 */
router.put("/birthday/settings", authorize(), async (req, res, next) => {
	try {
		if (!(await canManageBirthdayNotifications(req))) {
			return res.status(403).json({ success: false, message: "Forbidden" });
		}
		const params = {
			...req.body,
			modified_by: req.user?.id || req.body.modified_by || 1,
			owner: req.user?.id || req.body.owner || 1,
		};
		const result = await notificationService.updateBirthdayCompanySettings(params);
		return res.status(result.success ? 200 : 400).json(result);
	} catch (error) {
		next(error);
	}
});

/**
 * Preview birthdays + recipients + email template
 * @route GET /sapps/notifications/birthday/preview
 */
router.get("/birthday/preview", authorize(), async (req, res, next) => {
	try {
		if (!(await canManageBirthdayNotifications(req))) {
			return res.status(403).json({ success: false, message: "Forbidden" });
		}
		const result = await notificationService.previewBirthdayNotifications(req.query);
		return res.status(result.success ? 200 : 400).json(result);
	} catch (error) {
		next(error);
	}
});

/**
 * Birthday summary (yesterday / today / tomorrow)
 * @route GET /sapps/notifications/birthday/summary
 */
router.get("/birthday/summary", authorize(), async (req, res, next) => {
	try {
		const result = await notificationService.getBirthdaySummary(req.query);
		return res.status(result.success ? 200 : 400).json(result);
	} catch (error) {
		next(error);
	}
});

/**
 * Generate birthday notifications + optionally send email
 * @route POST /sapps/notifications/birthday/generate
 */
router.post("/birthday/generate", authorize(), async (req, res, next) => {
	try {
		if (!(await canManageBirthdayNotifications(req))) {
			return res.status(403).json({ success: false, message: "Forbidden" });
		}
		const params = {
			...req.body,
			modified_by: req.user?.id || req.body.modified_by || 1,
			owner: req.user?.id || req.body.owner || 1,
		};
		const result = await notificationService.generateBirthdayNotifications(params);
		return res.status(result.success ? 200 : 400).json(result);
	} catch (error) {
		next(error);
	}
});

/**
 * Send a birthday test email to a specific address using a given template
 * @route POST /sapps/notifications/birthday/test-email
 */
router.post("/birthday/test-email", authorize(), async (req, res, next) => {
	try {
		if (!(await canManageBirthdayNotifications(req))) {
			return res.status(403).json({ success: false, message: "Forbidden" });
		}
		const params = {
			...req.body,
			modified_by: req.user?.id || req.body.modified_by || 1,
			owner: req.user?.id || req.body.owner || 1,
		};
		const result = await notificationService.sendBirthdayTestEmail(params);
		return res.status(result.success ? 200 : 400).json(result);
	} catch (error) {
		next(error);
	}
});

/**
 * Send email for a specific notification
 * @route POST /sapps/notifications/:id/send-email
 */
router.post("/:id/send-email", authorize(), async (req, res, next) => {
	try {
		const params = {
			modified_by: req.user?.id || req.body.modified_by || 1,
			owner: req.user?.id || req.body.owner || 1,
		};
		const result = await notificationService.sendEmailForNotification(req.params.id, params);
		return res.status(result.success ? 200 : 400).json(result);
	} catch (error) {
		next(error);
	}
});

module.exports = router;
