use std::{collections::HashMap, sync::LazyLock};

use common_enums::{EntityType, MerchantProductType, PermissionGroup, RoleScope};

use super::RoleInfo;
use crate::consts;

pub static PREDEFINED_ROLES: LazyLock<HashMap<&'static str, RoleInfo>> = LazyLock::new(|| {
    let mut roles = HashMap::new();

    // Internal Roles
    roles.insert(
        common_utils::consts::ROLE_ID_INTERNAL_ADMIN,
        RoleInfo {
            groups: vec![
                PermissionGroup::OperationsView,
                PermissionGroup::OperationsManage,
                PermissionGroup::ConnectorsView,
                PermissionGroup::ConnectorsManage,
                PermissionGroup::WorkflowsView,
                PermissionGroup::WorkflowsManage,
                PermissionGroup::AnalyticsView,
                PermissionGroup::UsersView,
                PermissionGroup::UsersManage,
                PermissionGroup::AccountView,
                PermissionGroup::AccountManage,
                PermissionGroup::ReconSourcesView,
                PermissionGroup::ReconSourcesManage,
                PermissionGroup::ReconExceptionsView,
                PermissionGroup::ReconExceptionsManage,
                PermissionGroup::ReconTransactionsView,
                PermissionGroup::ReconTransactionsManage,
                PermissionGroup::ReconRulesView,
                PermissionGroup::ReconRulesManage,
            ],
            role_id: common_utils::consts::ROLE_ID_INTERNAL_ADMIN.to_string(),
            role_name: "internal_admin".to_string(),
            scope: RoleScope::Organization,
            entity_type: EntityType::Merchant,
            is_invitable: false,
            is_deletable: false,
            is_updatable: false,
            is_internal: true,
            product_type_filter: None,
        },
    );
    roles.insert(
        common_utils::consts::ROLE_ID_INTERNAL_VIEW_ONLY_USER,
        RoleInfo {
            groups: vec![
                PermissionGroup::OperationsView,
                PermissionGroup::ConnectorsView,
                PermissionGroup::WorkflowsView,
                PermissionGroup::AnalyticsView,
                PermissionGroup::UsersView,
                PermissionGroup::AccountView,
                PermissionGroup::ReconSourcesView,
                PermissionGroup::ReconExceptionsView,
                PermissionGroup::ReconTransactionsView,
                PermissionGroup::ReconRulesView,
            ],
            role_id: common_utils::consts::ROLE_ID_INTERNAL_VIEW_ONLY_USER.to_string(),
            role_name: "internal_view_only".to_string(),
            scope: RoleScope::Organization,
            entity_type: EntityType::Merchant,
            is_invitable: false,
            is_deletable: false,
            is_updatable: false,
            is_internal: true,
            product_type_filter: None,
        },
    );
    // Tenant Roles
    roles.insert(
        common_utils::consts::ROLE_ID_TENANT_ADMIN,
        RoleInfo {
            groups: vec![
                PermissionGroup::OperationsView,
                PermissionGroup::OperationsManage,
                PermissionGroup::ConnectorsView,
                PermissionGroup::ConnectorsManage,
                PermissionGroup::WorkflowsView,
                PermissionGroup::WorkflowsManage,
                PermissionGroup::AnalyticsView,
                PermissionGroup::UsersView,
                PermissionGroup::UsersManage,
                PermissionGroup::AccountView,
                PermissionGroup::AccountManage,
                PermissionGroup::ReconSourcesView,
                PermissionGroup::ReconSourcesManage,
                PermissionGroup::ReconExceptionsView,
                PermissionGroup::ReconExceptionsManage,
                PermissionGroup::ReconTransactionsView,
                PermissionGroup::ReconTransactionsManage,
                PermissionGroup::ReconRulesView,
                PermissionGroup::ReconRulesManage,
            ],
            role_id: common_utils::consts::ROLE_ID_TENANT_ADMIN.to_string(),
            role_name: "tenant_admin".to_string(),
            scope: RoleScope::Organization,
            entity_type: EntityType::Tenant,
            is_invitable: false,
            is_deletable: false,
            is_updatable: false,
            is_internal: false,
            product_type_filter: None,
        },
    );

    // Organization Roles
    roles.insert(
        common_utils::consts::ROLE_ID_ORGANIZATION_ADMIN,
        RoleInfo {
            groups: vec![
                PermissionGroup::OperationsView,
                PermissionGroup::OperationsManage,
                PermissionGroup::ConnectorsView,
                PermissionGroup::ConnectorsManage,
                PermissionGroup::WorkflowsView,
                PermissionGroup::WorkflowsManage,
                PermissionGroup::AnalyticsView,
                PermissionGroup::UsersView,
                PermissionGroup::UsersManage,
                PermissionGroup::AccountView,
                PermissionGroup::AccountManage,
                PermissionGroup::CloneConnectorManage,
                PermissionGroup::ThemeView,
                PermissionGroup::ThemeManage,
                PermissionGroup::ConfigurationsView,
                PermissionGroup::ConfigurationsManage,
                PermissionGroup::ReconSourcesView,
                PermissionGroup::ReconSourcesManage,
                PermissionGroup::ReconExceptionsView,
                PermissionGroup::ReconExceptionsManage,
                PermissionGroup::ReconTransactionsView,
                PermissionGroup::ReconTransactionsManage,
                PermissionGroup::ReconRulesView,
                PermissionGroup::ReconRulesManage,
            ],
            role_id: common_utils::consts::ROLE_ID_ORGANIZATION_ADMIN.to_string(),
            role_name: "organization_admin".to_string(),
            scope: RoleScope::Organization,
            entity_type: EntityType::Organization,
            is_invitable: true,
            is_deletable: true,
            is_updatable: true,
            is_internal: false,
            // Org level roles should not have any product type
            product_type_filter: None,
        },
    );

    // MERCHANT ROLES
    roles.insert(
        consts::user_role::ROLE_ID_MERCHANT_ADMIN,
        RoleInfo {
            groups: vec![
                PermissionGroup::OperationsView,
                PermissionGroup::OperationsManage,
                PermissionGroup::ConnectorsView,
                PermissionGroup::ConnectorsManage,
                PermissionGroup::WorkflowsView,
                PermissionGroup::WorkflowsManage,
                PermissionGroup::AnalyticsView,
                PermissionGroup::UsersView,
                PermissionGroup::UsersManage,
                PermissionGroup::AccountView,
                PermissionGroup::AccountManage,
                PermissionGroup::ConfigurationsView,
                PermissionGroup::ConfigurationsManage,
                PermissionGroup::CloneConnectorManage,
            ],
            role_id: consts::user_role::ROLE_ID_MERCHANT_ADMIN.to_string(),
            role_name: "merchant_admin".to_string(),
            scope: RoleScope::Organization,
            entity_type: EntityType::Merchant,
            is_invitable: true,
            is_deletable: true,
            is_updatable: true,
            is_internal: false,
            product_type_filter: Some(MerchantProductType::Orchestration),
        },
    );
    roles.insert(
        consts::user_role::ROLE_ID_MERCHANT_VIEW_ONLY,
        RoleInfo {
            groups: vec![
                PermissionGroup::OperationsView,
                PermissionGroup::ConnectorsView,
                PermissionGroup::WorkflowsView,
                PermissionGroup::AnalyticsView,
                PermissionGroup::UsersView,
                PermissionGroup::AccountView,
            ],
            role_id: consts::user_role::ROLE_ID_MERCHANT_VIEW_ONLY.to_string(),
            role_name: "merchant_view_only".to_string(),
            scope: RoleScope::Organization,
            entity_type: EntityType::Merchant,
            is_invitable: true,
            is_deletable: true,
            is_updatable: true,
            is_internal: false,
            product_type_filter: Some(MerchantProductType::Orchestration),
        },
    );
    roles.insert(
        consts::user_role::ROLE_ID_MERCHANT_IAM_ADMIN,
        RoleInfo {
            groups: vec![
                PermissionGroup::OperationsView,
                PermissionGroup::AnalyticsView,
                PermissionGroup::UsersView,
                PermissionGroup::UsersManage,
                PermissionGroup::AccountView,
            ],
            role_id: consts::user_role::ROLE_ID_MERCHANT_IAM_ADMIN.to_string(),
            role_name: "merchant_iam".to_string(),
            scope: RoleScope::Organization,
            entity_type: EntityType::Merchant,
            is_invitable: true,
            is_deletable: true,
            is_updatable: true,
            is_internal: false,
            product_type_filter: Some(MerchantProductType::Orchestration),
        },
    );
    roles.insert(
        consts::user_role::ROLE_ID_MERCHANT_DEVELOPER,
        RoleInfo {
            groups: vec![
                PermissionGroup::OperationsView,
                PermissionGroup::ConnectorsView,
                PermissionGroup::AnalyticsView,
                PermissionGroup::UsersView,
                PermissionGroup::AccountView,
                PermissionGroup::AccountManage,
            ],
            role_id: consts::user_role::ROLE_ID_MERCHANT_DEVELOPER.to_string(),
            role_name: "merchant_developer".to_string(),
            scope: RoleScope::Organization,
            entity_type: EntityType::Merchant,
            is_invitable: true,
            is_deletable: true,
            is_updatable: true,
            is_internal: false,
            product_type_filter: Some(MerchantProductType::Orchestration),
        },
    );
    roles.insert(
        consts::user_role::ROLE_ID_MERCHANT_OPERATOR,
        RoleInfo {
            groups: vec![
                PermissionGroup::OperationsView,
                PermissionGroup::OperationsManage,
                PermissionGroup::ConnectorsView,
                PermissionGroup::WorkflowsView,
                PermissionGroup::AnalyticsView,
                PermissionGroup::UsersView,
                PermissionGroup::AccountView,
            ],
            role_id: consts::user_role::ROLE_ID_MERCHANT_OPERATOR.to_string(),
            role_name: "merchant_operator".to_string(),
            scope: RoleScope::Organization,
            entity_type: EntityType::Merchant,
            is_invitable: true,
            is_deletable: true,
            is_updatable: true,
            is_internal: false,
            product_type_filter: Some(MerchantProductType::Orchestration),
        },
    );
    roles.insert(
        consts::user_role::ROLE_ID_MERCHANT_CUSTOMER_SUPPORT,
        RoleInfo {
            groups: vec![
                PermissionGroup::OperationsView,
                PermissionGroup::AnalyticsView,
                PermissionGroup::UsersView,
                PermissionGroup::AccountView,
            ],
            role_id: consts::user_role::ROLE_ID_MERCHANT_CUSTOMER_SUPPORT.to_string(),
            role_name: "customer_support".to_string(),
            scope: RoleScope::Organization,
            entity_type: EntityType::Merchant,
            is_invitable: true,
            is_deletable: true,
            is_updatable: true,
            is_internal: false,
            product_type_filter: Some(MerchantProductType::Orchestration),
        },
    );

    // Profile Roles
    roles.insert(
        consts::user_role::ROLE_ID_PROFILE_ADMIN,
        RoleInfo {
            groups: vec![
                PermissionGroup::OperationsView,
                PermissionGroup::OperationsManage,
                PermissionGroup::ConnectorsView,
                PermissionGroup::ConnectorsManage,
                PermissionGroup::WorkflowsView,
                PermissionGroup::WorkflowsManage,
                PermissionGroup::AnalyticsView,
                PermissionGroup::UsersView,
                PermissionGroup::UsersManage,
                PermissionGroup::AccountView,
                PermissionGroup::AccountManage,
                PermissionGroup::ConfigurationsView,
                PermissionGroup::ConfigurationsManage,
            ],
            role_id: consts::user_role::ROLE_ID_PROFILE_ADMIN.to_string(),
            role_name: "profile_admin".to_string(),
            scope: RoleScope::Organization,
            entity_type: EntityType::Profile,
            is_invitable: true,
            is_deletable: true,
            is_updatable: true,
            is_internal: false,
            product_type_filter: Some(MerchantProductType::Orchestration),
        },
    );
    roles.insert(
        consts::user_role::ROLE_ID_PROFILE_VIEW_ONLY,
        RoleInfo {
            groups: vec![
                PermissionGroup::OperationsView,
                PermissionGroup::ConnectorsView,
                PermissionGroup::WorkflowsView,
                PermissionGroup::AnalyticsView,
                PermissionGroup::UsersView,
                PermissionGroup::AccountView,
            ],
            role_id: consts::user_role::ROLE_ID_PROFILE_VIEW_ONLY.to_string(),
            role_name: "profile_view_only".to_string(),
            scope: RoleScope::Organization,
            entity_type: EntityType::Profile,
            is_invitable: true,
            is_deletable: true,
            is_updatable: true,
            is_internal: false,
            product_type_filter: Some(MerchantProductType::Orchestration),
        },
    );
    roles.insert(
        consts::user_role::ROLE_ID_PROFILE_IAM_ADMIN,
        RoleInfo {
            groups: vec![
                PermissionGroup::OperationsView,
                PermissionGroup::AnalyticsView,
                PermissionGroup::UsersView,
                PermissionGroup::UsersManage,
                PermissionGroup::AccountView,
            ],
            role_id: consts::user_role::ROLE_ID_PROFILE_IAM_ADMIN.to_string(),
            role_name: "profile_iam".to_string(),
            scope: RoleScope::Organization,
            entity_type: EntityType::Profile,
            is_invitable: true,
            is_deletable: true,
            is_updatable: true,
            is_internal: false,
            product_type_filter: Some(MerchantProductType::Orchestration),
        },
    );
    roles.insert(
        consts::user_role::ROLE_ID_PROFILE_DEVELOPER,
        RoleInfo {
            groups: vec![
                PermissionGroup::OperationsView,
                PermissionGroup::ConnectorsView,
                PermissionGroup::AnalyticsView,
                PermissionGroup::UsersView,
                PermissionGroup::AccountView,
                PermissionGroup::AccountManage,
            ],
            role_id: consts::user_role::ROLE_ID_PROFILE_DEVELOPER.to_string(),
            role_name: "profile_developer".to_string(),
            scope: RoleScope::Organization,
            entity_type: EntityType::Profile,
            is_invitable: true,
            is_deletable: true,
            is_updatable: true,
            is_internal: false,
            product_type_filter: Some(MerchantProductType::Orchestration),
        },
    );
    roles.insert(
        consts::user_role::ROLE_ID_PROFILE_OPERATOR,
        RoleInfo {
            groups: vec![
                PermissionGroup::OperationsView,
                PermissionGroup::OperationsManage,
                PermissionGroup::ConnectorsView,
                PermissionGroup::WorkflowsView,
                PermissionGroup::AnalyticsView,
                PermissionGroup::UsersView,
                PermissionGroup::AccountView,
            ],
            role_id: consts::user_role::ROLE_ID_PROFILE_OPERATOR.to_string(),
            role_name: "profile_operator".to_string(),
            scope: RoleScope::Organization,
            entity_type: EntityType::Profile,
            is_invitable: true,
            is_deletable: true,
            is_updatable: true,
            is_internal: false,
            product_type_filter: Some(MerchantProductType::Orchestration),
        },
    );
    roles.insert(
        consts::user_role::ROLE_ID_PROFILE_CUSTOMER_SUPPORT,
        RoleInfo {
            groups: vec![
                PermissionGroup::OperationsView,
                PermissionGroup::AnalyticsView,
                PermissionGroup::UsersView,
                PermissionGroup::AccountView,
            ],
            role_id: consts::user_role::ROLE_ID_PROFILE_CUSTOMER_SUPPORT.to_string(),
            role_name: "profile_customer_support".to_string(),
            scope: RoleScope::Organization,
            entity_type: EntityType::Profile,
            is_invitable: true,
            is_deletable: true,
            is_updatable: true,
            is_internal: false,
            product_type_filter: Some(MerchantProductType::Orchestration),
        },
    );
    // Recon Roles
    roles.insert(
        consts::user_role::ROLE_ID_RECON_MERCHANT_ADMIN,
        RoleInfo {
            groups: vec![
                PermissionGroup::ReconSourcesView,
                PermissionGroup::ReconSourcesManage,
                PermissionGroup::ReconExceptionsView,
                PermissionGroup::ReconExceptionsManage,
                PermissionGroup::ReconTransactionsView,
                PermissionGroup::ReconTransactionsManage,
                PermissionGroup::UsersView,
                PermissionGroup::UsersManage,
                PermissionGroup::ReconRulesView,
                PermissionGroup::ReconRulesManage,
            ],
            role_id: consts::user_role::ROLE_ID_RECON_MERCHANT_ADMIN.to_string(),
            role_name: "recon_merchant_admin".to_string(),
            scope: RoleScope::Organization,
            entity_type: EntityType::Merchant,
            is_invitable: true,
            is_deletable: true,
            is_updatable: true,
            is_internal: false,
            product_type_filter: Some(MerchantProductType::Recon),
        },
    );
    roles.insert(
        consts::user_role::ROLE_ID_RECON_MERCHANT_DATA_ENGINEER,
        RoleInfo {
            groups: vec![
                PermissionGroup::ReconSourcesView,
                PermissionGroup::ReconSourcesManage,
                PermissionGroup::ReconTransactionsView,
                PermissionGroup::UsersView,
                PermissionGroup::ReconRulesView,
            ],
            role_id: consts::user_role::ROLE_ID_RECON_MERCHANT_DATA_ENGINEER.to_string(),
            role_name: "recon_merchant_data_engineer".to_string(),
            scope: RoleScope::Organization,
            entity_type: EntityType::Merchant,
            is_invitable: true,
            is_deletable: true,
            is_updatable: true,
            is_internal: false,
            product_type_filter: Some(MerchantProductType::Recon),
        },
    );
    roles.insert(
        consts::user_role::ROLE_ID_RECON_MERCHANT_OPERATOR,
        RoleInfo {
            groups: vec![
                PermissionGroup::ReconExceptionsView,
                PermissionGroup::ReconExceptionsManage,
                PermissionGroup::ReconTransactionsView,
                PermissionGroup::ReconTransactionsManage,
                PermissionGroup::ReconSourcesView,
                PermissionGroup::UsersView,
                PermissionGroup::ReconRulesView,
            ],
            role_id: consts::user_role::ROLE_ID_RECON_MERCHANT_OPERATOR.to_string(),
            role_name: "recon_merchant_operator".to_string(),
            scope: RoleScope::Organization,
            entity_type: EntityType::Merchant,
            is_invitable: true,
            is_deletable: true,
            is_updatable: true,
            is_internal: false,
            product_type_filter: Some(MerchantProductType::Recon),
        },
    );
    roles.insert(
        consts::user_role::ROLE_ID_RECON_MERCHANT_VIEW_ONLY,
        RoleInfo {
            groups: vec![
                PermissionGroup::ReconSourcesView,
                PermissionGroup::ReconTransactionsView,
                PermissionGroup::ReconExceptionsView,
                PermissionGroup::UsersView,
                PermissionGroup::ReconRulesView,
            ],
            role_id: consts::user_role::ROLE_ID_RECON_MERCHANT_VIEW_ONLY.to_string(),
            role_name: "recon_merchant_view_only".to_string(),
            scope: RoleScope::Organization,
            entity_type: EntityType::Merchant,
            is_invitable: true,
            is_deletable: true,
            is_updatable: true,
            is_internal: false,
            product_type_filter: Some(MerchantProductType::Recon),
        },
    );

    // Profile Recon Roles
    roles.insert(
        consts::user_role::ROLE_ID_RECON_PROFILE_ADMIN,
        RoleInfo {
            groups: vec![
                PermissionGroup::ReconSourcesView,
                PermissionGroup::ReconSourcesManage,
                PermissionGroup::ReconExceptionsView,
                PermissionGroup::ReconExceptionsManage,
                PermissionGroup::ReconTransactionsView,
                PermissionGroup::ReconTransactionsManage,
                PermissionGroup::UsersView,
                PermissionGroup::UsersManage,
                PermissionGroup::ReconRulesView,
                PermissionGroup::ReconRulesManage,
            ],
            role_id: consts::user_role::ROLE_ID_RECON_PROFILE_ADMIN.to_string(),
            role_name: "recon_profile_admin".to_string(),
            scope: RoleScope::Organization,
            entity_type: EntityType::Profile,
            is_invitable: true,
            is_deletable: true,
            is_updatable: true,
            is_internal: false,
            product_type_filter: Some(MerchantProductType::Recon),
        },
    );
    roles.insert(
        consts::user_role::ROLE_ID_RECON_PROFILE_DATA_ENGINEER,
        RoleInfo {
            groups: vec![
                PermissionGroup::ReconSourcesView,
                PermissionGroup::ReconSourcesManage,
                PermissionGroup::ReconTransactionsView,
                PermissionGroup::UsersView,
                PermissionGroup::ReconRulesView,
            ],
            role_id: consts::user_role::ROLE_ID_RECON_PROFILE_DATA_ENGINEER.to_string(),
            role_name: "recon_profile_data_engineer".to_string(),
            scope: RoleScope::Organization,
            entity_type: EntityType::Profile,
            is_invitable: true,
            is_deletable: true,
            is_updatable: true,
            is_internal: false,
            product_type_filter: Some(MerchantProductType::Recon),
        },
    );
    roles.insert(
        consts::user_role::ROLE_ID_RECON_PROFILE_OPERATOR,
        RoleInfo {
            groups: vec![
                PermissionGroup::ReconExceptionsView,
                PermissionGroup::ReconExceptionsManage,
                PermissionGroup::ReconTransactionsView,
                PermissionGroup::ReconTransactionsManage,
                PermissionGroup::ReconSourcesView,
                PermissionGroup::UsersView,
                PermissionGroup::ReconRulesView,
            ],
            role_id: consts::user_role::ROLE_ID_RECON_PROFILE_OPERATOR.to_string(),
            role_name: "recon_profile_operator".to_string(),
            scope: RoleScope::Organization,
            entity_type: EntityType::Profile,
            is_invitable: true,
            is_deletable: true,
            is_updatable: true,
            is_internal: false,
            product_type_filter: Some(MerchantProductType::Recon),
        },
    );
    roles.insert(
        consts::user_role::ROLE_ID_RECON_PROFILE_VIEW_ONLY,
        RoleInfo {
            groups: vec![
                PermissionGroup::ReconSourcesView,
                PermissionGroup::ReconTransactionsView,
                PermissionGroup::ReconExceptionsView,
                PermissionGroup::UsersView,
                PermissionGroup::ReconRulesView,
            ],
            role_id: consts::user_role::ROLE_ID_RECON_PROFILE_VIEW_ONLY.to_string(),
            role_name: "recon_profile_view_only".to_string(),
            scope: RoleScope::Organization,
            entity_type: EntityType::Profile,
            is_invitable: true,
            is_deletable: true,
            is_updatable: true,
            is_internal: false,
            product_type_filter: Some(MerchantProductType::Recon),
        },
    );

    roles
});
