IF EXISTS (SELECT * FROM sys.schemas WHERE name = 'Tabletop')
    DROP SCHEMA Tabletop;

CREATE SCHEMA Tabletop AUTHORIZATION dbo;

USE Tabletop;

-- -----------------------------------------------------
-- Table 'Fractions'
-- -----------------------------------------------------
CREATE TABLE Fractions 
(
    FractionId INT IDENTITY(1,1),
    Image VARBINARY(MAX) NULL,

    PRIMARY KEY (FractionId)
);

-- -----------------------------------------------------
-- Table 'FractionDescription'
-- -----------------------------------------------------
CREATE TABLE FractionDescription (
    FractionId INT NOT NULL,
    Code VARCHAR(5) NOT NULL DEFAULT '',
    Name VARCHAR(50) NOT NULL,
    ShortName VARCHAR(5) NOT NULL,
    Description TEXT NULL,

    PRIMARY KEY (FractionId, Code),
    FOREIGN KEY (FractionId) REFERENCES Fractions(FractionId) ON DELETE CASCADE ON UPDATE CASCADE
);

-- -----------------------------------------------------
-- Table 'Gamemodes'
-- -----------------------------------------------------
CREATE TABLE Gamemodes 
(
    GamemodeId INT IDENTITY(1,1),
    Image VARBINARY(MAX) NULL,

    PRIMARY KEY (GamemodeId)
);

-- -----------------------------------------------------
-- Table 'GamemodeDescription'
-- -----------------------------------------------------
CREATE TABLE GamemodeDescription (
    GamemodeId INT NOT NULL,
    Code VARCHAR(5) NOT NULL DEFAULT '',
    Name VARCHAR(50) NOT NULL,
    Description TEXT NULL,
    Mechanic TEXT NULL,

    PRIMARY KEY (GamemodeId, Code),
    FOREIGN KEY (GamemodeId) REFERENCES Gamemodes(GamemodeId) ON DELETE CASCADE ON UPDATE CASCADE
);

-- -----------------------------------------------------
-- Table 'Weapons'
-- -----------------------------------------------------
CREATE TABLE Weapons 
(
    WeaponId INT IDENTITY(1,1),
    Attack INT NOT NULL,
    Quality INT NOT NULL,
    Range INT NOT NULL,
    Dices INT NOT NULL,
    Image VARBINARY(MAX) NULL,

    PRIMARY KEY (WeaponId)
);

-- -----------------------------------------------------
-- Table 'WeaponDescription'
-- -----------------------------------------------------
CREATE TABLE WeaponDescription (
    WeaponId INT NOT NULL,
    Code VARCHAR(5) NOT NULL DEFAULT '',
    Name VARCHAR(50) NOT NULL,
    Description TEXT NULL,

    PRIMARY KEY (WeaponId, Code),
    FOREIGN KEY (WeaponId) REFERENCES Weapons(WeaponId) ON DELETE CASCADE ON UPDATE CASCADE
);

-- -----------------------------------------------------
-- Table 'Classes'
-- -----------------------------------------------------
CREATE TABLE Classes (
    ClassId INT NOT NULL,
    Quantity INT NOT NULL,
    
    PRIMARY KEY (ClassId)
);

-- -----------------------------------------------------
-- Table 'ClassDescription'
-- -----------------------------------------------------
CREATE TABLE ClassDescription (
    ClassId INT NOT NULL,
    Code VARCHAR(5) NOT NULL DEFAULT '',
    Name VARCHAR(50) NOT NULL,
    Description TEXT NULL,

    PRIMARY KEY (ClassId, Code),
    FOREIGN KEY (ClassId) REFERENCES Classes(ClassId) ON DELETE CASCADE ON UPDATE CASCADE
);

-- -----------------------------------------------------
-- Table 'Abilities'
-- -----------------------------------------------------
CREATE TABLE Abilities (
    AbilityId INT,
    Quality INT NOT NULL,
    Force INT NOT NULL,
    
    PRIMARY KEY (AbilityId)
);

-- -----------------------------------------------------
-- Table 'AbilityDescription'
-- -----------------------------------------------------
CREATE TABLE AbilityDescription (
    AbilityId INT NOT NULL,
    Code VARCHAR(5) NOT NULL DEFAULT '',
    Name VARCHAR(50) NOT NULL,
    Description TEXT NULL,
    Mechanic TEXT NULL,

    PRIMARY KEY (AbilityId, Code),
    FOREIGN KEY (AbilityId) REFERENCES Abilities(AbilityId) ON DELETE CASCADE ON UPDATE CASCADE
);

-- -----------------------------------------------------
-- Table 'Units'
-- -----------------------------------------------------
CREATE TABLE Units
(
    UnitId INT IDENTITY(1,1),
    FractionId INT NOT NULL,
    ClassId INT NOT NULL,
    TroopQuantity INT NOT NULL,
    Defense INT NOT NULL,
    Moving INT NOT NULL,
    PrimaryWeaponId INT NULL,
    SecondaryWeaponId INT NULL,
    FirstAbilityId INT NULL,
    SecondAbilityId INT NULL,
    Image VARBINARY(MAX) NULL,

    PRIMARY KEY (UnitId),
    FOREIGN KEY (FractionId) REFERENCES Fractions(FractionId) ON DELETE CASCADE ON UPDATE CASCADE,
    FOREIGN KEY (ClassId) REFERENCES Classes(ClassId),
    FOREIGN KEY (PrimaryWeaponId) REFERENCES Weapons(WeaponId),
    FOREIGN KEY (SecondaryWeaponId) REFERENCES Weapons(WeaponId),
    FOREIGN KEY (FirstAbilityId) REFERENCES Abilities(AbilityId),
    FOREIGN KEY (SecondAbilityId) REFERENCES Abilities(AbilityId)
);

-- -----------------------------------------------------
-- Table 'UnitDescription'
-- -----------------------------------------------------
CREATE TABLE UnitDescription (
    UnitId INT NOT NULL,
    Code VARCHAR(5) NOT NULL DEFAULT '',
    Name VARCHAR(50) NOT NULL,
    Description TEXT NULL,
    Mechanic TEXT NULL,

    PRIMARY KEY (UnitId, Code),
    FOREIGN KEY (UnitId) REFERENCES Units(UnitId) ON DELETE CASCADE ON UPDATE CASCADE
);

-- -----------------------------------------------------
-- Table 'Users'
-- -----------------------------------------------------
CREATE TABLE Users (
    UserId INT IDENTITY(1,1) PRIMARY KEY,
    Username VARCHAR(50) NOT NULL,
    DisplayName VARCHAR(100) NOT NULL,
    Description TEXT NULL,
    MainFractionId INT NULL, 
    Password VARCHAR(255) NOT NULL,
    Salt VARCHAR(255) NOT NULL,
    LastLogin DATETIME,
    RegistrationDate TIMESTAMP,
    Image VARBINARY(MAX) NULL,

    PRIMARY KEY (UserId),
    FOREIGN KEY (MainFractionId) REFERENCES Fractions(FractionId)
);

-- -----------------------------------------------------
-- Table 'Permissions'
-- -----------------------------------------------------
CREATE TABLE Permissions (
    PermissionId INT IDENTITY(1,1),
    Identifier VARCHAR(50) NOT NULL,

    PRIMARY KEY (PermissionId)
);

-- -----------------------------------------------------
-- Table 'PermissionDescription'
-- -----------------------------------------------------
CREATE TABLE PermissionDescription (
    PermissionId INT NOT NULL,
    Code VARCHAR(5) NOT NULL DEFAULT '',
    Name VARCHAR(50) NOT NULL,
    Description TEXT NULL,

    PRIMARY KEY (PermissionId, Code),
    FOREIGN KEY (PermissionId) REFERENCES Permissions(PermissionId) ON DELETE CASCADE ON UPDATE CASCADE
);

-- -----------------------------------------------------
-- Table 'UserPermissions'
-- -----------------------------------------------------
CREATE TABLE UserPermissions (
    UserId INT NOT NULL,
    PermissionId INT NOT NULL,

    PRIMARY KEY(UserId, PermissionId),
    FOREIGN KEY (UserId) REFERENCES Users(UserId) ON DELETE CASCADE ON UPDATE CASCADE,
    FOREIGN KEY (PermissionId) REFERENCES Permissions(PermissionId) ON DELETE CASCADE ON UPDATE CASCADE
);

-- -----------------------------------------------------
-- Table 'UserUnits'
-- -----------------------------------------------------
CREATE TABLE UserUnits 
(
    UserId INT NOT NULL,
    UnitId INT NOT NULL,
    Quantity INT NOT NULL,

    PRIMARY KEY (UserId, UnitId),
    FOREIGN KEY (UserId) REFERENCES Users(UserId) ON DELETE CASCADE ON UPDATE CASCADE,
    FOREIGN KEY (UnitId) REFERENCES Units(UnitId) ON DELETE CASCADE ON UPDATE CASCADE
);

-- -----------------------------------------------------
-- Table 'UserFriends'
-- -----------------------------------------------------
CREATE TABLE UserFriends 
(
    UserId INT NOT NULL,
    FriendId INT NOT NULL,

    PRIMARY KEY (UserId, FriendId),
    FOREIGN KEY (UserId) REFERENCES Users(UserId) ON DELETE CASCADE ON UPDATE CASCADE,
    FOREIGN KEY (FriendId) REFERENCES Users(UserId) ON DELETE CASCADE ON UPDATE CASCADE
);

-- -----------------------------------------------------
-- Table 'Games'
-- -----------------------------------------------------
CREATE TABLE Games 
(
    GameId INT IDENTITY(1,1) PRIMARY KEY,
    GamemodeId INT NOT NULL,
    UserId INT NOT NULL,
    SurfaceId INT NOT NULL,
    LayoutId INT NOT NULL,
    Name VARCHAR(50) NOT NULL,
    Force INT NOT NULL,
    NumberOfRounds INT NOT NULL,
    NumberOfTeams INT NOT NULL,
    NumberOfPlayers INT NOT NULL,
    Date DATETIME NOT NULL,

    FOREIGN KEY (GamemodeId) REFERENCES Gamemodes(GamemodeId)
    FOREIGN KEY (SurfaceId) REFERENCES Surfaces(SurfaceId),
    FOREIGN KEY (LayoutId) REFERENCES Layouts(LayoutId)
);

-- -----------------------------------------------------
-- Table 'Players'
-- -----------------------------------------------------
CREATE TABLE Players 
(
    PlayerId INT IDENTITY(1,1) PRIMARY KEY,
    UserId INT NOT NULL,
    GameId INT NOT NULL,
    FractionId INT NULL,
    TeamId INT NOT NULL,
    Color VARCHAR(7) NOT NULL,
    UsedForce INT NOT NULL,
    Points INT NOT NULL DEFAULT 0,
    Order INT NOT NULL,
    StartZone INT NOT NULL,
    NumberOfEliminations INT NOT NULL DEFAULT 0,
    ForcePointsOfEliminations INT NOT NULL DEFAULT 0,
    NumberOfRemainingUnits INT NOT NULL DEFAULT 0,
    OwnForcePointsLeft INT NOT NULL DEFAULT 0,

    FOREIGN KEY (UserId) REFERENCES Users(UserId),
    FOREIGN KEY (GameId) REFERENCES Games(GameId) ON DELETE CASCADE ON UPDATE CASCADE,
    FOREIGN KEY (FractionId) REFERENCES Fractions(FractionId)
);

-- -----------------------------------------------------
-- Table 'PlayerUnits'
-- -----------------------------------------------------
CREATE TABLE PlayerUnits 
(
    PlayerId INT NOT NULL,
    UnitId INT NOT NULL,
    Quantity INT NOT NULL,

    PRIMARY KEY (PlayerId, UnitId),
    FOREIGN KEY (PlayerId) REFERENCES Players(PlayerId) ON DELETE CASCADE ON UPDATE CASCADE,
    FOREIGN KEY (UnitId) REFERENCES Units(UnitId) ON DELETE CASCADE ON UPDATE CASCADE
);

-- -----------------------------------------------------
-- Table 'Teams'
-- -----------------------------------------------------
CREATE TABLE Teams 
(
    TeamId INT IDENTITY(1,1) PRIMARY KEY,
    GameId INT NOT NULL,
    Name VARCHAR(50) NOT NULL,
    Color VARCHAR(7) NOT NULL,
    Points INT NOT NULL DEFAULT 0,
    NumberOfEliminations INT NOT NULL DEFAULT 0,
    ForcePointsOfEliminations INT NOT NULL DEFAULT 0,

    FOREIGN KEY (GameId) REFERENCES Games(GameId) ON DELETE CASCADE ON UPDATE CASCADE
);

-- -----------------------------------------------------
-- Table 'Moves'
-- -----------------------------------------------------
CREATE TABLE Moves 
(
    MoveId INT IDENTITY(1,1) PRIMARY KEY,
    PlayerId INT NOT NULL,
    GameId INT NOT NULL,
    TurnNr INT NOT NULL,
    MoveNr INT NOT NULL,
    StartMove DATETIME,
    EndMove DATETIME,

    FOREIGN KEY (PlayerId) REFERENCES Players(PlayerId) ON DELETE CASCADE ON UPDATE CASCADE,
    FOREIGN KEY (GameId) REFERENCES Games(GameId) ON UPDATE CASCADE,
);

-- -----------------------------------------------------
-- Table 'Captures'
-- -----------------------------------------------------
CREATE TABLE Captures 
(
    CaptureId INT IDENTITY(1,1) PRIMARY KEY,
    MoveId INT NOT NULL,
    CaptureZoneNr INT NOT NULL,
    TeamId INT NOT NULL,
    PlayerId INT NOT NULL,
    NrOfTurns INT NOT NULL,
    PointsReceived INT NOT NULL,

    FOREIGN KEY (MoveId) REFERENCES Moves(MoveId) ON DELETE CASCADE ON UPDATE CASCADE,
    FOREIGN KEY (TeamId) REFERENCES Teams(TeamId),
    FOREIGN KEY (PlayerId) REFERENCES Players(PlayerId)
);

-- -----------------------------------------------------
-- Table 'Eliminations'
-- -----------------------------------------------------
CREATE TABLE Eliminations 
(
    EliminationId INT IDENTITY(1,1) PRIMARY KEY,
    MoveId INT NOT NULL,
    TeamId INT NOT NULL,
    AtkId INT NOT NULL,
    AtkUnitId INT NOT NULL,
    AtkUnitNr INT NOT NULL,
    DefId INT NOT NULL,
    DefUnitId INT NOT NULL,
    DefUnitNr INT NOT NULL,
    EliminationNr INT NOT NULL,
    ForcePointsOfEliminations INT NOT NULL,
    
    FOREIGN KEY (TeamId) REFERENCES Teams(TeamId) ON DELETE CASCADE ON UPDATE CASCADE,
    FOREIGN KEY (MoveId) REFERENCES Moves(MoveId) ON DELETE CASCADE ON UPDATE CASCADE,
    FOREIGN KEY (AtkId) REFERENCES Players(PlayerId) ON DELETE CASCADE ON UPDATE CASCADE,
    FOREIGN KEY (AtkUnitId) REFERENCES Units(UnitId) ON DELETE CASCADE ON UPDATE CASCADE,
    FOREIGN KEY (DefId) REFERENCES Players(PlayerId) ON DELETE CASCADE ON UPDATE CASCADE,
    FOREIGN KEY (DefUnitId) REFERENCES Units(UnitId) ON DELETE CASCADE ON UPDATE CASCADE
);

-- -----------------------------------------------------
-- Table 'Templates'
-- -----------------------------------------------------
CREATE TABLE Templates 
(
    TemplateId INT IDENTITY(1,1) PRIMARY KEY,
    UserId INT NOT NULL,
    FractionId INT NOT NULL,
    Name VARCHAR(50) NOT NULL,
    Force INT NOT NULL, 
    UsedForce INT NOT NULL,

    FOREIGN KEY (UserId) REFERENCES Users(UserId) ON DELETE CASCADE ON UPDATE CASCADE,
    FOREIGN KEY (FractionId) REFERENCES Fractions(FractionId) ON DELETE CASCADE ON UPDATE CASCADE
);

-- -----------------------------------------------------
-- Table 'TemplateUnits'
-- -----------------------------------------------------
CREATE TABLE TemplateUnits 
(
    TemplateId INT PRIMARY KEY,
    UnitId INT PRIMARY KEY,
    Quantity INT NOT NULL,

    PRIMARY KEY (TemplateId, UnitId),
    FOREIGN KEY (TemplateId) REFERENCES Templates(TemplateId) ON DELETE CASCADE ON UPDATE CASCADE,
    FOREIGN KEY (UnitId) REFERENCES Units(UnitId) ON DELETE CASCADE ON UPDATE CASCADE
);

-- -----------------------------------------------------
-- Table 'Layouts'
-- -----------------------------------------------------
CREATE TABLE Layouts 
(
    LayoutId INT IDENTITY(1,1) PRIMARY KEY,
    GamemodeId INT NOT NULL,
    Teams INT NOT NULL,
    Width FLOAT NOT NULL CHECK (Width > 0),
    Height FLOAT NOT NULL CHECK (Height > 0),

    FOREIGN KEY (GamemodeId) REFERENCES Gamemodes(GamemodeId) ON DELETE CASCADE ON UPDATE CASCADE
);

-- -----------------------------------------------------
-- Table 'Zones'
-- -----------------------------------------------------
CREATE TABLE Zones (
    ZoneId INT IDENTITY(1,1) PRIMARY KEY,
    X FLOAT NOT NULL CHECK (X >= 0),
    Y FLOAT NOT NULL CHECK (Y >= 0),
    Width FLOAT NOT NULL CHECK (Width > 0),
    Height FLOAT NOT NULL CHECK (Height > 0)
);

-- -----------------------------------------------------
-- Table 'SetupZones'
-- -----------------------------------------------------
CREATE TABLE SetupZones (
    SetupZoneId INT NOT NULL,
    LayoutId INT NOT NULL,
    ZoneId INT NOT NULL,
    
    PRIMARY KEY (SetupZoneId, LayoutId),
    FOREIGN KEY (ZoneId) REFERENCES Zones(ZoneId) ON DELETE CASCADE ON UPDATE CASCADE,
    FOREIGN KEY (LayoutId) REFERENCES Layouts(LayoutId) ON DELETE CASCADE ON UPDATE CASCADE
);

-- -----------------------------------------------------
-- Table 'CaptureZones'
-- -----------------------------------------------------
CREATE TABLE CaptureZones (
    CaptureZoneId INT NOT NULL,
    LayoutId INT NOT NULL,
    ZoneId INT NOT NULL,
    PointsPerRound INT NOT NULL,
    
    PRIMARY KEY (CaptureZoneId, LayoutId),
    FOREIGN KEY (ZoneId) REFERENCES Zones(ZoneId) ON DELETE CASCADE ON UPDATE CASCADE,
    FOREIGN KEY (LayoutId) REFERENCES Layouts(LayoutId) ON DELETE CASCADE ON UPDATE CASCADE
);

-- -----------------------------------------------------
-- Table 'Surfaces'
-- -----------------------------------------------------
CREATE TABLE Surfaces (
    SurfaceId INT IDENTITY(1,1) PRIMARY KEY,
    Image VARBINARY(MAX) NULL
);

-- -----------------------------------------------------
-- Table 'SurfaceDescription'
-- -----------------------------------------------------
CREATE TABLE SurfaceDescription (
    SurfaceId INT NOT NULL,
    Code VARCHAR(5) NOT NULL DEFAULT '',
    Name VARCHAR(50) NOT NULL,
    Description TEXT NULL

    PRIMARY KEY (SurfaceId, Code),
    FOREIGN KEY (SurfaceId) REFERENCES Surfaces(SurfaceId) ON DELETE CASCADE ON UPDATE CASCADE
);

-- -----------------------------------------------------
-- Table 'ConnectionLogs'
-- -----------------------------------------------------
CREATE TABLE ConnectionLogs 
(
    ConnectionId INT IDENTITY(1,1) PRIMARY KEY,
    IpAddress VARCHAR(50) NOT NULL,
    ConnectionTime DATETIME,
    UserAgent VARCHAR(300) NOT NULL,
    Referrer VARCHAR(300) NOT NULL,
    RequestedUrl VARCHAR(300) NOT NULL,
    Geolocation VARCHAR(100) NOT NULL,
    SessionId VARCHAR(50) NOT NULL,
    StatusCode INT NOT NULL,
    DeviceType VARCHAR(50) NOT NULL,
    OperatingSystem VARCHAR(50) NOT NULL,
);