import TeamComplianceSettingService from "./TeamComplianceSettingService";
import TeamMemberService from "./TeamMemberService";
import UserEmailService from "./UserEmailService";
import UserSmsService from "./UserSmsService";
import UserCallService from "./UserCallService";
import UserPushService from "./UserPushService";
import IncidentSeverityService from "./IncidentSeverityService";
import AlertSeverityService from "./AlertSeverityService";
import UserNotificationRuleService from "./UserNotificationRuleService";
import UserService from "./UserService";
import TeamService from "./TeamService";
import ComplianceRuleType from "../../Types/Team/ComplianceRuleType";
import BadDataException from "../../Types/Exception/BadDataException";
import Includes from "../../Types/BaseDatabase/Includes";
import { LIMIT_PER_PROJECT } from "../../Types/Database/LimitMax";
export default class TeamComplianceService {
    static async getTeamComplianceStatus(teamId, projectId) {
        var _a, _b, _c;
        // Get team details
        const team = await TeamService.findOneById({
            id: teamId,
            select: {
                name: true,
                _id: true,
            },
            props: {
                isRoot: true,
            },
        });
        if (!team) {
            throw new BadDataException("Team not found");
        }
        // Get compliance settings for this team
        const complianceSettings = await TeamComplianceSettingService.findBy({
            query: {
                teamId: teamId,
                projectId: projectId,
            },
            select: {
                ruleType: true,
                enabled: true,
            },
            limit: 100,
            skip: 0,
            props: {
                isRoot: true,
            },
        });
        // Get team members
        const teamMembers = await TeamMemberService.findBy({
            query: {
                teamId: teamId,
                projectId: projectId,
            },
            select: {
                userId: true,
                _id: true,
            },
            limit: 100,
            skip: 0,
            props: {
                isRoot: true,
            },
        });
        const userIds = teamMembers
            .map((member) => {
            return member.userId;
        })
            .filter(Boolean);
        // Get user details
        const users = await UserService.findBy({
            query: {
                _id: new Includes(userIds),
            },
            select: {
                name: true,
                email: true,
                _id: true,
                profilePictureId: true,
            },
            limit: 100,
            skip: 0,
            props: {
                isRoot: true,
            },
        });
        // Check compliance for each user
        const userComplianceStatuses = [];
        for (const user of users) {
            const complianceStatus = await this.checkUserCompliance(user.id, projectId, complianceSettings.map((setting) => {
                return {
                    ruleType: setting.ruleType,
                    enabled: setting.enabled || false,
                };
            }));
            userComplianceStatuses.push(Object.assign({ userId: user.id, userName: ((_a = user.name) === null || _a === void 0 ? void 0 : _a.toString()) || ((_b = user.email) === null || _b === void 0 ? void 0 : _b.toString()) || "Unknown User", userEmail: ((_c = user.email) === null || _c === void 0 ? void 0 : _c.toString()) || "", userProfilePictureId: user.profilePictureId }, complianceStatus));
        }
        return {
            teamId: teamId,
            teamName: team.name || "Unknown Team",
            complianceSettings: complianceSettings.map((setting) => {
                return {
                    ruleType: setting.ruleType,
                    enabled: setting.enabled || false,
                };
            }),
            userComplianceStatuses,
        };
    }
    static async checkUserCompliance(userId, projectId, complianceSettings) {
        const nonCompliantRules = [];
        // Check each enabled compliance rule
        for (const setting of complianceSettings) {
            if (!setting.enabled) {
                continue;
            }
            const isCompliant = await this.checkRuleCompliance(userId, projectId, setting.ruleType);
            if (!isCompliant.compliant) {
                nonCompliantRules.push({
                    ruleType: setting.ruleType,
                    reason: isCompliant.reason,
                });
            }
        }
        return {
            isCompliant: nonCompliantRules.length === 0,
            nonCompliantRules,
        };
    }
    static async checkRuleCompliance(userId, projectId, ruleType) {
        switch (ruleType) {
            case ComplianceRuleType.HasNotificationEmailMethod:
                return await this.checkHasNotificationEmail(userId, projectId);
            case ComplianceRuleType.HasNotificationSMSMethod:
                return await this.checkHasNotificationSMS(userId, projectId);
            case ComplianceRuleType.HasNotificationCallMethod:
                return await this.checkHasNotificationCall(userId, projectId);
            case ComplianceRuleType.HasNotificationPushMethod:
                return await this.checkHasNotificationPush(userId, projectId);
            case ComplianceRuleType.HasIncidentOnCallRules:
                return await this.checkHasIncidentOnCallRules(userId, projectId);
            case ComplianceRuleType.HasAlertOnCallRules:
                return await this.checkHasAlertOnCallRules(userId, projectId);
            default:
                return { compliant: true, reason: "" };
        }
    }
    static async checkHasNotificationEmail(userId, projectId) {
        const userEmails = await UserEmailService.findBy({
            query: {
                userId: userId,
                projectId: projectId,
                isVerified: true,
            },
            select: {
                _id: true,
            },
            props: {
                isRoot: true,
            },
            limit: 1,
            skip: 0,
        });
        const hasEmail = userEmails.length > 0;
        return {
            compliant: hasEmail,
            reason: hasEmail
                ? ""
                : "No verified email address configured for notifications",
        };
    }
    static async checkHasNotificationSMS(userId, projectId) {
        const userSMS = await UserSmsService.findBy({
            query: {
                userId: userId,
                projectId: projectId,
                isVerified: true,
            },
            select: {
                _id: true,
            },
            props: {
                isRoot: true,
            },
            limit: 1,
            skip: 0,
        });
        const hasSMS = userSMS.length > 0;
        return {
            compliant: hasSMS,
            reason: hasSMS
                ? ""
                : "No verified phone number configured for SMS notifications",
        };
    }
    static async checkHasNotificationCall(userId, projectId) {
        const userCalls = await UserCallService.findBy({
            query: {
                userId: userId,
                projectId: projectId,
                isVerified: true,
            },
            select: {
                _id: true,
            },
            props: {
                isRoot: true,
            },
            limit: 1,
            skip: 0,
        });
        const hasCall = userCalls.length > 0;
        return {
            compliant: hasCall,
            reason: hasCall
                ? ""
                : "No verified phone number configured for call notifications",
        };
    }
    static async checkHasNotificationPush(userId, projectId) {
        const userPush = await UserPushService.findBy({
            query: {
                userId: userId,
                projectId: projectId,
                isVerified: true,
            },
            select: {
                _id: true,
            },
            props: {
                isRoot: true,
            },
            limit: 1,
            skip: 0,
        });
        const hasPush = userPush.length > 0;
        return {
            compliant: hasPush,
            reason: hasPush ? "" : "No verified push notification device configured",
        };
    }
    static async checkHasIncidentOnCallRules(userId, projectId) {
        // Get all incident severities for the project
        const incidentSeverities = await IncidentSeverityService.findBy({
            query: {
                projectId: projectId,
            },
            select: {
                _id: true,
                name: true,
            },
            props: {
                isRoot: true,
            },
            limit: LIMIT_PER_PROJECT,
            skip: 0,
        });
        if (incidentSeverities.length === 0) {
            return { compliant: true, reason: "" }; // No incident severities configured
        }
        // Check if user has notification rules for all incident severities
        const severityIds = incidentSeverities.map((severity) => {
            return severity._id;
        });
        const missingSeverities = [];
        for (const severityId of severityIds) {
            const notificationRules = await UserNotificationRuleService.findBy({
                query: {
                    userId: userId,
                    projectId: projectId,
                    incidentSeverityId: severityId,
                },
                select: {
                    _id: true,
                    userCallId: true,
                    userSmsId: true,
                    userEmailId: true,
                    userPushId: true,
                },
                props: {
                    isRoot: true,
                },
                limit: 1,
                skip: 0,
            });
            // Check if user has at least one notification method configured for this severity
            const hasNotificationMethod = notificationRules.some((rule) => {
                return (rule.userCallId ||
                    rule.userSmsId ||
                    rule.userEmailId ||
                    rule.userPushId);
            });
            if (!hasNotificationMethod) {
                const severity = incidentSeverities.find((s) => {
                    var _a;
                    return ((_a = s._id) === null || _a === void 0 ? void 0 : _a.toString()) === severityId.toString();
                });
                const severityName = (severity === null || severity === void 0 ? void 0 : severity.name) || severityId.toString();
                missingSeverities.push(severityName);
            }
        }
        if (missingSeverities.length > 0) {
            return {
                compliant: false,
                reason: `Missing notification rules for incident severities: ${missingSeverities.join(", ")}`,
            };
        }
        return {
            compliant: true,
            reason: "",
        };
    }
    static async checkHasAlertOnCallRules(userId, projectId) {
        // Get all alert severities for the project
        const alertSeverities = await AlertSeverityService.findBy({
            query: {
                projectId: projectId,
            },
            select: {
                _id: true,
                name: true,
            },
            props: {
                isRoot: true,
            },
            limit: 100, // Assuming reasonable limit for severities
            skip: 0,
        });
        if (alertSeverities.length === 0) {
            return { compliant: true, reason: "" }; // No alert severities configured
        }
        // Check if user has notification rules for all alert severities
        const severityIds = alertSeverities.map((severity) => {
            return severity._id;
        });
        const missingSeverities = [];
        for (const severityId of severityIds) {
            const notificationRules = await UserNotificationRuleService.findBy({
                query: {
                    userId: userId,
                    projectId: projectId,
                    alertSeverityId: severityId,
                },
                select: {
                    _id: true,
                    userCallId: true,
                    userSmsId: true,
                    userEmailId: true,
                    userPushId: true,
                },
                props: {
                    isRoot: true,
                },
                limit: 1,
                skip: 0,
            });
            // Check if user has at least one notification method configured for this severity
            const hasNotificationMethod = notificationRules.some((rule) => {
                return (rule.userCallId ||
                    rule.userSmsId ||
                    rule.userEmailId ||
                    rule.userPushId);
            });
            if (!hasNotificationMethod) {
                const severity = alertSeverities.find((s) => {
                    var _a;
                    return ((_a = s._id) === null || _a === void 0 ? void 0 : _a.toString()) === severityId.toString();
                });
                const severityName = (severity === null || severity === void 0 ? void 0 : severity.name) || severityId.toString();
                missingSeverities.push(severityName);
            }
        }
        if (missingSeverities.length > 0) {
            return {
                compliant: false,
                reason: `Missing notification rules for alert severities: ${missingSeverities.join(", ")}`,
            };
        }
        return {
            compliant: true,
            reason: "",
        };
    }
}
//# sourceMappingURL=TeamComplianceService.js.map