SET ANSI_NULLS ON;
GO
SET QUOTED_IDENTIFIER ON;
GO

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

    SELECT suggestion.SceneCharacterSuggestionID,
        suggestion.SceneID,
        suggestion.CharacterID,
        ch.CharacterName,
        suggestion.Status,
        suggestion.Confidence,
        suggestion.Reason,
        suggestion.DetectedUtc
    FROM dbo.SceneCharacterSuggestions suggestion
    INNER JOIN dbo.Scenes s ON s.SceneID = suggestion.SceneID
    INNER JOIN dbo.Chapters c ON c.ChapterID = s.ChapterID
    INNER JOIN dbo.Books b ON b.BookID = c.BookID
    INNER JOIN dbo.Projects p ON p.ProjectID = b.ProjectID
    INNER JOIN dbo.ProjectUserAccess pua ON pua.ProjectID = p.ProjectID
    INNER JOIN dbo.Characters ch ON ch.CharacterID = suggestion.CharacterID
    WHERE suggestion.SceneID = @SceneID
        AND suggestion.Status = N'Pending'
        AND s.IsArchived = 0
        AND c.IsArchived = 0
        AND b.IsArchived = 0
        AND p.IsArchived = 0
        AND ch.IsArchived = 0
        AND pua.UserID = @UserID
        AND pua.IsActive = 1
    ORDER BY
        CASE suggestion.Confidence WHEN N'High' THEN 0 WHEN N'Medium' THEN 1 ELSE 2 END,
        ch.CharacterName;
END;
GO

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

    DECLARE @SceneID int;
    DECLARE @CharacterID int;
    DECLARE @SceneCharacterCreated bit = 0;

    SELECT @SceneID = suggestion.SceneID,
        @CharacterID = suggestion.CharacterID
    FROM dbo.SceneCharacterSuggestions suggestion
    INNER JOIN dbo.Scenes s ON s.SceneID = suggestion.SceneID
    INNER JOIN dbo.Chapters c ON c.ChapterID = s.ChapterID
    INNER JOIN dbo.Books b ON b.BookID = c.BookID
    INNER JOIN dbo.Projects p ON p.ProjectID = b.ProjectID
    INNER JOIN dbo.ProjectUserAccess pua ON pua.ProjectID = p.ProjectID
    INNER JOIN dbo.Characters ch ON ch.CharacterID = suggestion.CharacterID AND ch.ProjectID = p.ProjectID
    WHERE suggestion.SceneCharacterSuggestionID = @SceneCharacterSuggestionID
        AND suggestion.Status = N'Pending'
        AND s.IsArchived = 0
        AND c.IsArchived = 0
        AND b.IsArchived = 0
        AND p.IsArchived = 0
        AND ch.IsArchived = 0
        AND pua.UserID = @UserID
        AND pua.IsActive = 1;

    IF @SceneID IS NULL OR @CharacterID IS NULL
        RETURN;

    IF NOT EXISTS (SELECT 1 FROM dbo.SceneCharacters WHERE SceneID = @SceneID AND CharacterID = @CharacterID)
    BEGIN
        INSERT dbo.SceneCharacters (SceneID, CharacterID)
        VALUES (@SceneID, @CharacterID);

        SET @SceneCharacterCreated = 1;
    END;

    UPDATE dbo.SceneCharacterSuggestions
    SET Status = N'Accepted',
        ReviewedByUserID = @UserID,
        ReviewedUtc = SYSUTCDATETIME()
    WHERE SceneCharacterSuggestionID = @SceneCharacterSuggestionID
        AND Status = N'Pending';

    SELECT @SceneCharacterSuggestionID AS SceneCharacterSuggestionID,
        @SceneID AS SceneID,
        @CharacterID AS CharacterID,
        N'Accepted' AS Status,
        @SceneCharacterCreated AS SceneCharacterCreated;
END;
GO

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

    DECLARE @SceneID int;
    DECLARE @CharacterID int;

    SELECT @SceneID = suggestion.SceneID,
        @CharacterID = suggestion.CharacterID
    FROM dbo.SceneCharacterSuggestions suggestion
    INNER JOIN dbo.Scenes s ON s.SceneID = suggestion.SceneID
    INNER JOIN dbo.Chapters c ON c.ChapterID = s.ChapterID
    INNER JOIN dbo.Books b ON b.BookID = c.BookID
    INNER JOIN dbo.Projects p ON p.ProjectID = b.ProjectID
    INNER JOIN dbo.ProjectUserAccess pua ON pua.ProjectID = p.ProjectID
    INNER JOIN dbo.Characters ch ON ch.CharacterID = suggestion.CharacterID AND ch.ProjectID = p.ProjectID
    WHERE suggestion.SceneCharacterSuggestionID = @SceneCharacterSuggestionID
        AND suggestion.Status = N'Pending'
        AND s.IsArchived = 0
        AND c.IsArchived = 0
        AND b.IsArchived = 0
        AND p.IsArchived = 0
        AND ch.IsArchived = 0
        AND pua.UserID = @UserID
        AND pua.IsActive = 1;

    IF @SceneID IS NULL OR @CharacterID IS NULL
        RETURN;

    UPDATE dbo.SceneCharacterSuggestions
    SET Status = N'Rejected',
        ReviewedByUserID = @UserID,
        ReviewedUtc = SYSUTCDATETIME()
    WHERE SceneCharacterSuggestionID = @SceneCharacterSuggestionID
        AND Status = N'Pending';

    SELECT @SceneCharacterSuggestionID AS SceneCharacterSuggestionID,
        @SceneID AS SceneID,
        @CharacterID AS CharacterID,
        N'Rejected' AS Status,
        CAST(0 AS bit) AS SceneCharacterCreated;
END;
GO

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

    IF NOT EXISTS
    (
        SELECT 1
        FROM dbo.Chapters c
        INNER JOIN dbo.Books b ON b.BookID = c.BookID
        INNER JOIN dbo.Projects p ON p.ProjectID = b.ProjectID
        INNER JOIN dbo.ProjectUserAccess pua ON pua.ProjectID = p.ProjectID
        WHERE c.ChapterID = @ChapterID
            AND c.IsArchived = 0
            AND b.IsArchived = 0
            AND p.IsArchived = 0
            AND pua.UserID = @UserID
            AND pua.IsActive = 1
    )
        RETURN;

    SELECT s.SceneID,
        COUNT(suggestion.SceneCharacterSuggestionID) AS PendingSuggestionCount
    FROM dbo.Scenes s
    INNER JOIN dbo.SceneCharacterSuggestions suggestion ON suggestion.SceneID = s.SceneID
    INNER JOIN dbo.Characters ch ON ch.CharacterID = suggestion.CharacterID
    WHERE s.ChapterID = @ChapterID
        AND s.IsArchived = 0
        AND ch.IsArchived = 0
        AND suggestion.Status = N'Pending'
    GROUP BY s.SceneID;
END;
GO

CREATE OR ALTER PROCEDURE dbo.WordCompanion_Runtime_CharacterSuggestions_Create
    @UserID int,
    @DocumentGuid uniqueidentifier,
    @SceneID int,
    @CharacterIds nvarchar(max)
AS
BEGIN
    SET NOCOUNT ON;

    IF @DocumentGuid IS NULL
        OR @DocumentGuid = '00000000-0000-0000-0000-000000000000'
        OR @SceneID <= 0
        RETURN;

    DECLARE @ProjectID int;
    DECLARE @ManuscriptDocumentID int;

    SELECT @ProjectID = b.ProjectID,
        @ManuscriptDocumentID = md.ManuscriptDocumentID
    FROM dbo.Scenes s
    INNER JOIN dbo.Chapters c ON c.ChapterID = s.ChapterID
    INNER JOIN dbo.Books b ON b.BookID = c.BookID
    INNER JOIN dbo.Projects p ON p.ProjectID = b.ProjectID
    INNER JOIN dbo.ManuscriptDocuments md ON md.BookID = b.BookID
    INNER JOIN dbo.ProjectUserAccess pua ON pua.ProjectID = b.ProjectID
    WHERE s.SceneID = @SceneID
        AND s.IsArchived = 0
        AND c.IsArchived = 0
        AND b.IsArchived = 0
        AND p.IsArchived = 0
        AND md.DocumentGuid = @DocumentGuid
        AND md.IsActive = 1
        AND s.IsLinkedToManuscript = 1
        AND s.ManuscriptDocumentID = md.ManuscriptDocumentID
        AND pua.UserID = @UserID
        AND pua.IsActive = 1;

    IF @ProjectID IS NULL
        RETURN;

    DECLARE @Requested table (CharacterID int NOT NULL PRIMARY KEY);

    INSERT @Requested (CharacterID)
    SELECT DISTINCT TRY_CONVERT(int, LTRIM(RTRIM(value)))
    FROM STRING_SPLIT(COALESCE(@CharacterIds, N''), N',')
    WHERE TRY_CONVERT(int, LTRIM(RTRIM(value))) IS NOT NULL
        AND TRY_CONVERT(int, LTRIM(RTRIM(value))) > 0;

    IF NOT EXISTS (SELECT 1 FROM @Requested)
    BEGIN
        SELECT @SceneID AS SceneId,
            0 AS CreatedCount,
            0 AS SkippedCount,
            N'No character suggestions detected.' AS Message;
        RETURN;
    END;

    IF EXISTS
    (
        SELECT 1
        FROM @Requested requested
        WHERE NOT EXISTS
        (
            SELECT 1
            FROM dbo.Characters ch
            WHERE ch.CharacterID = requested.CharacterID
                AND ch.ProjectID = @ProjectID
                AND ch.IsArchived = 0
        )
    )
        RETURN;

    DECLARE @Inserted table (CharacterID int NOT NULL PRIMARY KEY);

    INSERT dbo.SceneCharacterSuggestions
        (SceneID, CharacterID, SuggestionSource, Status, Confidence, Reason, CreatedByUserID)
    OUTPUT inserted.CharacterID INTO @Inserted
    SELECT @SceneID,
        requested.CharacterID,
        N'Word Companion',
        N'Pending',
        N'High',
        N'Detected in manuscript text',
        @UserID
    FROM @Requested requested
    WHERE NOT EXISTS
        (SELECT 1 FROM dbo.SceneCharacters sc WHERE sc.SceneID = @SceneID AND sc.CharacterID = requested.CharacterID)
        AND NOT EXISTS
        (SELECT 1 FROM dbo.SceneCharacterSuggestions suggestion WHERE suggestion.SceneID = @SceneID AND suggestion.CharacterID = requested.CharacterID);

    SELECT @SceneID AS SceneId,
        (SELECT COUNT(*) FROM @Inserted) AS CreatedCount,
        (SELECT COUNT(*) FROM @Requested) - (SELECT COUNT(*) FROM @Inserted) AS SkippedCount,
        CASE
            WHEN (SELECT COUNT(*) FROM @Inserted) = 1 THEN N'1 character suggestion detected.'
            WHEN (SELECT COUNT(*) FROM @Inserted) > 1 THEN CONCAT((SELECT COUNT(*) FROM @Inserted), N' character suggestions detected.')
            ELSE N'No new character suggestions.'
        END AS Message;
END;
GO
