public async Task <IActionResult> CreateItem([FromRoute] ulong guildId, [FromBody] ModCaseForCreateDto modCaseDto, [FromQuery] bool sendPublicNotification = true, [FromQuery] bool handlePunishment = true, [FromQuery] bool sendDmNotification = true)
        {
            Identity currentIdentity = await GetIdentity();

            if (!await currentIdentity.HasPermissionToExecutePunishment(guildId, modCaseDto.PunishmentType))
            {
                throw new UnauthorizedException();
            }

            ModCase newModCase = new()
            {
                Title       = modCaseDto.Title,
                Description = modCaseDto.Description,
                GuildId     = guildId,
                ModId       = currentIdentity.GetCurrentUser().Id,
                UserId      = modCaseDto.UserId,
                Labels      = modCaseDto.Labels.Distinct().ToArray(),
                Others      = modCaseDto.Others
            };

            if (modCaseDto.OccuredAt.HasValue)
            {
                newModCase.OccuredAt = modCaseDto.OccuredAt.Value;
            }
            newModCase.CreationType   = CaseCreationType.Default;
            newModCase.PunishmentType = modCaseDto.PunishmentType;
            newModCase.PunishedUntil  = modCaseDto.PunishedUntil;

            newModCase = await ModCaseRepository.CreateDefault(_serviceProvider, currentIdentity).CreateModCase(newModCase, handlePunishment, sendPublicNotification, sendDmNotification);

            return(StatusCode(201, newModCase));
        }
        public async Task <IActionResult> CreateItem([FromRoute] string guildid, [FromBody] ModCaseForCreateDto modCase, [FromQuery] bool sendNotification = true, [FromQuery] bool handlePunishment = true)
        {
            logger.LogInformation($"{HttpContext.Request.Method} {HttpContext.Request.Path} | Incoming request.");
            Identity currentIdentity = await identityManager.GetIdentity(HttpContext);

            User currentUser = await currentIdentity.GetCurrentDiscordUser();

            if (currentUser == null)
            {
                logger.LogInformation($"{HttpContext.Request.Method} {HttpContext.Request.Path} | 401 Unauthorized.");
                return(Unauthorized());
            }
            if (!await currentIdentity.HasModRoleOrHigherOnGuild(guildid, this.database) && !config.Value.SiteAdminDiscordUserIds.Contains(currentUser.Id))
            {
                logger.LogInformation($"{HttpContext.Request.Method} {HttpContext.Request.Path} | 401 Unauthorized.");
                return(Unauthorized());
            }
            // ========================================================

            GuildConfig guildConfig = await database.SelectSpecificGuildConfig(guildid);

            if (guildConfig == null)
            {
                logger.LogInformation($"{HttpContext.Request.Method} {HttpContext.Request.Path} | 400 Guild not registered.");
                return(BadRequest("Guild not registered."));
            }

            var currentModerator = currentUser.Id;

            if (currentModerator == null)
            {
                logger.LogInformation($"{HttpContext.Request.Method} {HttpContext.Request.Path} | 400 Failed to fetch mod user info.");
                return(BadRequest("Could not fetch own user info."));
            }

            ModCase newModCase = new ModCase();

            User currentReportedUser = await discord.FetchUserInfo(modCase.UserId, true);

            if (currentReportedUser == null)
            {
                logger.LogInformation($"{HttpContext.Request.Method} {HttpContext.Request.Path} | 400 Invalid Discord UserId.");
                return(BadRequest("Invalid Discord UserId."));
            }
            if (currentReportedUser.Bot)
            {
                logger.LogInformation($"{HttpContext.Request.Method} {HttpContext.Request.Path} | 400 Cannot create cases for bots.");
                return(BadRequest("Cannot create cases for bots."));
            }
            if (config.Value.SiteAdminDiscordUserIds.Contains(currentReportedUser.Id))
            {
                logger.LogInformation($"{HttpContext.Request.Method} {HttpContext.Request.Path} | 400 Cannot create cases for site admins.");
                return(BadRequest("Cannot create cases for site admins."));
            }

            newModCase.Username      = currentReportedUser.Username;
            newModCase.Discriminator = currentReportedUser.Discriminator;

            GuildMember currentReportedMember = await discord.FetchMemberInfo(guildid, modCase.UserId, true);

            if (currentReportedMember != null)
            {
                if (currentReportedMember.Roles.Contains(guildConfig.ModRoleId) || currentReportedMember.Roles.Contains(guildConfig.AdminRoleId))
                {
                    logger.LogInformation($"{HttpContext.Request.Method} {HttpContext.Request.Path} | 400 Cannot create cases for team members.");
                    return(BadRequest("Cannot create cases for team members."));
                }
                newModCase.Nickname = currentReportedMember.Nick;
            }

            newModCase.CaseId = await database.GetHighestCaseIdForGuild(guildid) + 1;

            newModCase.Title       = modCase.Title;
            newModCase.Description = modCase.Description;
            newModCase.GuildId     = guildid;
            newModCase.ModId       = currentModerator;
            newModCase.UserId      = modCase.UserId;
            newModCase.CreatedAt   = DateTime.UtcNow;
            if (modCase.OccuredAt.HasValue)
            {
                newModCase.OccuredAt = modCase.OccuredAt.Value;
            }
            else
            {
                newModCase.OccuredAt = newModCase.CreatedAt;
            }
            newModCase.LastEditedAt      = newModCase.CreatedAt;
            newModCase.LastEditedByModId = currentModerator;
            newModCase.Punishment        = modCase.Punishment;
            newModCase.Labels            = modCase.Labels.Distinct().ToArray();
            newModCase.Others            = modCase.Others;
            newModCase.Valid             = true;
            newModCase.PunishmentType    = modCase.PunishmentType;
            newModCase.PunishedUntil     = modCase.PunishedUntil;
            if (modCase.PunishmentType == PunishmentType.None)
            {
                modCase.PunishedUntil    = null;
                modCase.PunishmentActive = false;
            }
            if (modCase.PunishedUntil == null)
            {
                newModCase.PunishmentActive = modCase.PunishmentType != PunishmentType.None && modCase.PunishmentType != PunishmentType.Kick;
            }
            else
            {
                newModCase.PunishmentActive = modCase.PunishedUntil > DateTime.UtcNow && modCase.PunishmentType != PunishmentType.None && modCase.PunishmentType != PunishmentType.Kick;
            }

            await database.SaveModCase(newModCase);

            await database.SaveChangesAsync();

            if (handlePunishment && (newModCase.PunishmentActive || newModCase.PunishmentType == PunishmentType.Kick))
            {
                if (newModCase.PunishedUntil == null || newModCase.PunishedUntil > DateTime.UtcNow)
                {
                    try {
                        logger.LogInformation($"{HttpContext.Request.Method} {HttpContext.Request.Path} | Handling punishment.");
                        await punishmentHandler.ExecutePunishment(newModCase, database);
                    }
                    catch (Exception e) {
                        logger.LogError(e, "Failed to handle punishment for modcase.");
                    }
                }
            }

            logger.LogInformation($"{HttpContext.Request.Method} {HttpContext.Request.Path} | Sending notification.");
            try {
                await discordAnnouncer.AnnounceModCase(newModCase, RestAction.Created, currentUser, sendNotification);
            }
            catch (Exception e) {
                logger.LogError(e, "Failed to announce modcase.");
            }

            logger.LogInformation(HttpContext.Request.Method + " " + HttpContext.Request.Path + " | 201 Resource created.");
            return(StatusCode(201, new { id = newModCase.Id, caseid = newModCase.CaseId }));
        }