SET ANSI_NULLS ON;
GO
SET QUOTED_IDENTIFIER ON;
GO

IF NOT EXISTS (SELECT 1 FROM sys.tables WHERE name = N'FeatureRequests' AND schema_id = SCHEMA_ID(N'dbo'))
BEGIN
    CREATE TABLE dbo.FeatureRequests
    (
        FeatureRequestID int IDENTITY(1,1) NOT NULL CONSTRAINT PK_FeatureRequests PRIMARY KEY,
        UserID int NOT NULL,
        Title nvarchar(200) NOT NULL,
        Description nvarchar(max) NOT NULL,
        AppArea nvarchar(100) NULL,
        Importance nvarchar(50) NULL,
        Status nvarchar(50) NOT NULL CONSTRAINT DF_FeatureRequests_Status DEFAULT N'New',
        IsPublicCandidate bit NOT NULL CONSTRAINT DF_FeatureRequests_IsPublicCandidate DEFAULT 0,
        AdminNotes nvarchar(max) NULL,
        CreatedUtc datetime2 NOT NULL CONSTRAINT DF_FeatureRequests_CreatedUtc DEFAULT sysutcdatetime(),
        UpdatedUtc datetime2 NOT NULL CONSTRAINT DF_FeatureRequests_UpdatedUtc DEFAULT sysutcdatetime(),
        ClosedUtc datetime2 NULL,
        ShippedUtc datetime2 NULL,
        CONSTRAINT FK_FeatureRequests_AppUser FOREIGN KEY (UserID) REFERENCES dbo.AppUser(UserID)
    );
END;
GO

IF NOT EXISTS (SELECT 1 FROM sys.tables WHERE name = N'FeatureRequestMessages' AND schema_id = SCHEMA_ID(N'dbo'))
BEGIN
    CREATE TABLE dbo.FeatureRequestMessages
    (
        FeatureRequestMessageID int IDENTITY(1,1) NOT NULL CONSTRAINT PK_FeatureRequestMessages PRIMARY KEY,
        FeatureRequestID int NOT NULL,
        UserID int NULL,
        IsAdmin bit NOT NULL CONSTRAINT DF_FeatureRequestMessages_IsAdmin DEFAULT 0,
        MessageBody nvarchar(max) NOT NULL,
        CreatedUtc datetime2 NOT NULL CONSTRAINT DF_FeatureRequestMessages_CreatedUtc DEFAULT sysutcdatetime(),
        CONSTRAINT FK_FeatureRequestMessages_FeatureRequests FOREIGN KEY (FeatureRequestID) REFERENCES dbo.FeatureRequests(FeatureRequestID),
        CONSTRAINT FK_FeatureRequestMessages_AppUser FOREIGN KEY (UserID) REFERENCES dbo.AppUser(UserID)
    );
END;
GO

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

IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = N'IX_FeatureRequests_Status' AND object_id = OBJECT_ID(N'dbo.FeatureRequests'))
    CREATE INDEX IX_FeatureRequests_Status ON dbo.FeatureRequests(Status);
GO

IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = N'IX_FeatureRequests_CreatedUtc' AND object_id = OBJECT_ID(N'dbo.FeatureRequests'))
    CREATE INDEX IX_FeatureRequests_CreatedUtc ON dbo.FeatureRequests(CreatedUtc);
GO

IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = N'IX_FeatureRequestMessages_FeatureRequestID' AND object_id = OBJECT_ID(N'dbo.FeatureRequestMessages'))
    CREATE INDEX IX_FeatureRequestMessages_FeatureRequestID ON dbo.FeatureRequestMessages(FeatureRequestID);
GO

IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = N'IX_FeatureRequestMessages_CreatedUtc' AND object_id = OBJECT_ID(N'dbo.FeatureRequestMessages'))
    CREATE INDEX IX_FeatureRequestMessages_CreatedUtc ON dbo.FeatureRequestMessages(CreatedUtc);
GO

CREATE OR ALTER PROCEDURE dbo.FeatureRequest_Create
    @UserID int,
    @Title nvarchar(200),
    @Description nvarchar(max),
    @AppArea nvarchar(100) = NULL,
    @Importance nvarchar(50) = NULL
AS
BEGIN
    SET NOCOUNT ON;

    INSERT INTO dbo.FeatureRequests (UserID, Title, Description, AppArea, Importance)
    VALUES (@UserID, @Title, @Description, NULLIF(@AppArea, N''), NULLIF(@Importance, N''));

    DECLARE @FeatureRequestID int = SCOPE_IDENTITY();

    EXEC dbo.FeatureRequest_GetForUser @FeatureRequestID = @FeatureRequestID, @UserID = @UserID;
END;
GO

CREATE OR ALTER PROCEDURE dbo.FeatureRequest_GetForUser
    @FeatureRequestID int,
    @UserID int
AS
BEGIN
    SET NOCOUNT ON;

    SELECT fr.FeatureRequestID, fr.UserID, au.Email AS UserEmail, au.DisplayName AS UserDisplayName,
        fr.Title, fr.Description, fr.AppArea, fr.Importance, fr.Status, fr.IsPublicCandidate,
        fr.AdminNotes, fr.CreatedUtc, fr.UpdatedUtc, fr.ClosedUtc, fr.ShippedUtc,
        latest.LatestActivityUtc
    FROM dbo.FeatureRequests fr
    INNER JOIN dbo.AppUser au ON au.UserID = fr.UserID
    OUTER APPLY
    (
        SELECT MAX(frm.CreatedUtc) AS LatestActivityUtc
        FROM dbo.FeatureRequestMessages frm
        WHERE frm.FeatureRequestID = fr.FeatureRequestID
    ) latest
    WHERE fr.FeatureRequestID = @FeatureRequestID
        AND fr.UserID = @UserID;
END;
GO

CREATE OR ALTER PROCEDURE dbo.FeatureRequest_GetForAdmin
    @FeatureRequestID int
AS
BEGIN
    SET NOCOUNT ON;

    SELECT fr.FeatureRequestID, fr.UserID, au.Email AS UserEmail, au.DisplayName AS UserDisplayName,
        fr.Title, fr.Description, fr.AppArea, fr.Importance, fr.Status, fr.IsPublicCandidate,
        fr.AdminNotes, fr.CreatedUtc, fr.UpdatedUtc, fr.ClosedUtc, fr.ShippedUtc,
        latest.LatestActivityUtc
    FROM dbo.FeatureRequests fr
    INNER JOIN dbo.AppUser au ON au.UserID = fr.UserID
    OUTER APPLY
    (
        SELECT MAX(frm.CreatedUtc) AS LatestActivityUtc
        FROM dbo.FeatureRequestMessages frm
        WHERE frm.FeatureRequestID = fr.FeatureRequestID
    ) latest
    WHERE fr.FeatureRequestID = @FeatureRequestID;
END;
GO

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

    SELECT fr.FeatureRequestID, fr.UserID, au.Email AS UserEmail, au.DisplayName AS UserDisplayName,
        fr.Title, fr.Description, fr.AppArea, fr.Importance, fr.Status, fr.IsPublicCandidate,
        CAST(NULL AS nvarchar(max)) AS AdminNotes, fr.CreatedUtc, fr.UpdatedUtc, fr.ClosedUtc, fr.ShippedUtc,
        latest.LatestActivityUtc
    FROM dbo.FeatureRequests fr
    INNER JOIN dbo.AppUser au ON au.UserID = fr.UserID
    OUTER APPLY
    (
        SELECT MAX(frm.CreatedUtc) AS LatestActivityUtc
        FROM dbo.FeatureRequestMessages frm
        WHERE frm.FeatureRequestID = fr.FeatureRequestID
    ) latest
    WHERE fr.UserID = @UserID
    ORDER BY fr.UpdatedUtc DESC, fr.FeatureRequestID DESC;
END;
GO

CREATE OR ALTER PROCEDURE dbo.FeatureRequest_ListForAdmin
    @Status nvarchar(50) = NULL
AS
BEGIN
    SET NOCOUNT ON;

    SELECT fr.FeatureRequestID, fr.UserID, au.Email AS UserEmail, au.DisplayName AS UserDisplayName,
        fr.Title, fr.Description, fr.AppArea, fr.Importance, fr.Status, fr.IsPublicCandidate,
        fr.AdminNotes, fr.CreatedUtc, fr.UpdatedUtc, fr.ClosedUtc, fr.ShippedUtc,
        latest.LatestActivityUtc
    FROM dbo.FeatureRequests fr
    INNER JOIN dbo.AppUser au ON au.UserID = fr.UserID
    OUTER APPLY
    (
        SELECT MAX(frm.CreatedUtc) AS LatestActivityUtc
        FROM dbo.FeatureRequestMessages frm
        WHERE frm.FeatureRequestID = fr.FeatureRequestID
    ) latest
    WHERE @Status IS NULL OR fr.Status = @Status
    ORDER BY fr.UpdatedUtc DESC, fr.FeatureRequestID DESC;
END;
GO

CREATE OR ALTER PROCEDURE dbo.FeatureRequest_UpdateStatus
    @FeatureRequestID int,
    @Status nvarchar(50),
    @IsPublicCandidate bit = NULL
AS
BEGIN
    SET NOCOUNT ON;

    UPDATE dbo.FeatureRequests
    SET Status = @Status,
        IsPublicCandidate = COALESCE(@IsPublicCandidate, IsPublicCandidate),
        UpdatedUtc = sysutcdatetime(),
        ClosedUtc = CASE WHEN @Status IN (N'Shipped', N'Not Planned') THEN COALESCE(ClosedUtc, sysutcdatetime()) ELSE NULL END,
        ShippedUtc = CASE WHEN @Status = N'Shipped' THEN COALESCE(ShippedUtc, sysutcdatetime()) ELSE NULL END
    WHERE FeatureRequestID = @FeatureRequestID;

    EXEC dbo.FeatureRequest_GetForAdmin @FeatureRequestID = @FeatureRequestID;
END;
GO

CREATE OR ALTER PROCEDURE dbo.FeatureRequest_UpdateAdminNotes
    @FeatureRequestID int,
    @AdminNotes nvarchar(max) = NULL
AS
BEGIN
    SET NOCOUNT ON;

    UPDATE dbo.FeatureRequests
    SET AdminNotes = NULLIF(@AdminNotes, N''),
        UpdatedUtc = sysutcdatetime()
    WHERE FeatureRequestID = @FeatureRequestID;

    EXEC dbo.FeatureRequest_GetForAdmin @FeatureRequestID = @FeatureRequestID;
END;
GO

CREATE OR ALTER PROCEDURE dbo.FeatureRequestMessage_Add
    @FeatureRequestID int,
    @UserID int = NULL,
    @IsAdmin bit = 0,
    @MessageBody nvarchar(max)
AS
BEGIN
    SET NOCOUNT ON;

    IF NOT EXISTS (SELECT 1 FROM dbo.FeatureRequests WHERE FeatureRequestID = @FeatureRequestID)
        RETURN;

    INSERT INTO dbo.FeatureRequestMessages (FeatureRequestID, UserID, IsAdmin, MessageBody)
    VALUES (@FeatureRequestID, @UserID, @IsAdmin, @MessageBody);

    UPDATE dbo.FeatureRequests
    SET UpdatedUtc = sysutcdatetime()
    WHERE FeatureRequestID = @FeatureRequestID;

    SELECT frm.FeatureRequestMessageID, frm.FeatureRequestID, frm.UserID, au.Email AS UserEmail,
        au.DisplayName AS UserDisplayName, frm.IsAdmin, frm.MessageBody, frm.CreatedUtc
    FROM dbo.FeatureRequestMessages frm
    LEFT JOIN dbo.AppUser au ON au.UserID = frm.UserID
    WHERE frm.FeatureRequestMessageID = SCOPE_IDENTITY();
END;
GO

CREATE OR ALTER PROCEDURE dbo.FeatureRequestMessage_List
    @FeatureRequestID int
AS
BEGIN
    SET NOCOUNT ON;

    SELECT frm.FeatureRequestMessageID, frm.FeatureRequestID, frm.UserID, au.Email AS UserEmail,
        au.DisplayName AS UserDisplayName, frm.IsAdmin, frm.MessageBody, frm.CreatedUtc
    FROM dbo.FeatureRequestMessages frm
    LEFT JOIN dbo.AppUser au ON au.UserID = frm.UserID
    WHERE frm.FeatureRequestID = @FeatureRequestID
    ORDER BY frm.CreatedUtc ASC, frm.FeatureRequestMessageID ASC;
END;
GO
