
import discord
from discord.ext import commands 
from discord.utils import get
import os
import asyncio
import random
import re
import json
import string
from discord.ext.commands import has_permissions, MissingPermissions
from discord import File
import io
import sys
import os
from discord.ext import commands
import os
import random
import youtube_dl
import discord
from discord.ext import commands
import discord
from discord.ext import commands
import youtube_dl
import os


def __init__(self, client):
    self.client = client
    



intents = discord.Intents.default()
intents.members = True

client = commands.Bot(command_prefix=".", intents=intents, case_insensitive=True)
client.remove_command('help')

#global banning bot test

@client.event 
async def on_member_join(member):
    await member.send(f"Welcome To {member.guild.name} Enjoy Your Stay :)")

    with open('bans.json', 'r') as f:
        load = json.load(f)
    try:
        load[str(member.id)]
    except KeyError:
        return

    await member.send(f"You're globally banned.")
    await member.ban(reason="This user was previously globally banned.")
    droppxlogs = client.get_channel(887139696415739970)
    await droppxlogs.send(f"**{member}** | **{member.id}** was removed from {member.guild.name}")



@client.event
async def on_guild_join(guild):
    newserverjoinlog = client.get_channel(887139696700956722)
    await newserverjoinlog.send(f"Droppx Has Been Added To A New Server! Server's Name: **{guild.name}** With The Guild ID: **{guild.id}** Server Owner: **{guild.owner}**")

    with open('guildblacklist.json', 'r') as f:
        load = json.load(f)
    try:
        load[str(guild.id)]
    except KeyError:
        return

    await guild.leave()


#Moderation Commands:

@client.event
async def on_ready():
    online = True
    while online:

     await client.change_presence(activity=discord.Activity(type=discord.ActivityType.listening, name=f"@DroppX Bot | Moderation/Global Banning Bot. Users: {len(client.users)}"))
    await asyncio.sleep(7)

    print("Bot is online!")

@commands.Cog.listener()
async def on_command_error(ctx, error):
    if isinstance(error, commands.NotOwner):
        return await ctx.send("Only developers can do this!")

    elif isinstance(error, commands.CommandNotFound):
        return

    elif isinstance(error, commands.MissingAnyRole):
        return await ctx.send("You do not have the required role to use this command!")

    elif isinstance(error, commands.MissingRole):
        return await ctx.send("You do not have the required role to use this command!")

    elif isinstance(error, commands.MissingRequiredArgument):
        return await ctx.send(f"{error.param.name} is a required argument that is missing!")

    elif isinstance(error, commands.NoPrivateMessage):
        return await ctx.send("This command cannot be used in private messages!")

@client.command() #Ban command
@commands.has_role(887139696193449990)
async def manualban(ctx, member : discord.User, *, reason=None):

    owner_ids = [842626352950673418, 700871587120939018]
    if member.id in owner_ids:
        return await ctx.send("You cannot do this.")
    
    numbers = string.digits
    ban_id = ''.join(random.sample(numbers, 5))
    
    droppxlogs = client.get_channel(887139696415739970)
    droppxglobalbans = client.get_channel(887139696415739971)
    
    await droppxlogs.send(f"User `{member.name}` has been globally banned for the reason: `{reason}` with the ban ID: `{ban_id}`")
    await ctx.reply(f"User `{member.name}` has been globally banned for the reason: `{reason}` with the ban ID: `{ban_id}`")
    
    with open('bans.json', 'r') as f:
        load = json.load(f)
        
    servers_banned_from = []
    
    for guild in client.guilds:
        if member in guild.members:
            await guild.ban(user=member, reason=reason)
            servers_banned_from.append(guild.id)
            await asyncio.sleep(4)
        else:
            pass
        
        with open('bans.json', 'r') as f:
            b = json.load(f)
            
        b[str(ban_id)] = {}
        b[str(ban_id)]["User ID"] = int(member.id)
        b[str(ban_id)]["Reason"] = reason
        b[str(ban_id)]["Servers"] = servers_banned_from
        
        with open('bans.json', 'w') as f:
            json.dump(b, f, indent=4)
            
        load[str(member.id)] = str(reason)
        
        with open('bans.json', 'w') as f:
            json.dump(load, f, indent=4)
            
        with open('bans.json', 'r') as f:
            b = json.load(f)
            
        b[str(ban_id)] = {}
        b[str(ban_id)]["User ID"] = int(member.id)
        b[str(ban_id)]["Reason"] = reason
        b[str(ban_id)]["Servers"] = servers_banned_from
        b[str(ban_id)]["Staff"] = int(ctx.author.id)
        
        with open('bans.json', 'w') as f:
            json.dump(b, f, indent=4)

    
        

@client.command() #Ban command
@commands.has_role(887139696193449990)
async def globalban(ctx, member : discord.Member, *, reason=None):

    owner_ids = [842626352950673418, 700871587120939018]
    if member.id in owner_ids:
        return await ctx.send("You cannot do this.")
    
    numbers = string.digits
    ban_id = ''.join(random.sample(numbers, 5))
    
    droppxlogs = client.get_channel(887139696415739970)
    droppxglobalbans = client.get_channel(887139696415739971)
    
    await droppxlogs.send(f"User `{member.name}` has been globally banned for the reason: `{reason}` with the ban ID: `{ban_id}`")
    await ctx.reply(f"User `{member.name}` has been globally banned for the reason: `{reason}` with the ban ID: `{ban_id}`")
    await member.send(f"You have been banned from `{ctx.guild.name}` for the reason: `{reason}` by `{ctx.author}`")
    await member.ban()
    
    with open('bans.json', 'r') as f:
        load = json.load(f)
        
    
    servers_banned_from = []
    
    for guild in client.guilds:
        if member in guild.members:
            await guild.ban(user=member, reason=reason)
            servers_banned_from.append(guild.id)
            await asyncio.sleep(4)
        else:
            pass
        
        
        with open('bans.json', 'r') as f:
            b = json.load(f)
            
        b[str(ban_id)] = {}
        b[str(ban_id)]["User ID"] = int(member.id)
        b[str(ban_id)]["Reason"] = reason
        b[str(ban_id)]["Servers"] = servers_banned_from
        
        with open('bans.json', 'w') as f:
            json.dump(b, f, indent=4)
            
        load[str(member.id)] = str(reason)
        
        with open('bans.json', 'w') as f:
            json.dump(load, f, indent=4)
            
        with open('bans.json', 'r') as f:
            b = json.load(f)
            
        b[str(ban_id)] = {}
        b[str(ban_id)]["User ID"] = int(member.id)
        b[str(ban_id)]["Reason"] = reason
        b[str(ban_id)]["Servers"] = servers_banned_from
        b[str(ban_id)]["Staff"] = int(ctx.author.id)
        
        with open('bans.json', 'w') as f:
            json.dump(b, f, indent=4)


@client.command()
@commands.has_role(887139696193449990)
async def searchban(ctx, ban_id: str):
    with open('bans.json', 'r') as f:
        load = json.load(f)

    try:
        load[str(ban_id)]
    except KeyError:
        return await ctx.send(f"Cannot find records of ban: {ban_id}")

    
    
    reason = load[str(ban_id)]["Reason"]
    staff_id = load[str(ban_id)]["Staff"]
    user_id = load[str(ban_id)]["User ID"]
    user = client.get_user(user_id)
    staff = client.get_user(staff_id)
    
    embed = discord.Embed(
        color=ctx.author.color, description=f"Ban information for {ban_id}")
    embed.add_field(name="User", value=f"{user_id}", inline=False)
    embed.add_field(name="Reason", value=reason, inline=False)
    embed.add_field(name="Staff", value=f"{staff} ({staff.id})", inline=False)
    
    await ctx.send(embed=embed)


@client.command()
@commands.has_role(887139696193449990)
async def searchblacklist(ctx, ban_id: str):
    with open('guildblacklist.json', 'r') as f:
        load = json.load(f)

    try:
        load[str(ban_id)]
    except KeyError:
        return await ctx.send(f"Cannot find records of ban: {ban_id}")

    
    
    reason = load[str(ban_id)]["Reason"]
    staff_id = load[str(ban_id)]["Staff"]
    user_id = load[str(ban_id)]["Guild ID"]
    guild_banned = load[str(ban_id)]["Guild ID"]
    user = client.get_user(user_id)
    staff = client.get_user(staff_id)
    
    embed = discord.Embed(
        color=ctx.author.color, description=f"Ban information for {ban_id}")
    embed.add_field(name="Ban ID", value=f"{ban_id}", inline=False)
    embed.add_field(name="Guild", value=f"{guild_banned}", inline=False)
    embed.add_field(name="Reason", value=reason, inline=False)
    embed.add_field(name="Staff", value=f"{staff} ({staff.id})", inline=False)
    
    await ctx.send(embed=embed)


            
        
@client.command() #Ban command
@has_permissions(ban_members=True, kick_members=True)
async def ban(ctx, member : discord.Member, *, reason=None):
    staff_ids = [842626352950673418, 700871587120939018]
    if member.id in staff_ids:
        return await ctx.send("You cannot do this. You're trying to ban a staff member.")
    droppxlogs = client.get_channel(888763901448163399)

    embed = discord.Embed(
    color=ctx.author.color, description="Message From DROPPX")
    embed.add_field(name=f"Banned {member}", value=f"You Have Been Banned From {ctx.guild.name} For: {reason}", inline=False)
    embed.set_author(name=ctx.author, icon_url=ctx.author.avatar_url)
    embed.set_thumbnail(url=ctx.guild.icon_url)
    await ctx.send(embed=embed)
    await member.send(embed=embed)
    await member.ban(reason=reason)
    await droppxlogs.send(f"{member.name} | {member.id} has been banned by **{ctx.author}** for `{reason}`")

@client.command()
async def reportuser(ctx, member : discord.User, *, reason=None):
    droppxlogs = client.get_channel(887139696415739972)
    
    owner_ids = [842626352950673418, 700871587120939018]
    if member.id in owner_ids:
        return await ctx.send("You cannot report owner's of the bot.")

    await ctx.author.send(f"You Have Succesfully Reported {member.name} | {member.id} Plz Wait Up To 24 Hours To Get A Response From The Staff Team Of Droppx.")
    await droppxlogs.send(f"{member.name} | {member.id} has been reported by **{ctx.author}** for `{reason}` This Report Has Come From The Server `{ctx.guild.name}` With The Guild ID: `{ctx.guild.id}`")
    await ctx.message.delete()


@client.command()
async def suggest(ctx, *, Suggestion=None):
    droppxlogs = client.get_channel(887139696415739973)

    await ctx.author.send(f"Thank You For The Suggestion We Will Check It Out!")
    await droppxlogs.send(f"**{ctx.author}** Has Made A Suggestion They Suggest: {Suggestion}")
    await ctx.message.delete()

@client.command()
@commands.is_owner()
async def announce(ctx, Titleofembed=None, *, announcement=None):
    announcechannel = client.get_channel(872359840314441792)

    embed = discord.Embed(
    color=ctx.author.color, description=f"{Titleofembed}")
    embed.add_field(name="DroppX", value=f"Announcement!", inline=False)
    embed.add_field(name="Announcement", value=f"New Announcement: {announcement}\n", inline=False)
    embed.set_footer(text=f"This Announcement Has Been Sent By {ctx.author.name}")
    embed.set_author(name=ctx.author, icon_url=ctx.author.avatar_url)
    embed.set_thumbnail(url=ctx.guild.icon_url)
    await announcechannel.send(embed=embed)
    
    await announcechannel.send("@everyone")
    await ctx.reply(f'Sent Announcement! Under The Name Of {ctx.author}')


@client.command() #Kick command
@has_permissions(kick_members=True)
async def kick(ctx, member : discord.Member, *, reason=None):
    staff_ids = [842626352950673418, 700871587120939018]
    if member.id in staff_ids:
        return await ctx.send("You cannot do this. You're trying to kick a staff member.")
    droppxlogs = client.get_channel(888763901448163399)

    embed = discord.Embed(
    color=ctx.author.color, description="Message From DROPPX")
    embed.add_field(name=f"Kicked {member}", value=f"You Have Been Kicked For : {reason}", inline=False)
    embed.set_author(name=ctx.author, icon_url=ctx.author.avatar_url)
    embed.set_thumbnail(url=ctx.guild.icon_url)
    await ctx.send(embed=embed)
    await member.send(embed=embed)
    await member.kick(reason=reason)
    await droppxlogs.send(f"{member.name} | {member.id} has been kicked by **{ctx.author}** for `{reason}`")


@client.command(aliases=['warnmember'])
@has_permissions(ban_members=True, kick_members=True)
async def warn(ctx, member: discord.User, *, reason="No reason specified"):
    staff_ids = [842626352950673418, 700871587120939018]
    if member.id in staff_ids:
        return await ctx.send("You cannot do this. You're trying to warn a staff member.")
    droppxlogs = client.get_channel(888763901448163399)
    
    embed = discord.Embed(
    color=ctx.author.color, description="Message From DROPPX")
    embed.add_field(name="Droppx, Adaph", value=f"You Have Been Warned For : {reason}", inline=False)
    embed.set_author(name=ctx.author, icon_url=ctx.author.avatar_url)
    embed.set_thumbnail(url=ctx.guild.icon_url)

    await member.send(embed=embed)
    await droppxlogs.send(f"User **{member}** (**{member.id}**) has been warned for the reason `{reason}` by **{ctx.author}**")


@client.command()
@commands.has_role(887139696193449990)
async def searchuser(ctx, member : discord.User,):
    await ctx.reply(f'There Username Is `{member}`')



@client.command() #globalx Command
async def globalx(ctx):
    await ctx.send(f"Check Out GlobalX A Discord Global Banning Bot Made By Novy & Scoopy, Wanna Know More About GlobalX? If So Then Type '.info' To Learn More!, https://discord.gg/ZGcvwVgPs9")

@client.command()
async def info(ctx):
    embed = discord.Embed(
    color=ctx.author.color, description="DroppX")
    embed.add_field(name="DroppX", value=f"Need Help? Do '.help'\n", inline=False)
    embed.add_field(name="DroppX Owner's", value=f"Adaph#0001 `842626352950673418`\nNovy#0001 `700871587120939018`", inline=False)
    embed.add_field(name="Invite!", value=f"[Invite Me](https://discord.com/api/oauth2/authorize?client_id=879134628269658154&permissions=2054&scope=bot)", inline=False)
    embed.add_field(name="Support Server!", value=f"[Join!](https://discord.gg/Nbrp28QXpH)", inline=False)
    embed.add_field(name="Vote!", value=f"[Vote!](https://stellarbotlist.com/bot/879134628269658154 'Vote On StellarBot')", inline=False)
    embed.set_author(name=ctx.author, icon_url=ctx.author.avatar_url)
    embed.set_thumbnail(url=ctx.guild.icon_url)
    await ctx.send(embed=embed)

@client.command()
async def server(ctx):
    embed = discord.Embed(
    color=ctx.author.color, description="What Server Is This?")
    embed.add_field(name="Droppx, Adaph", value=f"This Server Is Called {ctx.guild.name}", inline=False)
    embed.set_author(name=ctx.author, icon_url=ctx.author.avatar_url)
    embed.set_thumbnail(url=ctx.guild.icon_url)
    await ctx.send(embed=embed)

@client.command()
async def users(ctx):
    embed = discord.Embed(
    color=ctx.author.color, description="User Count")
    embed.add_field(name="DroppX", value=f"The Current User Count For DroppX Is {len(client.users)}", inline=False)
    embed.set_author(name=ctx.author, icon_url=ctx.author.avatar_url)
    embed.set_thumbnail(url=ctx.guild.icon_url)
    await ctx.send(embed=embed)


@client.command(name="servers")
@commands.has_role(887139696193449990)
async def servers(ctx, amt: int = 0):
  embed = discord.Embed(color=client.user.color)
  embed.set_author(name=f"Servers ({amt} to {amt+60})",
  icon_url=client.user.avatar_url)

  for x in client.guilds[amt: amt+60]:
    embed.add_field(name=x.id, value=f"**Server Name:** {x.name}\n **Server Owner:** {x.owner}\n", inline=False)

  await ctx.send(embed=embed)

@client.command(name="serverinfo")
@commands.has_role(887139696193449990)
async def serverlist(ctx, arg: int):
  guild = client.get_guild(arg)
  channel = random.choice(guild.text_channels)
  invite = await channel.create_invite()
  await ctx.send(f"{guild.name} | {invite} | Owned by {guild.owner}")


@client.command(name="leaveserver")
@commands.is_owner()
async def leaveserver(ctx, arg: int,):
  guild = client.get_guild(arg)
  channel = random.choice(guild.text_channels)
  invite = await channel.create_invite()
  await guild.leave()
  await ctx.send(f"Left Server `{guild.name}` | {invite} | Owned by `{guild.owner}`")

@client.command() #Ban command
@commands.is_owner()
async def blacklistserver(ctx, servertoblacklist=None, *, reason=None):
    
    numbers = string.digits
    ban_id = ''.join(random.sample(numbers, 5))
    
    droppxlogs = client.get_channel(887139696415739970)
    droppxglobalbans = client.get_channel(887139696415739971)
    
    await droppxlogs.send(f"Guild Has Been Blacklisted, For Reason `{reason}`, with the ban ID: `{ban_id}`")
    await ctx.reply(f"Guild Has Been Blacklisted, For Reason `{reason}`, with the ban ID: `{ban_id}`")
    
    with open('guildblacklist.json', 'r') as f:
        load = json.load(f)
        
    
    servers_banned_from = []
        
        
    with open('guildblacklist.json', 'r') as f:
        b = json.load(f)
            
    b[str(ban_id)] = {}
    b[str(ban_id)]["Guild ID"] = int(servertoblacklist)
    b[str(ban_id)]["Reason"] = reason
        
    with open('guildblacklist.json', 'w') as f:
        json.dump(b, f, indent=4)
            
    load[str(servertoblacklist)] = str(reason)
        
    with open('guildblacklist.json', 'w') as f:
         json.dump(load, f, indent=4)
            
    with open('guildblacklist.json', 'r') as f:
         b = json.load(f)
            
    b[str(ban_id)] = {}
    b[str(ban_id)]["Guild ID"] = int(servertoblacklist)
    b[str(ban_id)]["Reason"] = reason
    b[str(ban_id)]["Staff"] = int(ctx.author.id)
        
    with open('guildblacklist.json', 'w') as f:
         json.dump(b, f, indent=4)

    await client.get_guild(int(servertoblacklist)).leave()


@client.command()
async def profilepic(ctx, member : discord.User):
    await ctx.send(f'{member.avatar_url}')

@client.command()
@commands.has_permissions(kick_members=True)
async def mute(ctx, member : discord.Member, *, reason=None):
    role = get(member.guild.roles, name='Muted')
    await member.add_roles(role)
    await ctx.send(f'Muted `{member}` For Reason `{reason}`')

@client.command()
@commands.has_permissions(kick_members=True)
async def unmute(ctx, member : discord.Member, *, reason=None):
    role = get(member.guild.roles, name='Muted')
    await member.remove_roles(role)
    await ctx.send(f'Unmuted `{member}` For Reason `{reason}`')

@client.command()
async def help(ctx):
    embed = discord.Embed(
    color=ctx.author.color, description="Commands")
    embed.add_field(name="User Commands", value=f"droppx\n help\n profilepic\n reportuser\n suggest\n users\n")
    embed.add_field(name="Staff Commands", value=f"kick\n warn\n ban\n mute\n unmute\n")
    embed.add_field(name="DroppX Staff Commands", value=f"globalban\n manualban\n servers\n searchban\n searchuser\n serverinfo\n")
    embed.add_field(name="DroppX Owner Commands", value=f"leaveserver\n blacklistserver\n searchblacklist\n")
    embed.set_author(name=ctx.author, icon_url=ctx.author.avatar_url)
    embed.set_thumbnail(url=ctx.guild.icon_url)
    await ctx.send(embed=embed)

@client.command()
@commands.is_owner()
async def staffrules(ctx):
    embed = discord.Embed(
    color=ctx.author.color, description="Staff Rules/Manual")
    embed.add_field(name="DroppX Staff Rules!", value=f"1. You May NOT Global Ban Anyone For Stupid Reason's Or Pranks Or Joking Around\n 2. You Must Put A Reasoning For Global/Manual Bans Otherwise You Will Get A Staff Strike 3 Staff Strikes And You Get Kicked Off The Staff Team\n", inline=False)
    embed.add_field(name="Global/Manual Ban Reason's", value=f"You May ONLY Manual/Global Ban If These Reasons Occur\n 1. Hard R\n 2. Mass Self Promo/Raiding/Spamming\n 3. Any Slurs\n 4. Any Profanity/Nudity That Is NOT In A NSFW Channel")
    embed.set_author(name=ctx.author, icon_url=ctx.author.avatar_url)
    embed.set_thumbnail(url=ctx.guild.icon_url)
    await ctx.send(embed=embed)

@client.command()
async def responce(ctx):
   await ctx.reply("The Bot Works")

def restart_client(): 
  os.execv(sys.executable, ['python'] + sys.argv)

@client.command(name= 'restart')
@commands.is_owner()
async def restart(ctx):
  await ctx.send("Restarting bot...")
  restart_client()
  await ctx.send('Bot Restarted!')


@client.command()
async def vote(ctx):
    embed = discord.Embed(
    color=ctx.author.color, description="DroppX Voting")
    embed.add_field(name="Vote!", value=f"[Vote!](https://stellarbotlist.com/bot/879134628269658154 'Vote On StellarBot')", inline=False)
    embed.set_author(name=ctx.author, icon_url=ctx.author.avatar_url)
    embed.set_thumbnail(url=ctx.guild.icon_url)
    await ctx.send(embed=embed)


@client.command()
@commands.is_owner()
async def join(ctx):
    channel = ctx.author.voice.channel
    await channel.connect()





client.run('ODc5MTM0NjI4MjY5NjU4MTU0.YSLT7A.TzxYxpCWrhxhhKMdJ1G1oWCGQgg')

# NOVY IS AMAZING - NOVY IS AMAZING - NOVY IS AMAZING <3
# ADAPH IS AMAZING - ADAPH IS AMAZING - ADAPH AMAZING <3
# NOVY IS AMAZING - NOVY IS AMAZING - NOVY IS AMAZING <3
# ADAPH IS AMAZING - ADAPH IS AMAZING - ADAPH AMAZING <3
# NOVY IS AMAZING - NOVY IS AMAZING - NOVY IS AMAZING <3
# ADAPH IS AMAZING - ADAPH IS AMAZING - ADAPH AMAZING <3
# NOVY IS AMAZING - NOVY IS AMAZING - NOVY IS AMAZING <3
# ADAPH IS AMAZING - ADAPH IS AMAZING - ADAPH AMAZING <3
# NOVY IS AMAZING - NOVY IS AMAZING - NOVY IS AMAZING <3
# ADAPH IS AMAZING - ADAPH IS AMAZING - ADAPH AMAZING <3
# NOVY IS AMAZING - NOVY IS AMAZING - NOVY IS AMAZING <3
# ADAPH IS AMAZING - ADAPH IS AMAZING - ADAPH AMAZING <3
# NOVY IS AMAZING - NOVY IS AMAZING - NOVY IS AMAZING <3
# ADAPH IS AMAZING - ADAPH IS AMAZING - ADAPH AMAZING <3
# NOVY IS AMAZING - NOVY IS AMAZING - NOVY IS AMAZING <3
