IF OBJECT_ID(N'dbo.SceneAssetSuggestions', N'U') IS NULL
BEGIN
    CREATE TABLE dbo.SceneAssetSuggestions
    (
        SceneAssetSuggestionID int IDENTITY(1,1) NOT NULL CONSTRAINT PK_SceneAssetSuggestions PRIMARY KEY,
        SceneID int NOT NULL,
        AssetID int NOT NULL,
        SuggestionSource nvarchar(50) NOT NULL CONSTRAINT DF_SceneAssetSuggestions_Source DEFAULT (N'Word Companion'),
        DetectedUtc datetime2 NOT NULL CONSTRAINT DF_SceneAssetSuggestions_DetectedUtc DEFAULT SYSUTCDATETIME(),
        Status nvarchar(20) NOT NULL CONSTRAINT DF_SceneAssetSuggestions_Status DEFAULT (N'Pending'),
        Confidence nvarchar(20) NOT NULL CONSTRAINT DF_SceneAssetSuggestions_Confidence DEFAULT (N'High'),
        Reason nvarchar(200) NULL,
        CreatedByUserID int NOT NULL,
        ReviewedByUserID int NULL,
        ReviewedUtc datetime2 NULL,
        CONSTRAINT FK_SceneAssetSuggestions_Scenes FOREIGN KEY (SceneID) REFERENCES dbo.Scenes(SceneID),
        CONSTRAINT FK_SceneAssetSuggestions_StoryAssets FOREIGN KEY (AssetID) REFERENCES dbo.StoryAssets(StoryAssetID),
        CONSTRAINT FK_SceneAssetSuggestions_CreatedByUser FOREIGN KEY (CreatedByUserID) REFERENCES dbo.AppUser(UserID),
        CONSTRAINT FK_SceneAssetSuggestions_ReviewedByUser FOREIGN KEY (ReviewedByUserID) REFERENCES dbo.AppUser(UserID),
        CONSTRAINT CK_SceneAssetSuggestions_Status CHECK (Status IN (N'Pending', N'Accepted', N'Rejected', N'Dismissed')),
        CONSTRAINT CK_SceneAssetSuggestions_Confidence CHECK (Confidence IN (N'High', N'Medium', N'Low'))
    );
END;
GO

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

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

CREATE OR ALTER PROCEDURE dbo.WordCompanion_Runtime_AssetAlias_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 sa.StoryAssetID AS AssetId,
        sa.AssetName AS Name,
        sa.AssetName AS MatchText,
        CAST(1 AS bit) AS IsDisplayName
    FROM dbo.StoryAssets sa
    WHERE sa.ProjectID = @ProjectID
        AND sa.IsArchived = 0
        AND NULLIF(LTRIM(RTRIM(sa.AssetName)), N'') IS NOT NULL

    UNION ALL

    SELECT sa.StoryAssetID AS AssetId,
        sa.AssetName AS Name,
        aa.Alias AS MatchText,
        CAST(0 AS bit) AS IsDisplayName
    FROM dbo.StoryAssets sa
    INNER JOIN dbo.AssetAliases aa ON aa.StoryAssetID = sa.StoryAssetID
    WHERE sa.ProjectID = @ProjectID
        AND sa.IsArchived = 0
        AND NULLIF(LTRIM(RTRIM(aa.Alias)), N'') IS NOT NULL
    ORDER BY Name, AssetId, IsDisplayName DESC, MatchText;
END;
GO

CREATE OR ALTER PROCEDURE dbo.WordCompanion_Runtime_AssetSuggestions_Create
    @UserID int,
    @DocumentGuid uniqueidentifier,
    @SceneID int,
    @AssetIds 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 (AssetID int NOT NULL PRIMARY KEY);

    INSERT @Requested (AssetID)
    SELECT DISTINCT TRY_CONVERT(int, LTRIM(RTRIM(value)))
    FROM STRING_SPLIT(COALESCE(@AssetIds, 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 asset suggestions detected.' AS Message;
        RETURN;
    END;

    IF EXISTS
    (
        SELECT 1
        FROM @Requested requested
        WHERE NOT EXISTS
        (
            SELECT 1
            FROM dbo.StoryAssets sa
            WHERE sa.StoryAssetID = requested.AssetID
                AND sa.ProjectID = @ProjectID
                AND sa.IsArchived = 0
        )
    )
        RETURN;

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

    INSERT dbo.SceneAssetSuggestions
        (SceneID, AssetID, SuggestionSource, Status, Confidence, Reason, CreatedByUserID)
    OUTPUT inserted.AssetID INTO @Inserted
    SELECT @SceneID,
        requested.AssetID,
        N'Word Companion',
        N'Pending',
        N'High',
        N'Detected in manuscript text',
        @UserID
    FROM @Requested requested
    WHERE NOT EXISTS
        (SELECT 1 FROM dbo.AssetEvents ae WHERE ae.SceneID = @SceneID AND ae.StoryAssetID = requested.AssetID)
        AND NOT EXISTS
        (SELECT 1 FROM dbo.SceneAssetLocations sal WHERE sal.SceneID = @SceneID AND sal.StoryAssetID = requested.AssetID)
        AND NOT EXISTS
        (SELECT 1 FROM dbo.AssetCustodyEvents ace WHERE ace.SceneID = @SceneID AND ace.StoryAssetID = requested.AssetID)
        AND NOT EXISTS
        (SELECT 1 FROM dbo.SceneAssetSuggestions suggestion WHERE suggestion.SceneID = @SceneID AND suggestion.AssetID = requested.AssetID);

    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 asset suggestion detected.'
            WHEN (SELECT COUNT(*) FROM @Inserted) > 1 THEN CONCAT((SELECT COUNT(*) FROM @Inserted), N' asset suggestions detected.')
            ELSE N'No new asset suggestions.'
        END AS Message;
END;
GO
