#! .\sbsheriff\scripts\python.exe
import sqlalchemy as sqla
from sqlalchemy.orm import declarative_base, relationship, scoped_session, sessionmaker

engine = sqla.create_engine('postgresql://strix:unnipus1213@192.168.1.2:5432/sbdb')

Base = declarative_base()

class World(Base):
    __tablename__ = 'world'
    id = sqla.Column(sqla.Integer, primary_key=True)
    short_name = sqla.Column(sqla.String(50))
    world_name = sqla.Column(sqla.String(50))
    shk_id = sqla.Column(sqla.Integer)
    age = sqla.Column(sqla.Integer)
    ended = sqla.Column(sqla.Boolean)
    hoh_scraped = sqla.Column(sqla.Boolean)
    servers = relationship('Server',back_populates='worlds') #Checked
    hoh_entries = relationship('Hall_Of_Heroes',back_populates='world') #Checked
    house_histories = relationship('House_History',back_populates='world') #Checked

class Player(Base): 
    __tablename__ = 'player'
    id = sqla.Column(sqla.Integer, primary_key=True)
    player_name = sqla.Column(sqla.String(100))
    user_id = sqla.Column(sqla.Integer,sqla.ForeignKey('user.id'))

    user = relationship('User',back_populates='player') #Checked
    vm_entries = relationship('Vm_Entry',back_populates='player') #Checked
    hoh_entries = relationship("Hall_Of_Heroes",back_populates="player") #Checked
    house_history = relationship("House_History",back_populates="player") #Checked
    castle_designs = relationship("Player_Castle_Designs",back_populates="player") #Checked

server_user = sqla.Table(
    "association",
    Base.metadata,
    sqla.Column("server_id",sqla.ForeignKey("server.id")),
    sqla.Column("user_id",sqla.ForeignKey("user.id")),
)

class Server(Base):
    __tablename__ = 'server'
    id = sqla.Column(sqla.Integer, primary_key=True)
    server_name = sqla.Column(sqla.Integer)
    discord_guild_id = sqla.Column(sqla.BigInteger,unique=True)
    world_id = sqla.Column(sqla.Integer,sqla.ForeignKey('world.id'))

    worlds = relationship("World",back_populates="servers") #Checked
    users = relationship("User",secondary=server_user,back_populates='servers') #Checked

class User(Base):
    __tablename__ = 'user'
    id = sqla.Column(sqla.Integer, primary_key=True)
    discord_id = sqla.Column(sqla.BigInteger,unique=True)
    display_name = sqla.Column(sqla.String(50))
    servers = relationship("Server",secondary=server_user,back_populates='users') #Checked

    #Parent in user prefferences relationship
    user_prefference =  relationship("User_Prefference",back_populates="user",uselist=False) #Checked

    #Parent in user player relationship
    player = relationship('Player',back_populates='user',uselist=False) #Checked

class User_Prefference(Base):
    __tablename__ = 'user_prefference'
    id = sqla.Column(sqla.Integer,primary_key=True)
    preffered_pikes = sqla.Column(sqla.Integer)
    preffered_archers = sqla.Column(sqla.Integer)
    user_id = sqla.Column(sqla.Integer,sqla.ForeignKey('user.id'))
    user = relationship('User',back_populates='user_prefference') #Checked

class Advert_Type(Base):
    __tablename__ = 'advert_type'
    id = sqla.Column(sqla.Integer, primary_key=True)
    advert_name = sqla.Column(sqla.String(50))
    adverts = relationship("Advert",back_populates="advert_type") #Checked

class Advert(Base):
    __tablename__ = 'advert'
    advert_id = sqla.Column(sqla.Integer, primary_key=True)
    advert_type_id = sqla.Column(sqla.SmallInteger, sqla.ForeignKey("advert_type.id"))
    channel_id = sqla.Column(sqla.BigInteger)
    message_id = sqla.Column(sqla.BigInteger)
    advert_type = relationship("Advert_Type",back_populates="adverts") #Checked

class Vm_Entry(Base):
    __tablename__ = 'vm_entry'
    id = sqla.Column(sqla.Integer, primary_key=True)
    added_by_user_id = sqla.Column(sqla.Integer, sqla.ForeignKey("user.id"))
    player_id = sqla.Column(sqla.Integer, sqla.ForeignKey("player.id"))
    server_id = sqla.Column(sqla.Integer, sqla.ForeignKey("server.id"))
    time_added = sqla.Column(sqla.Time)
    time_ended = sqla.Column(sqla.Time,nullable=True)   
    player = relationship("Player",back_populates="vm_entries") #Checked

class House(Base):
    __tablename__ = 'house'
    id = sqla.Column(sqla.Integer, primary_key=True)
    color = sqla.Column(sqla.String)
    emoji = sqla.Column(sqla.String)
    relationships = relationship("House_Relationship",back_populates="house")

class Relationship_State(Base):
    __tablename__ = 'relationship_state'
    id = sqla.Column(sqla.Integer, primary_key=True)
    relationship_name = sqla.Column(sqla.String(50))
    alignment = sqla.Column(sqla.Integer)
    house_relations = relationship('House_Relationship',back_populates='relationship_state') #Checked
    player_relations = relationship('Player_Relationship',back_populates='relationship_state')#Checked

class House_Relationship(Base):
    __tablename__ = 'house_relationship'
    id = sqla.Column(sqla.Integer, primary_key=True)

    server_id = sqla.Column(sqla.Integer, sqla.ForeignKey("server.id"))
    house_id = sqla.Column(sqla.Integer, sqla.ForeignKey("house.id"))
    house = relationship("House",back_populates="relationships") #Checked
    relationship_state_id = sqla.Column(sqla.Integer, sqla.ForeignKey("relationship_state.id"))
    relationship_state = relationship("Relationship_State",back_populates="house_relations")  #Checked

class Player_Relationship(Base):
    __tablename__ = 'player_relationship'
    id = sqla.Column(sqla.Integer, primary_key=True)
    note = sqla.Column(sqla.String(100),nullable=True)

    server_id = sqla.Column(sqla.Integer, sqla.ForeignKey("server.id"))
    player_id = sqla.Column(sqla.Integer, sqla.ForeignKey("player.id"))
    relationship_state_id = sqla.Column(sqla.Integer, sqla.ForeignKey("relationship_state.id"))
    relationship_state = relationship('Relationship_State',back_populates='player_relations')#Checked

class Hoh_Rank(Base):
    __tablename__ = 'hoh_rank'
    id = sqla.Column(sqla.Integer, primary_key=True)
    rank_name = sqla.Column(sqla.String(50))
    hoh_entries = relationship("Hall_Of_Heroes",back_populates="rank") #Checked

class Hall_Of_Heroes(Base):
    __tablename__ = 'hall_of_heroes'
    id = sqla.Column(sqla.Integer,primary_key=True)
    player_id = sqla.Column(sqla.Integer,sqla.ForeignKey('player.id'))
    hoh_rank_id = sqla.Column(sqla.Integer,sqla.ForeignKey('hoh_rank.id'))
    world_id = sqla.Column(sqla.Integer,sqla.ForeignKey('world.id'))

    #Parent in player hoh relationship
    player = relationship('Player',back_populates='hoh_entries') #Checked
    rank = relationship('Hoh_Rank',back_populates='hoh_entries') #Checked
    world = relationship('World',back_populates='hoh_entries') #Checked

class Player_Castle_Designs(Base):
    __tablename__ = "player_castle_designs"
    id = sqla.Column(sqla.Integer,primary_key=True)
    path = sqla.Column(sqla.String)
    player_id = sqla.Column(sqla.Integer,sqla.ForeignKey("player.id"))
    server_id = sqla.Column(sqla.Integer,sqla.ForeignKey("server.id"))

    player = relationship("Player", back_populates="castle_designs") #Checked
    server = relationship("Server") #Checked

class House_History(Base):
    __tablename__ = 'house_history'
    id = sqla.Column(sqla.Integer,primary_key=True)
    date = sqla.Column(sqla.Date)

    player_id =  sqla.Column(sqla.Integer,sqla.ForeignKey("player.id"))
    world_id = sqla.Column(sqla.Integer,sqla.ForeignKey("world.id"))
    house_id = sqla.Column(sqla.Integer,sqla.ForeignKey("house.id"))
    player = relationship("Player",back_populates='house_history') #Checked
    world = relationship("World",back_populates='house_histories') #Checked
    house = relationship("House") #Checked

class Liegelord_Requests(Base):
    __tablename__ = 'liegelord_requests'
    id = sqla.Column(sqla.Integer,primary_key=True)
    village_id = sqla.Column(sqla.SmallInteger)
    confirm_message_id = sqla.Column(sqla.BigInteger)

    server_id = sqla.Column(sqla.Integer,sqla.ForeignKey("server.id"))
    request_user_id = sqla.Column(sqla.Integer,sqla.ForeignKey('user.id'))
    fulfilled_user_id = sqla.Column(sqla.Integer,sqla.ForeignKey('user.id'))
    server = relationship("Server") #Checked
    request_user = relationship("User",foreign_keys=[request_user_id])
    fulfilled_user= relationship("User",foreign_keys=[fulfilled_user_id])

def create_session():
    session = scoped_session(sessionmaker(bind=engine))
    return session