IF OBJECT_ID(N'dbo.SceneCharacterSuggestions', N'U') IS NULL
BEGIN
    CREATE TABLE dbo.SceneCharacterSuggestions
    (
        SceneCharacterSuggestionID int IDENTITY(1,1) NOT NULL CONSTRAINT PK_SceneCharacterSuggestions PRIMARY KEY,
        SceneID int NOT NULL,
        CharacterID int NOT NULL,
        SuggestionSource nvarchar(50) NOT NULL CONSTRAINT DF_SceneCharacterSuggestions_Source DEFAULT (N'Word Companion'),
        DetectedUtc datetime2 NOT NULL CONSTRAINT DF_SceneCharacterSuggestions_DetectedUtc DEFAULT SYSUTCDATETIME(),
        Status nvarchar(20) NOT NULL CONSTRAINT DF_SceneCharacterSuggestions_Status DEFAULT (N'Pending'),
        Confidence nvarchar(20) NOT NULL CONSTRAINT DF_SceneCharacterSuggestions_Confidence DEFAULT (N'High'),
        Reason nvarchar(200) NULL,
        CreatedByUserID int NOT NULL,
        ReviewedByUserID int NULL,
        ReviewedUtc datetime2 NULL,
        CONSTRAINT FK_SceneCharacterSuggestions_Scenes FOREIGN KEY (SceneID) REFERENCES dbo.Scenes(SceneID),
        CONSTRAINT FK_SceneCharacterSuggestions_Characters FOREIGN KEY (CharacterID) REFERENCES dbo.Characters(CharacterID),
        CONSTRAINT FK_SceneCharacterSuggestions_CreatedByUser FOREIGN KEY (CreatedByUserID) REFERENCES dbo.AppUser(UserID),
        CONSTRAINT FK_SceneCharacterSuggestions_ReviewedByUser FOREIGN KEY (ReviewedByUserID) REFERENCES dbo.AppUser(UserID),
        CONSTRAINT CK_SceneCharacterSuggestions_Status CHECK (Status IN (N'Pending', N'Accepted', N'Rejected', N'Dismissed')),
        CONSTRAINT CK_SceneCharacterSuggestions_Confidence CHECK (Confidence IN (N'High', N'Medium', N'Low'))
    );
END;
GO

IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = N'UX_SceneCharacterSuggestions_Pending' AND object_id = OBJECT_ID(N'dbo.SceneCharacterSuggestions'))
    CREATE UNIQUE INDEX UX_SceneCharacterSuggestions_Pending ON dbo.SceneCharacterSuggestions(SceneID, CharacterID) WHERE Status = N'Pending';
GO

IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = N'IX_SceneCharacterSuggestions_SceneStatus' AND object_id = OBJECT_ID(N'dbo.SceneCharacterSuggestions'))
    CREATE INDEX IX_SceneCharacterSuggestions_SceneStatus ON dbo.SceneCharacterSuggestions(SceneID, Status, CharacterID);
GO

CREATE OR ALTER PROCEDURE dbo.WordCompanion_Runtime_CharacterAlias_List
    @UserID int,
    @ProjectID int,
    @DocumentGuid uniqueidentifier
AS
BEGIN
    SET NOCOUNT ON;

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

    IF NOT EXISTS
    (
        SELECT 1
        FROM dbo.ManuscriptDocuments md
        INNER JOIN dbo.ProjectUserAccess pua ON pua.ProjectID = md.ProjectID
        INNER JOIN dbo.Projects p ON p.ProjectID = md.ProjectID
        WHERE md.DocumentGuid = @DocumentGuid
            AND md.ProjectID = @ProjectID
            AND md.IsActive = 1
            AND p.IsArchived = 0
            AND pua.UserID = @UserID
            AND pua.IsActive = 1
    )
        RETURN;

    SELECT c.CharacterID AS CharacterId,
        c.CharacterName AS Name,
        c.CharacterName AS MatchText,
        CAST(1 AS bit) AS IsDisplayName
    FROM dbo.Characters c
    WHERE c.ProjectID = @ProjectID
        AND c.IsArchived = 0
        AND NULLIF(LTRIM(RTRIM(c.CharacterName)), N'') IS NOT NULL

    UNION ALL

    SELECT c.CharacterID AS CharacterId,
        c.CharacterName AS Name,
        ca.Alias AS MatchText,
        CAST(0 AS bit) AS IsDisplayName
    FROM dbo.Characters c
    INNER JOIN dbo.CharacterAliases ca ON ca.CharacterID = c.CharacterID
    WHERE c.ProjectID = @ProjectID
        AND c.IsArchived = 0
        AND NULLIF(LTRIM(RTRIM(ca.Alias)), N'') IS NOT NULL
    ORDER BY Name, CharacterId, IsDisplayName DESC, MatchText;
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 AND suggestion.Status = N'Pending');

    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
