SET ANSI_NULLS ON;
GO
SET QUOTED_IDENTIFIER ON;
GO

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

    DECLARE @ProjectID int;
    DECLARE @BookID int;

    SELECT @ProjectID = b.ProjectID, @BookID = b.BookID
    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.ProjectUserAccess pua ON pua.ProjectID = p.ProjectID
    WHERE s.SceneID = @SceneID
        AND s.IsArchived = 0
        AND c.IsArchived = 0
        AND b.IsArchived = 0
        AND p.IsArchived = 0
        AND pua.UserID = @UserID
        AND pua.IsActive = 1;

    IF @ProjectID IS NULL
        RETURN;

    SELECT s.SceneID, c.ChapterID, c.ChapterTitle, s.SceneTitle,
        sw.ActualWordCount AS ActualWords,
        sw.EstimatedWordCount AS EstimatedWords,
        s.ScenePurposeNotes AS WritingBrief,
        COALESCE(sw.IsBlocked, 0) AS Blocked,
        sw.BlockedReason,
        s.PrimaryLocationID AS PrimaryLocationId
    FROM dbo.Scenes s
    INNER JOIN dbo.Chapters c ON c.ChapterID = s.ChapterID
    LEFT JOIN dbo.SceneWorkflow sw ON sw.SceneID = s.SceneID
    WHERE s.SceneID = @SceneID;

    SELECT ch.CharacterID, ch.CharacterName AS Name,
        CAST(CASE WHEN EXISTS (SELECT 1 FROM dbo.SceneCharacters sc WHERE sc.SceneID = @SceneID AND sc.CharacterID = ch.CharacterID) THEN 1 ELSE 0 END AS bit) AS Linked
    FROM dbo.Characters ch
    WHERE ch.ProjectID = @ProjectID
        AND ch.IsArchived = 0
    ORDER BY ch.CharacterName, ch.CharacterID;

    SELECT sa.StoryAssetID AS AssetId, sa.AssetName AS Name,
        CAST(CASE WHEN EXISTS (SELECT 1 FROM dbo.AssetEvents ae WHERE ae.SceneID = @SceneID AND ae.StoryAssetID = sa.StoryAssetID)
            OR EXISTS (SELECT 1 FROM dbo.SceneAssetLocations sal WHERE sal.SceneID = @SceneID AND sal.StoryAssetID = sa.StoryAssetID)
            THEN 1 ELSE 0 END AS bit) AS Linked
    FROM dbo.StoryAssets sa
    WHERE sa.ProjectID = @ProjectID
        AND sa.IsArchived = 0
    ORDER BY sa.AssetName, sa.StoryAssetID;

    SELECT l.LocationID, l.LocationName AS Name,
        CAST(CASE WHEN EXISTS (SELECT 1 FROM dbo.Scenes s WHERE s.SceneID = @SceneID AND s.PrimaryLocationID = l.LocationID) THEN 1 ELSE 0 END AS bit) AS Linked
    FROM dbo.Locations l
    WHERE l.ProjectID = @ProjectID
        AND l.IsArchived = 0
    ORDER BY l.LocationName, l.LocationID;
END;
GO

CREATE OR ALTER PROCEDURE dbo.WordCompanion_SceneLinks_Update
    @SceneID int,
    @UserID int,
    @CharacterIds nvarchar(max) = NULL,
    @AssetIds nvarchar(max) = NULL,
    @LocationIds nvarchar(max) = NULL,
    @PrimaryLocationId int = NULL
AS
BEGIN
    SET NOCOUNT ON;

    DECLARE @ProjectID int;
    DECLARE @UsedAssetEventTypeID int;
    SELECT @ProjectID = b.ProjectID
    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.ProjectUserAccess pua ON pua.ProjectID = p.ProjectID
    WHERE s.SceneID = @SceneID
        AND s.IsArchived = 0
        AND c.IsArchived = 0
        AND b.IsArchived = 0
        AND p.IsArchived = 0
        AND pua.UserID = @UserID
        AND pua.IsActive = 1;

    IF @ProjectID IS NULL
        RETURN;

    SELECT TOP (1) @UsedAssetEventTypeID = AssetEventTypeID
    FROM dbo.AssetEventTypes
    WHERE TypeName = N'Used' AND IsActive = 1
    ORDER BY SortOrder, AssetEventTypeID;

    IF @UsedAssetEventTypeID IS NULL
        SELECT TOP (1) @UsedAssetEventTypeID = AssetEventTypeID
        FROM dbo.AssetEventTypes
        WHERE IsActive = 1
        ORDER BY SortOrder, AssetEventTypeID;

    IF @UsedAssetEventTypeID IS NULL
        RETURN;

    DECLARE @Characters TABLE (ID int PRIMARY KEY);
    DECLARE @Assets TABLE (ID int PRIMARY KEY);

    INSERT @Characters (ID)
    SELECT DISTINCT TRY_CONVERT(int, LTRIM(RTRIM(value)))
    FROM STRING_SPLIT(ISNULL(@CharacterIds, N''), N',')
    WHERE NULLIF(LTRIM(RTRIM(value)), N'') IS NOT NULL
        AND TRY_CONVERT(int, LTRIM(RTRIM(value))) IS NOT NULL;

    INSERT @Assets (ID)
    SELECT DISTINCT TRY_CONVERT(int, LTRIM(RTRIM(value)))
    FROM STRING_SPLIT(ISNULL(@AssetIds, N''), N',')
    WHERE NULLIF(LTRIM(RTRIM(value)), N'') IS NOT NULL
        AND TRY_CONVERT(int, LTRIM(RTRIM(value))) IS NOT NULL;

    IF EXISTS (SELECT 1 FROM @Characters requested WHERE requested.ID <= 0 OR NOT EXISTS (SELECT 1 FROM dbo.Characters c WHERE c.CharacterID = requested.ID AND c.ProjectID = @ProjectID AND c.IsArchived = 0))
        RETURN;
    IF EXISTS (SELECT 1 FROM @Assets requested WHERE requested.ID <= 0 OR NOT EXISTS (SELECT 1 FROM dbo.StoryAssets sa WHERE sa.StoryAssetID = requested.ID AND sa.ProjectID = @ProjectID AND sa.IsArchived = 0))
        RETURN;
    IF @PrimaryLocationId IS NOT NULL
        AND NOT EXISTS (SELECT 1 FROM dbo.Locations l WHERE l.LocationID = @PrimaryLocationId AND l.ProjectID = @ProjectID AND l.IsArchived = 0)
        RETURN;

    UPDATE dbo.Scenes
    SET PrimaryLocationID = @PrimaryLocationId,
        UpdatedDate = SYSUTCDATETIME()
    WHERE SceneID = @SceneID;

    DELETE sc
    FROM dbo.SceneCharacters sc
    WHERE sc.SceneID = @SceneID
        AND NOT EXISTS (SELECT 1 FROM @Characters requested WHERE requested.ID = sc.CharacterID)
        AND sc.RoleInSceneTypeID IS NULL
        AND sc.PresenceTypeID IS NULL
        AND sc.LocationID IS NULL
        AND sc.EntryLocationID IS NULL
        AND sc.ExitLocationID IS NULL
        AND sc.AppearanceNotes IS NULL
        AND sc.OutfitDescription IS NULL
        AND sc.PhysicalCondition IS NULL
        AND sc.EmotionalState IS NULL
        AND sc.KnowledgeNotes IS NULL;

    INSERT dbo.SceneCharacters (SceneID, CharacterID)
    SELECT @SceneID, requested.ID
    FROM @Characters requested
    WHERE NOT EXISTS (SELECT 1 FROM dbo.SceneCharacters sc WHERE sc.SceneID = @SceneID AND sc.CharacterID = requested.ID);

    DELETE ae
    FROM dbo.AssetEvents ae
    WHERE ae.SceneID = @SceneID
        AND ae.AssetEventTypeID = @UsedAssetEventTypeID
        AND ae.EventTitle = N'Used'
        AND ae.EventDescription IS NULL
        AND ae.FromStateID IS NULL
        AND ae.ToStateID IS NULL
        AND NOT EXISTS (SELECT 1 FROM @Assets requested WHERE requested.ID = ae.StoryAssetID);

    DELETE sal
    FROM dbo.SceneAssetLocations sal
    WHERE sal.SceneID = @SceneID
        AND sal.Description IS NULL
        AND NOT EXISTS (SELECT 1 FROM @Assets requested WHERE requested.ID = sal.StoryAssetID);

    INSERT dbo.AssetEvents (StoryAssetID, SceneID, AssetEventTypeID, FromStateID, ToStateID, EventTitle, EventDescription)
    SELECT requested.ID, @SceneID, @UsedAssetEventTypeID, NULL, NULL, N'Used', NULL
    FROM @Assets requested
    WHERE NOT EXISTS (SELECT 1 FROM dbo.AssetEvents ae WHERE ae.SceneID = @SceneID AND ae.StoryAssetID = requested.ID)
        AND NOT EXISTS (SELECT 1 FROM dbo.SceneAssetLocations sal WHERE sal.SceneID = @SceneID AND sal.StoryAssetID = requested.ID);

    IF @PrimaryLocationId IS NOT NULL
    BEGIN
        INSERT dbo.SceneAssetLocations (SceneID, StoryAssetID, LocationID, Description)
        SELECT @SceneID, requested.ID, @PrimaryLocationId, NULL
        FROM @Assets requested
        WHERE NOT EXISTS (SELECT 1 FROM dbo.SceneAssetLocations sal WHERE sal.SceneID = @SceneID AND sal.StoryAssetID = requested.ID);

        UPDATE sal
        SET LocationID = @PrimaryLocationId,
            UpdatedDate = SYSUTCDATETIME()
        FROM dbo.SceneAssetLocations sal
        INNER JOIN @Assets requested ON requested.ID = sal.StoryAssetID
        WHERE sal.SceneID = @SceneID
            AND sal.Description IS NULL;
    END;

    SELECT @SceneID AS SceneId,
        (SELECT COUNT(*) FROM @Characters) AS CharactersUpdated,
        (SELECT COUNT(*) FROM @Assets) AS AssetsUpdated,
        CASE WHEN @PrimaryLocationId IS NULL THEN 0 ELSE 1 END AS LocationsUpdated,
        N'Scene links updated.' AS Message;
END;
GO
