SET ANSI_NULLS ON;
GO
SET QUOTED_IDENTIFIER ON;
GO

IF OBJECT_ID(N'dbo.SubscriptionLevel', N'U') IS NULL
BEGIN
    CREATE TABLE dbo.SubscriptionLevel
    (
        SubscriptionLevelID int IDENTITY(1,1) NOT NULL CONSTRAINT PK_SubscriptionLevel PRIMARY KEY,
        Name nvarchar(100) NOT NULL,
        DisplayName nvarchar(100) NOT NULL,
        Description nvarchar(500) NULL,
        MaxBooks int NOT NULL,
        MaxChaptersPerBook int NOT NULL,
        MaxScenesPerBook int NOT NULL,
        MaxCharactersPerProject int NOT NULL,
        MaxStorageMB int NOT NULL,
        MaxCollaborators int NOT NULL,
        IsActive bit NOT NULL CONSTRAINT DF_SubscriptionLevel_IsActive DEFAULT 1,
        SortOrder int NOT NULL,
        CreatedDateUTC datetime2 NOT NULL CONSTRAINT DF_SubscriptionLevel_CreatedDateUTC DEFAULT SYSUTCDATETIME(),
        ModifiedDateUTC datetime2 NOT NULL CONSTRAINT DF_SubscriptionLevel_ModifiedDateUTC DEFAULT SYSUTCDATETIME()
    );
END;
GO

IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = N'UX_SubscriptionLevel_Name' AND object_id = OBJECT_ID(N'dbo.SubscriptionLevel'))
    CREATE UNIQUE INDEX UX_SubscriptionLevel_Name ON dbo.SubscriptionLevel(Name);
GO

IF OBJECT_ID(N'dbo.UserSubscription', N'U') IS NULL
BEGIN
    CREATE TABLE dbo.UserSubscription
    (
        UserSubscriptionID int IDENTITY(1,1) NOT NULL CONSTRAINT PK_UserSubscription PRIMARY KEY,
        UserID int NOT NULL,
        SubscriptionLevelID int NOT NULL,
        StartDateUTC datetime2 NOT NULL CONSTRAINT DF_UserSubscription_StartDateUTC DEFAULT SYSUTCDATETIME(),
        EndDateUTC datetime2 NULL,
        IsActive bit NOT NULL CONSTRAINT DF_UserSubscription_IsActive DEFAULT 1,
        IsTrial bit NOT NULL CONSTRAINT DF_UserSubscription_IsTrial DEFAULT 0,
        TrialExpiryDateUTC datetime2 NULL,
        CreatedDateUTC datetime2 NOT NULL CONSTRAINT DF_UserSubscription_CreatedDateUTC DEFAULT SYSUTCDATETIME(),
        ModifiedDateUTC datetime2 NOT NULL CONSTRAINT DF_UserSubscription_ModifiedDateUTC DEFAULT SYSUTCDATETIME(),
        CONSTRAINT FK_UserSubscription_AppUser FOREIGN KEY (UserID) REFERENCES dbo.AppUser(UserID),
        CONSTRAINT FK_UserSubscription_SubscriptionLevel FOREIGN KEY (SubscriptionLevelID) REFERENCES dbo.SubscriptionLevel(SubscriptionLevelID)
    );
END;
GO

IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = N'UX_UserSubscription_User_Active' AND object_id = OBJECT_ID(N'dbo.UserSubscription'))
    CREATE UNIQUE INDEX UX_UserSubscription_User_Active ON dbo.UserSubscription(UserID) WHERE IsActive = 1;
GO

MERGE dbo.SubscriptionLevel AS target
USING (VALUES
    (N'DraftDesk', N'Draft Desk', N'Trial and evaluation.', 2, 75, 300, 75, 100, 0, 1, 10),
    (N'WritingRoom', N'Writing Room', N'Standard subscription for most authors.', 10, 150, 1000, 250, 1024, 1, 1, 20),
    (N'StoryForge', N'Story Forge', N'Professional authors and co-authors.', 30, 200, 2000, 500, 5120, 3, 1, 30),
    (N'AuthorStudio', N'Author Studio', N'Advanced users and writing teams.', 999999, 999999, 999999, 999999, 20480, 10, 1, 40)
) AS source
(
    Name,
    DisplayName,
    Description,
    MaxBooks,
    MaxChaptersPerBook,
    MaxScenesPerBook,
    MaxCharactersPerProject,
    MaxStorageMB,
    MaxCollaborators,
    IsActive,
    SortOrder
)
ON target.Name = source.Name
WHEN MATCHED THEN UPDATE SET
    DisplayName = source.DisplayName,
    Description = source.Description,
    MaxBooks = source.MaxBooks,
    MaxChaptersPerBook = source.MaxChaptersPerBook,
    MaxScenesPerBook = source.MaxScenesPerBook,
    MaxCharactersPerProject = source.MaxCharactersPerProject,
    MaxStorageMB = source.MaxStorageMB,
    MaxCollaborators = source.MaxCollaborators,
    IsActive = source.IsActive,
    SortOrder = source.SortOrder,
    ModifiedDateUTC = SYSUTCDATETIME()
WHEN NOT MATCHED THEN
    INSERT
    (
        Name,
        DisplayName,
        Description,
        MaxBooks,
        MaxChaptersPerBook,
        MaxScenesPerBook,
        MaxCharactersPerProject,
        MaxStorageMB,
        MaxCollaborators,
        IsActive,
        SortOrder
    )
    VALUES
    (
        source.Name,
        source.DisplayName,
        source.Description,
        source.MaxBooks,
        source.MaxChaptersPerBook,
        source.MaxScenesPerBook,
        source.MaxCharactersPerProject,
        source.MaxStorageMB,
        source.MaxCollaborators,
        source.IsActive,
        source.SortOrder
    );
GO

DECLARE @AuthorStudioID int;
SELECT @AuthorStudioID = SubscriptionLevelID
FROM dbo.SubscriptionLevel
WHERE Name = N'AuthorStudio';

IF @AuthorStudioID IS NOT NULL
BEGIN
    INSERT INTO dbo.UserSubscription (UserID, SubscriptionLevelID, StartDateUTC, IsActive, IsTrial)
    SELECT u.UserID, @AuthorStudioID, SYSUTCDATETIME(), 1, 0
    FROM dbo.AppUser u
    WHERE NOT EXISTS
    (
        SELECT 1
        FROM dbo.UserSubscription us
        WHERE us.UserID = u.UserID
            AND us.IsActive = 1
    );
END;
GO

CREATE OR ALTER PROCEDURE dbo.SubscriptionLevel_ListActive
AS
BEGIN
    SET NOCOUNT ON;

    SELECT SubscriptionLevelID, Name, DisplayName, Description, MaxBooks, MaxChaptersPerBook,
        MaxScenesPerBook, MaxCharactersPerProject, MaxStorageMB, MaxCollaborators, IsActive,
        SortOrder, CreatedDateUTC, ModifiedDateUTC
    FROM dbo.SubscriptionLevel
    WHERE IsActive = 1
    ORDER BY SortOrder, DisplayName;
END;
GO

CREATE OR ALTER PROCEDURE dbo.SubscriptionLevel_Get
    @SubscriptionLevelID int
AS
BEGIN
    SET NOCOUNT ON;

    SELECT SubscriptionLevelID, Name, DisplayName, Description, MaxBooks, MaxChaptersPerBook,
        MaxScenesPerBook, MaxCharactersPerProject, MaxStorageMB, MaxCollaborators, IsActive,
        SortOrder, CreatedDateUTC, ModifiedDateUTC
    FROM dbo.SubscriptionLevel
    WHERE SubscriptionLevelID = @SubscriptionLevelID;
END;
GO

CREATE OR ALTER PROCEDURE dbo.UserSubscription_GetCurrent
    @UserID int
AS
BEGIN
    SET NOCOUNT ON;

    SELECT us.UserSubscriptionID, us.UserID, us.SubscriptionLevelID, us.StartDateUTC, us.EndDateUTC,
        us.IsActive, us.IsTrial, us.TrialExpiryDateUTC, us.CreatedDateUTC, us.ModifiedDateUTC,
        sl.Name, sl.DisplayName, sl.Description, sl.MaxBooks, sl.MaxChaptersPerBook,
        sl.MaxScenesPerBook, sl.MaxCharactersPerProject, sl.MaxStorageMB, sl.MaxCollaborators,
        sl.IsActive AS SubscriptionLevelIsActive, sl.SortOrder
    FROM dbo.UserSubscription us
    INNER JOIN dbo.SubscriptionLevel sl ON sl.SubscriptionLevelID = us.SubscriptionLevelID
    WHERE us.UserID = @UserID
        AND us.IsActive = 1
        AND (us.EndDateUTC IS NULL OR us.EndDateUTC > SYSUTCDATETIME());
END;
GO

CREATE OR ALTER PROCEDURE dbo.UserSubscription_AssignDefaultDraftDesk
    @UserID int
AS
BEGIN
    SET NOCOUNT ON;

    DECLARE @DraftDeskID int;
    SELECT @DraftDeskID = SubscriptionLevelID
    FROM dbo.SubscriptionLevel
    WHERE Name = N'DraftDesk';

    IF @DraftDeskID IS NULL
        RETURN;

    IF NOT EXISTS
    (
        SELECT 1
        FROM dbo.UserSubscription
        WHERE UserID = @UserID
            AND IsActive = 1
    )
    BEGIN
        INSERT INTO dbo.UserSubscription (UserID, SubscriptionLevelID, StartDateUTC, IsActive, IsTrial)
        VALUES (@UserID, @DraftDeskID, SYSUTCDATETIME(), 1, 0);
    END;
END;
GO

CREATE OR ALTER PROCEDURE dbo.User_Create
    @Email nvarchar(256),
    @DisplayName nvarchar(200),
    @PasswordHash nvarchar(max),
    @EmailConfirmed bit = 0
AS
BEGIN
    SET NOCOUNT ON;

    INSERT INTO dbo.AppUser (Email, DisplayName, PasswordHash, EmailConfirmed)
    VALUES (@Email, @DisplayName, @PasswordHash, @EmailConfirmed);

    DECLARE @UserID int = SCOPE_IDENTITY();
    EXEC dbo.UserSubscription_AssignDefaultDraftDesk @UserID = @UserID;

    EXEC dbo.User_GetById @UserID = @UserID;
END;
GO
