SET ANSI_NULLS ON;
GO
SET QUOTED_IDENTIFIER ON;
GO

IF OBJECT_ID(N'dbo.SceneNoteTypes', N'U') IS NULL
BEGIN
    CREATE TABLE dbo.SceneNoteTypes
    (
        SceneNoteTypeID int IDENTITY(1,1) NOT NULL CONSTRAINT PK_SceneNoteTypes PRIMARY KEY,
        TypeName nvarchar(100) NOT NULL,
        SortOrder int NOT NULL,
        IsActive bit NOT NULL CONSTRAINT DF_SceneNoteTypes_IsActive DEFAULT 1,
        CONSTRAINT UQ_SceneNoteTypes_TypeName UNIQUE (TypeName)
    );
END;
GO

IF OBJECT_ID(N'dbo.SceneNotes', N'U') IS NULL
BEGIN
    CREATE TABLE dbo.SceneNotes
    (
        SceneNoteID int IDENTITY(1,1) NOT NULL CONSTRAINT PK_SceneNotes PRIMARY KEY,
        SceneID int NOT NULL,
        SceneNoteTypeID int NOT NULL,
        NoteTitle nvarchar(200) NULL,
        NoteText nvarchar(max) NOT NULL,
        SortOrder int NULL,
        IsPinned bit NOT NULL CONSTRAINT DF_SceneNotes_IsPinned DEFAULT 0,
        IsResolved bit NOT NULL CONSTRAINT DF_SceneNotes_IsResolved DEFAULT 0,
        CreatedDate datetime2 NOT NULL CONSTRAINT DF_SceneNotes_CreatedDate DEFAULT SYSUTCDATETIME(),
        UpdatedDate datetime2 NOT NULL CONSTRAINT DF_SceneNotes_UpdatedDate DEFAULT SYSUTCDATETIME(),
        CONSTRAINT FK_SceneNotes_Scenes FOREIGN KEY (SceneID) REFERENCES dbo.Scenes(SceneID),
        CONSTRAINT FK_SceneNotes_Types FOREIGN KEY (SceneNoteTypeID) REFERENCES dbo.SceneNoteTypes(SceneNoteTypeID)
    );
END;
GO

IF OBJECT_ID(N'dbo.ChapterGoals', N'U') IS NULL
BEGIN
    CREATE TABLE dbo.ChapterGoals
    (
        ChapterGoalID int IDENTITY(1,1) NOT NULL CONSTRAINT PK_ChapterGoals PRIMARY KEY,
        ChapterID int NOT NULL,
        GoalSummary nvarchar(max) NULL,
        EmotionalGoal nvarchar(max) NULL,
        ReaderTakeaway nvarchar(max) NULL,
        MustInclude nvarchar(max) NULL,
        RisksOrConcerns nvarchar(max) NULL,
        CreatedDate datetime2 NOT NULL CONSTRAINT DF_ChapterGoals_CreatedDate DEFAULT SYSUTCDATETIME(),
        UpdatedDate datetime2 NOT NULL CONSTRAINT DF_ChapterGoals_UpdatedDate DEFAULT SYSUTCDATETIME(),
        CONSTRAINT FK_ChapterGoals_Chapters FOREIGN KEY (ChapterID) REFERENCES dbo.Chapters(ChapterID),
        CONSTRAINT UQ_ChapterGoals_ChapterID UNIQUE (ChapterID)
    );
END;
GO

IF OBJECT_ID(N'dbo.SceneWorkflow', N'U') IS NULL
BEGIN
    CREATE TABLE dbo.SceneWorkflow
    (
        SceneWorkflowID int IDENTITY(1,1) NOT NULL CONSTRAINT PK_SceneWorkflow PRIMARY KEY,
        SceneID int NOT NULL,
        DraftStatus nvarchar(50) NOT NULL CONSTRAINT DF_SceneWorkflow_DraftStatus DEFAULT N'Planned',
        EstimatedWordCount int NULL,
        ActualWordCount int NULL,
        DraftedDate date NULL,
        LastWorkedOn date NULL,
        ReadyForDraft bit NOT NULL CONSTRAINT DF_SceneWorkflow_ReadyForDraft DEFAULT 0,
        ReadyForRevision bit NOT NULL CONSTRAINT DF_SceneWorkflow_ReadyForRevision DEFAULT 0,
        ReadyForPolish bit NOT NULL CONSTRAINT DF_SceneWorkflow_ReadyForPolish DEFAULT 0,
        IsBlocked bit NOT NULL CONSTRAINT DF_SceneWorkflow_IsBlocked DEFAULT 0,
        BlockedReason nvarchar(max) NULL,
        Priority int NULL,
        CreatedDate datetime2 NOT NULL CONSTRAINT DF_SceneWorkflow_CreatedDate DEFAULT SYSUTCDATETIME(),
        UpdatedDate datetime2 NOT NULL CONSTRAINT DF_SceneWorkflow_UpdatedDate DEFAULT SYSUTCDATETIME(),
        CONSTRAINT FK_SceneWorkflow_Scenes FOREIGN KEY (SceneID) REFERENCES dbo.Scenes(SceneID),
        CONSTRAINT UQ_SceneWorkflow_SceneID UNIQUE (SceneID),
        CONSTRAINT CK_SceneWorkflow_DraftStatus CHECK (DraftStatus IN (N'Planned', N'Ready To Draft', N'Drafting', N'Drafted', N'Revising', N'Polishing', N'Complete', N'On Hold')),
        CONSTRAINT CK_SceneWorkflow_Priority CHECK (Priority IS NULL OR Priority BETWEEN 1 AND 10),
        CONSTRAINT CK_SceneWorkflow_WordCounts CHECK ((EstimatedWordCount IS NULL OR EstimatedWordCount >= 0) AND (ActualWordCount IS NULL OR ActualWordCount >= 0))
    );
END;
GO

IF OBJECT_ID(N'dbo.SceneChecklistItems', N'U') IS NULL
BEGIN
    CREATE TABLE dbo.SceneChecklistItems
    (
        SceneChecklistItemID int IDENTITY(1,1) NOT NULL CONSTRAINT PK_SceneChecklistItems PRIMARY KEY,
        SceneID int NOT NULL,
        ItemText nvarchar(300) NOT NULL,
        IsCompleted bit NOT NULL CONSTRAINT DF_SceneChecklistItems_IsCompleted DEFAULT 0,
        SortOrder int NULL,
        CreatedDate datetime2 NOT NULL CONSTRAINT DF_SceneChecklistItems_CreatedDate DEFAULT SYSUTCDATETIME(),
        UpdatedDate datetime2 NOT NULL CONSTRAINT DF_SceneChecklistItems_UpdatedDate DEFAULT SYSUTCDATETIME(),
        CONSTRAINT FK_SceneChecklistItems_Scenes FOREIGN KEY (SceneID) REFERENCES dbo.Scenes(SceneID)
    );
END;
GO

IF OBJECT_ID(N'dbo.SceneAttachmentTypes', N'U') IS NULL
BEGIN
    CREATE TABLE dbo.SceneAttachmentTypes
    (
        SceneAttachmentTypeID int IDENTITY(1,1) NOT NULL CONSTRAINT PK_SceneAttachmentTypes PRIMARY KEY,
        TypeName nvarchar(100) NOT NULL,
        SortOrder int NOT NULL,
        IsActive bit NOT NULL CONSTRAINT DF_SceneAttachmentTypes_IsActive DEFAULT 1,
        CONSTRAINT UQ_SceneAttachmentTypes_TypeName UNIQUE (TypeName)
    );
END;
GO

IF OBJECT_ID(N'dbo.SceneAttachments', N'U') IS NULL
BEGIN
    CREATE TABLE dbo.SceneAttachments
    (
        SceneAttachmentID int IDENTITY(1,1) NOT NULL CONSTRAINT PK_SceneAttachments PRIMARY KEY,
        SceneID int NOT NULL,
        SceneAttachmentTypeID int NOT NULL,
        Title nvarchar(200) NOT NULL,
        FilePath nvarchar(500) NULL,
        ExternalUrl nvarchar(1000) NULL,
        Notes nvarchar(max) NULL,
        CreatedDate datetime2 NOT NULL CONSTRAINT DF_SceneAttachments_CreatedDate DEFAULT SYSUTCDATETIME(),
        UpdatedDate datetime2 NOT NULL CONSTRAINT DF_SceneAttachments_UpdatedDate DEFAULT SYSUTCDATETIME(),
        CONSTRAINT FK_SceneAttachments_Scenes FOREIGN KEY (SceneID) REFERENCES dbo.Scenes(SceneID),
        CONSTRAINT FK_SceneAttachments_Types FOREIGN KEY (SceneAttachmentTypeID) REFERENCES dbo.SceneAttachmentTypes(SceneAttachmentTypeID)
    );
END;
GO

MERGE dbo.SceneNoteTypes AS target
USING (VALUES
    (N'Drafting Note', 10), (N'Revision Note', 20), (N'Continuity Note', 30), (N'Research Note', 40),
    (N'Emotional Intent', 50), (N'Dialogue Note', 60), (N'Sensory Note', 70), (N'Timeline Note', 80),
    (N'Plot Reminder', 90), (N'Character Reminder', 100), (N'TODO', 110)
) AS source (TypeName, SortOrder)
ON target.TypeName = source.TypeName
WHEN MATCHED THEN UPDATE SET SortOrder = source.SortOrder, IsActive = 1
WHEN NOT MATCHED THEN INSERT (TypeName, SortOrder, IsActive) VALUES (source.TypeName, source.SortOrder, 1);
GO

MERGE dbo.SceneAttachmentTypes AS target
USING (VALUES
    (N'Image', 10), (N'Link', 20), (N'Research Reference', 30), (N'Historical Reference', 40),
    (N'Character Reference', 50), (N'Location Reference', 60), (N'Continuity Reference', 70), (N'General File', 80)
) AS source (TypeName, SortOrder)
ON target.TypeName = source.TypeName
WHEN MATCHED THEN UPDATE SET SortOrder = source.SortOrder, IsActive = 1
WHEN NOT MATCHED THEN INSERT (TypeName, SortOrder, IsActive) VALUES (source.TypeName, source.SortOrder, 1);
GO

IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = N'IX_SceneNotes_SceneID' AND object_id = OBJECT_ID(N'dbo.SceneNotes'))
    CREATE INDEX IX_SceneNotes_SceneID ON dbo.SceneNotes(SceneID, IsResolved, IsPinned, SortOrder);
GO
IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = N'IX_SceneChecklistItems_SceneID' AND object_id = OBJECT_ID(N'dbo.SceneChecklistItems'))
    CREATE INDEX IX_SceneChecklistItems_SceneID ON dbo.SceneChecklistItems(SceneID, IsCompleted, SortOrder);
GO
IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = N'IX_SceneAttachments_SceneID' AND object_id = OBJECT_ID(N'dbo.SceneAttachments'))
    CREATE INDEX IX_SceneAttachments_SceneID ON dbo.SceneAttachments(SceneID, SceneAttachmentTypeID);
GO

CREATE OR ALTER PROCEDURE dbo.SceneNoteType_List
AS
BEGIN
    SET NOCOUNT ON;
    SELECT SceneNoteTypeID, TypeName, SortOrder, IsActive
    FROM dbo.SceneNoteTypes
    WHERE IsActive = 1
    ORDER BY SortOrder, TypeName;
END;
GO

CREATE OR ALTER PROCEDURE dbo.SceneAttachmentType_List
AS
BEGIN
    SET NOCOUNT ON;
    SELECT SceneAttachmentTypeID, TypeName, SortOrder, IsActive
    FROM dbo.SceneAttachmentTypes
    WHERE IsActive = 1
    ORDER BY SortOrder, TypeName;
END;
GO

CREATE OR ALTER PROCEDURE dbo.SceneWorkflow_Get
    @SceneID int
AS
BEGIN
    SET NOCOUNT ON;

    IF NOT EXISTS (SELECT 1 FROM dbo.SceneWorkflow WHERE SceneID = @SceneID)
    BEGIN
        INSERT dbo.SceneWorkflow (SceneID)
        VALUES (@SceneID);
    END;

    IF NOT EXISTS (SELECT 1 FROM dbo.SceneChecklistItems WHERE SceneID = @SceneID)
    BEGIN
        INSERT dbo.SceneChecklistItems (SceneID, ItemText, SortOrder)
        VALUES
            (@SceneID, N'Purpose clear', 10),
            (@SceneID, N'Emotional payoff clear', 20),
            (@SceneID, N'Continuity checked', 30),
            (@SceneID, N'POV consistent', 40),
            (@SceneID, N'Dialogue pass complete', 50),
            (@SceneID, N'Sensory detail pass complete', 60),
            (@SceneID, N'Character motivation clear', 70),
            (@SceneID, N'Ending hook strong', 80);
    END;

    SELECT SceneWorkflowID, SceneID, DraftStatus, EstimatedWordCount, ActualWordCount, DraftedDate, LastWorkedOn,
        ReadyForDraft, ReadyForRevision, ReadyForPolish, IsBlocked, BlockedReason, Priority, CreatedDate, UpdatedDate
    FROM dbo.SceneWorkflow
    WHERE SceneID = @SceneID;
END;
GO

CREATE OR ALTER PROCEDURE dbo.SceneWorkflow_Save
    @SceneID int,
    @DraftStatus nvarchar(50),
    @EstimatedWordCount int = NULL,
    @ActualWordCount int = NULL,
    @DraftedDate date = NULL,
    @LastWorkedOn date = NULL,
    @ReadyForDraft bit = 0,
    @ReadyForRevision bit = 0,
    @ReadyForPolish bit = 0,
    @IsBlocked bit = 0,
    @BlockedReason nvarchar(max) = NULL,
    @Priority int = NULL
AS
BEGIN
    SET NOCOUNT ON;

    IF EXISTS (SELECT 1 FROM dbo.SceneWorkflow WHERE SceneID = @SceneID)
    BEGIN
        UPDATE dbo.SceneWorkflow
        SET DraftStatus = @DraftStatus,
            EstimatedWordCount = @EstimatedWordCount,
            ActualWordCount = @ActualWordCount,
            DraftedDate = @DraftedDate,
            LastWorkedOn = @LastWorkedOn,
            ReadyForDraft = @ReadyForDraft,
            ReadyForRevision = @ReadyForRevision,
            ReadyForPolish = @ReadyForPolish,
            IsBlocked = @IsBlocked,
            BlockedReason = @BlockedReason,
            Priority = @Priority,
            UpdatedDate = SYSUTCDATETIME()
        WHERE SceneID = @SceneID;
    END
    ELSE
    BEGIN
        INSERT dbo.SceneWorkflow (SceneID, DraftStatus, EstimatedWordCount, ActualWordCount, DraftedDate, LastWorkedOn, ReadyForDraft, ReadyForRevision, ReadyForPolish, IsBlocked, BlockedReason, Priority)
        VALUES (@SceneID, @DraftStatus, @EstimatedWordCount, @ActualWordCount, @DraftedDate, @LastWorkedOn, @ReadyForDraft, @ReadyForRevision, @ReadyForPolish, @IsBlocked, @BlockedReason, @Priority);
    END;
END;
GO

CREATE OR ALTER PROCEDURE dbo.SceneNote_ListByScene
    @SceneID int
AS
BEGIN
    SET NOCOUNT ON;
    SELECT n.SceneNoteID, n.SceneID, n.SceneNoteTypeID, nt.TypeName, n.NoteTitle, n.NoteText, n.SortOrder,
        n.IsPinned, n.IsResolved, n.CreatedDate, n.UpdatedDate
    FROM dbo.SceneNotes n
    INNER JOIN dbo.SceneNoteTypes nt ON nt.SceneNoteTypeID = n.SceneNoteTypeID
    WHERE n.SceneID = @SceneID
    ORDER BY n.IsPinned DESC, n.IsResolved, ISNULL(n.SortOrder, 9999), n.UpdatedDate DESC;
END;
GO

CREATE OR ALTER PROCEDURE dbo.SceneNote_Save
    @SceneNoteID int = 0,
    @SceneID int,
    @SceneNoteTypeID int,
    @NoteTitle nvarchar(200) = NULL,
    @NoteText nvarchar(max),
    @SortOrder int = NULL,
    @IsPinned bit = 0,
    @IsResolved bit = 0
AS
BEGIN
    SET NOCOUNT ON;

    IF @SceneNoteID IS NULL OR @SceneNoteID = 0
    BEGIN
        INSERT dbo.SceneNotes (SceneID, SceneNoteTypeID, NoteTitle, NoteText, SortOrder, IsPinned, IsResolved)
        VALUES (@SceneID, @SceneNoteTypeID, @NoteTitle, @NoteText, @SortOrder, @IsPinned, @IsResolved);
        SET @SceneNoteID = CAST(SCOPE_IDENTITY() AS int);
    END
    ELSE
    BEGIN
        UPDATE dbo.SceneNotes
        SET SceneNoteTypeID = @SceneNoteTypeID,
            NoteTitle = @NoteTitle,
            NoteText = @NoteText,
            SortOrder = @SortOrder,
            IsPinned = @IsPinned,
            IsResolved = @IsResolved,
            UpdatedDate = SYSUTCDATETIME()
        WHERE SceneNoteID = @SceneNoteID;
    END;

    SELECT @SceneNoteID;
END;
GO

CREATE OR ALTER PROCEDURE dbo.SceneNote_Delete
    @SceneNoteID int
AS
BEGIN
    SET NOCOUNT ON;
    DELETE dbo.SceneNotes WHERE SceneNoteID = @SceneNoteID;
END;
GO

CREATE OR ALTER PROCEDURE dbo.SceneChecklist_ListByScene
    @SceneID int
AS
BEGIN
    SET NOCOUNT ON;
    SELECT SceneChecklistItemID, SceneID, ItemText, IsCompleted, SortOrder, CreatedDate, UpdatedDate
    FROM dbo.SceneChecklistItems
    WHERE SceneID = @SceneID
    ORDER BY IsCompleted, ISNULL(SortOrder, 9999), SceneChecklistItemID;
END;
GO

CREATE OR ALTER PROCEDURE dbo.SceneChecklist_Save
    @SceneChecklistItemID int = 0,
    @SceneID int,
    @ItemText nvarchar(300),
    @IsCompleted bit = 0,
    @SortOrder int = NULL
AS
BEGIN
    SET NOCOUNT ON;
    IF @SceneChecklistItemID IS NULL OR @SceneChecklistItemID = 0
    BEGIN
        INSERT dbo.SceneChecklistItems (SceneID, ItemText, IsCompleted, SortOrder)
        VALUES (@SceneID, @ItemText, @IsCompleted, @SortOrder);
        SET @SceneChecklistItemID = CAST(SCOPE_IDENTITY() AS int);
    END
    ELSE
    BEGIN
        UPDATE dbo.SceneChecklistItems
        SET ItemText = @ItemText, IsCompleted = @IsCompleted, SortOrder = @SortOrder, UpdatedDate = SYSUTCDATETIME()
        WHERE SceneChecklistItemID = @SceneChecklistItemID;
    END;

    SELECT @SceneChecklistItemID;
END;
GO

CREATE OR ALTER PROCEDURE dbo.SceneChecklist_Delete
    @SceneChecklistItemID int
AS
BEGIN
    SET NOCOUNT ON;
    DELETE dbo.SceneChecklistItems WHERE SceneChecklistItemID = @SceneChecklistItemID;
END;
GO

CREATE OR ALTER PROCEDURE dbo.SceneAttachment_ListByScene
    @SceneID int
AS
BEGIN
    SET NOCOUNT ON;
    SELECT a.SceneAttachmentID, a.SceneID, a.SceneAttachmentTypeID, at.TypeName, a.Title, a.FilePath, a.ExternalUrl, a.Notes, a.CreatedDate, a.UpdatedDate
    FROM dbo.SceneAttachments a
    INNER JOIN dbo.SceneAttachmentTypes at ON at.SceneAttachmentTypeID = a.SceneAttachmentTypeID
    WHERE a.SceneID = @SceneID
    ORDER BY a.UpdatedDate DESC, a.SceneAttachmentID DESC;
END;
GO

CREATE OR ALTER PROCEDURE dbo.SceneAttachment_Save
    @SceneAttachmentID int = 0,
    @SceneID int,
    @SceneAttachmentTypeID int,
    @Title nvarchar(200),
    @FilePath nvarchar(500) = NULL,
    @ExternalUrl nvarchar(1000) = NULL,
    @Notes nvarchar(max) = NULL
AS
BEGIN
    SET NOCOUNT ON;
    IF @SceneAttachmentID IS NULL OR @SceneAttachmentID = 0
    BEGIN
        INSERT dbo.SceneAttachments (SceneID, SceneAttachmentTypeID, Title, FilePath, ExternalUrl, Notes)
        VALUES (@SceneID, @SceneAttachmentTypeID, @Title, @FilePath, @ExternalUrl, @Notes);
        SET @SceneAttachmentID = CAST(SCOPE_IDENTITY() AS int);
    END
    ELSE
    BEGIN
        UPDATE dbo.SceneAttachments
        SET SceneAttachmentTypeID = @SceneAttachmentTypeID,
            Title = @Title,
            FilePath = @FilePath,
            ExternalUrl = @ExternalUrl,
            Notes = @Notes,
            UpdatedDate = SYSUTCDATETIME()
        WHERE SceneAttachmentID = @SceneAttachmentID;
    END;

    SELECT @SceneAttachmentID;
END;
GO

CREATE OR ALTER PROCEDURE dbo.SceneAttachment_Delete
    @SceneAttachmentID int
AS
BEGIN
    SET NOCOUNT ON;
    DELETE dbo.SceneAttachments WHERE SceneAttachmentID = @SceneAttachmentID;
END;
GO

CREATE OR ALTER PROCEDURE dbo.ChapterGoal_Get
    @ChapterID int
AS
BEGIN
    SET NOCOUNT ON;
    IF NOT EXISTS (SELECT 1 FROM dbo.ChapterGoals WHERE ChapterID = @ChapterID)
    BEGIN
        INSERT dbo.ChapterGoals (ChapterID) VALUES (@ChapterID);
    END;

    SELECT ChapterGoalID, ChapterID, GoalSummary, EmotionalGoal, ReaderTakeaway, MustInclude, RisksOrConcerns, CreatedDate, UpdatedDate
    FROM dbo.ChapterGoals
    WHERE ChapterID = @ChapterID;
END;
GO

CREATE OR ALTER PROCEDURE dbo.ChapterGoal_Save
    @ChapterID int,
    @GoalSummary nvarchar(max) = NULL,
    @EmotionalGoal nvarchar(max) = NULL,
    @ReaderTakeaway nvarchar(max) = NULL,
    @MustInclude nvarchar(max) = NULL,
    @RisksOrConcerns nvarchar(max) = NULL
AS
BEGIN
    SET NOCOUNT ON;
    IF EXISTS (SELECT 1 FROM dbo.ChapterGoals WHERE ChapterID = @ChapterID)
    BEGIN
        UPDATE dbo.ChapterGoals
        SET GoalSummary = @GoalSummary,
            EmotionalGoal = @EmotionalGoal,
            ReaderTakeaway = @ReaderTakeaway,
            MustInclude = @MustInclude,
            RisksOrConcerns = @RisksOrConcerns,
            UpdatedDate = SYSUTCDATETIME()
        WHERE ChapterID = @ChapterID;
    END
    ELSE
    BEGIN
        INSERT dbo.ChapterGoals (ChapterID, GoalSummary, EmotionalGoal, ReaderTakeaway, MustInclude, RisksOrConcerns)
        VALUES (@ChapterID, @GoalSummary, @EmotionalGoal, @ReaderTakeaway, @MustInclude, @RisksOrConcerns);
    END;
END;
GO

CREATE OR ALTER PROCEDURE dbo.ChapterWorkflow_Summary
    @ChapterID int
AS
BEGIN
    SET NOCOUNT ON;

    SELECT s.SceneID, s.SceneNumber, s.SceneTitle,
        COALESCE(sw.DraftStatus, N'Planned') AS DraftStatus,
        sw.Priority,
        COALESCE(sw.ReadyForDraft, 0) AS ReadyForDraft,
        COALESCE(sw.ReadyForRevision, 0) AS ReadyForRevision,
        COALESCE(sw.ReadyForPolish, 0) AS ReadyForPolish,
        COALESCE(sw.IsBlocked, 0) AS IsBlocked,
        sw.BlockedReason,
        ISNULL(warnings.WarningCount, 0) AS WarningCount,
        ISNULL(checklist.RemainingChecklistCount, 0) AS RemainingChecklistCount,
        ISNULL(notes.UnresolvedNoteCount, 0) AS UnresolvedNoteCount
    FROM dbo.Scenes s
    LEFT JOIN dbo.SceneWorkflow sw ON sw.SceneID = s.SceneID
    OUTER APPLY
    (
        SELECT COUNT(*) AS WarningCount
        FROM dbo.ContinuityWarnings cw
        WHERE cw.SceneID = s.SceneID AND cw.IsDismissed = 0
    ) warnings
    OUTER APPLY
    (
        SELECT COUNT(*) AS RemainingChecklistCount
        FROM dbo.SceneChecklistItems sci
        WHERE sci.SceneID = s.SceneID AND sci.IsCompleted = 0
    ) checklist
    OUTER APPLY
    (
        SELECT COUNT(*) AS UnresolvedNoteCount
        FROM dbo.SceneNotes sn
        WHERE sn.SceneID = s.SceneID AND sn.IsResolved = 0
    ) notes
    WHERE s.ChapterID = @ChapterID AND s.IsArchived = 0
    ORDER BY s.SortOrder, s.SceneID;
END;
GO

CREATE OR ALTER PROCEDURE dbo.WriterDashboard_Scenes
    @ProjectID int = NULL,
    @Queue nvarchar(50)
AS
BEGIN
    SET NOCOUNT ON;

    WITH SceneBase AS
    (
        SELECT p.ProjectID, p.ProjectName, b.BookID, b.BookTitle, c.ChapterID, c.ChapterNumber, c.ChapterTitle,
            s.SceneID, s.SceneNumber, s.SceneTitle, s.Summary,
            COALESCE(sw.DraftStatus, N'Planned') AS DraftStatus,
            sw.Priority,
            COALESCE(sw.IsBlocked, 0) AS IsBlocked,
            sw.BlockedReason,
            COALESCE(sw.ReadyForDraft, 0) AS ReadyForDraft,
            COALESCE(sw.ReadyForRevision, 0) AS ReadyForRevision,
            COALESCE(sw.ReadyForPolish, 0) AS ReadyForPolish,
            b.SortOrder AS BookSortOrder,
            c.SortOrder AS ChapterSortOrder,
            s.SortOrder AS SceneSortOrder
        FROM dbo.Projects p
        INNER JOIN dbo.Books b ON b.ProjectID = p.ProjectID AND b.IsArchived = 0
        INNER JOIN dbo.Chapters c ON c.BookID = b.BookID AND c.IsArchived = 0
        INNER JOIN dbo.Scenes s ON s.ChapterID = c.ChapterID AND s.IsArchived = 0
        LEFT JOIN dbo.SceneWorkflow sw ON sw.SceneID = s.SceneID
        WHERE p.IsArchived = 0 AND (@ProjectID IS NULL OR p.ProjectID = @ProjectID)
    )
    SELECT TOP (40) sb.ProjectID, sb.ProjectName, sb.BookID, sb.BookTitle, sb.ChapterID, sb.ChapterNumber, sb.ChapterTitle,
        sb.SceneID, sb.SceneNumber, sb.SceneTitle, sb.Summary, sb.DraftStatus, sb.Priority, sb.IsBlocked, sb.BlockedReason,
        ISNULL(warnings.WarningCount, 0) AS WarningCount,
        ISNULL(checklist.RemainingChecklistCount, 0) AS RemainingChecklistCount,
        ISNULL(notes.UnresolvedNoteCount, 0) AS UnresolvedNoteCount,
        threads.ImportantThreads,
        pinned.PinnedNotes
    FROM SceneBase sb
    OUTER APPLY
    (
        SELECT COUNT(*) AS WarningCount
        FROM dbo.ContinuityWarnings cw
        WHERE cw.SceneID = sb.SceneID AND cw.IsDismissed = 0
    ) warnings
    OUTER APPLY
    (
        SELECT COUNT(*) AS RemainingChecklistCount
        FROM dbo.SceneChecklistItems sci
        WHERE sci.SceneID = sb.SceneID AND sci.IsCompleted = 0
    ) checklist
    OUTER APPLY
    (
        SELECT COUNT(*) AS UnresolvedNoteCount
        FROM dbo.SceneNotes sn
        INNER JOIN dbo.SceneNoteTypes snt ON snt.SceneNoteTypeID = sn.SceneNoteTypeID
        WHERE sn.SceneID = sb.SceneID AND sn.IsResolved = 0
            AND (@Queue <> N'NeedsAttention' OR snt.TypeName IN (N'TODO', N'Continuity Note'))
    ) notes
    OUTER APPLY
    (
        SELECT STRING_AGG(CONVERT(nvarchar(max), pt.ThreadTitle), N', ') AS ImportantThreads
        FROM
        (
            SELECT DISTINCT TOP (5) pt.ThreadTitle, pt.Importance
            FROM dbo.ThreadEvents te
            INNER JOIN dbo.PlotThreads pt ON pt.PlotThreadID = te.PlotThreadID
            WHERE te.SceneID = sb.SceneID
            ORDER BY pt.Importance DESC, pt.ThreadTitle
        ) pt
    ) threads
    OUTER APPLY
    (
        SELECT STRING_AGG(CONVERT(nvarchar(max), COALESCE(sn.NoteTitle, sn.NoteText)), N' | ') AS PinnedNotes
        FROM dbo.SceneNotes sn
        WHERE sn.SceneID = sb.SceneID AND sn.IsPinned = 1 AND sn.IsResolved = 0
    ) pinned
    WHERE
        (@Queue = N'ContinueWriting' AND (sb.DraftStatus IN (N'Ready To Draft', N'Drafting') OR sb.ReadyForDraft = 1 OR ISNULL(sb.Priority, 0) >= 8))
        OR (@Queue = N'NeedsAttention' AND (sb.IsBlocked = 1 OR ISNULL(warnings.WarningCount, 0) > 0 OR ISNULL(notes.UnresolvedNoteCount, 0) > 0))
        OR (@Queue = N'RevisionQueue' AND (sb.DraftStatus IN (N'Drafted', N'Revising') OR sb.ReadyForRevision = 1))
        OR (@Queue = N'PolishingQueue' AND (sb.DraftStatus = N'Polishing' OR sb.ReadyForPolish = 1))
    ORDER BY ISNULL(sb.Priority, 0) DESC, sb.BookSortOrder, sb.ChapterSortOrder, sb.SceneSortOrder, sb.SceneID;
END;
GO

CREATE OR ALTER PROCEDURE dbo.WriterDashboard_Reminders
    @ProjectID int = NULL
AS
BEGIN
    SET NOCOUNT ON;

    SELECT TOP (60) N'Chapter Goal' AS Category, N'Info' AS SeverityName,
        CONCAT(N'Chapter ', c.ChapterNumber, N' needs intent') AS Title,
        N'Goal summary is empty.' AS Detail,
        CAST(NULL AS int) AS SceneID, c.ChapterID AS EntityID, N'Chapter' AS EntityType
    FROM dbo.Chapters c
    INNER JOIN dbo.Books b ON b.BookID = c.BookID AND b.IsArchived = 0
    LEFT JOIN dbo.ChapterGoals cg ON cg.ChapterID = c.ChapterID
    WHERE c.IsArchived = 0 AND (@ProjectID IS NULL OR b.ProjectID = @ProjectID)
        AND NULLIF(LTRIM(RTRIM(cg.GoalSummary)), N'') IS NULL
    UNION ALL
    SELECT N'Plot Thread', N'Info', pt.ThreadTitle,
        CONCAT(N'Unresolved thread in ', pl.PlotLineName, N'.'),
        CAST(NULL AS int), pt.PlotThreadID, N'PlotThread'
    FROM dbo.PlotThreads pt
    INNER JOIN dbo.ThreadStatuses ts ON ts.ThreadStatusID = pt.ThreadStatusID
    INNER JOIN dbo.PlotLines pl ON pl.PlotLineID = pt.PlotLineID AND pl.IsArchived = 0
    WHERE pt.IsArchived = 0 AND ts.IsOpenStatus = 1 AND (@ProjectID IS NULL OR pl.ProjectID = @ProjectID)
    UNION ALL
    SELECT N'Writer Note', N'Warning', COALESCE(sn.NoteTitle, s.SceneTitle),
        sn.NoteText, s.SceneID, sn.SceneNoteID, N'SceneNote'
    FROM dbo.SceneNotes sn
    INNER JOIN dbo.SceneNoteTypes snt ON snt.SceneNoteTypeID = sn.SceneNoteTypeID
    INNER JOIN dbo.Scenes s ON s.SceneID = sn.SceneID AND s.IsArchived = 0
    INNER JOIN dbo.Chapters c ON c.ChapterID = s.ChapterID AND c.IsArchived = 0
    INNER JOIN dbo.Books b ON b.BookID = c.BookID AND b.IsArchived = 0
    WHERE sn.IsResolved = 0 AND snt.TypeName IN (N'TODO', N'Continuity Note', N'Revision Note') AND (@ProjectID IS NULL OR b.ProjectID = @ProjectID);
END;
GO

CREATE OR ALTER PROCEDURE dbo.StoryBible_Search
    @ProjectID int,
    @Query nvarchar(200) = NULL
AS
BEGIN
    SET NOCOUNT ON;

    IF NULLIF(LTRIM(RTRIM(@Query)), N'') IS NULL
        RETURN;

    DECLARE @Term nvarchar(204) = N'%' + LTRIM(RTRIM(@Query)) + N'%';

    SELECT N'Character' AS ResultType, ch.CharacterID AS EntityID, ch.CharacterName AS Title,
        ch.DefaultDescription AS Detail, CAST(NULL AS int) AS SceneID
    FROM dbo.Characters ch
    WHERE ch.ProjectID = @ProjectID AND ch.IsArchived = 0
        AND (ch.CharacterName LIKE @Term OR ch.ShortName LIKE @Term OR ch.DefaultDescription LIKE @Term)
    UNION ALL
    SELECT N'Scene', s.SceneID, CONCAT(N'Scene ', s.SceneNumber, N': ', s.SceneTitle),
        s.Summary, s.SceneID
    FROM dbo.Scenes s
    INNER JOIN dbo.Chapters c ON c.ChapterID = s.ChapterID AND c.IsArchived = 0
    INNER JOIN dbo.Books b ON b.BookID = c.BookID AND b.ProjectID = @ProjectID AND b.IsArchived = 0
    WHERE s.IsArchived = 0 AND (s.SceneTitle LIKE @Term OR s.Summary LIKE @Term OR s.ScenePurposeNotes LIKE @Term OR s.SceneOutcomeNotes LIKE @Term)
    UNION ALL
    SELECT N'Plot Thread', pt.PlotThreadID, pt.ThreadTitle, pt.Summary, CAST(NULL AS int)
    FROM dbo.PlotThreads pt
    INNER JOIN dbo.PlotLines pl ON pl.PlotLineID = pt.PlotLineID AND pl.ProjectID = @ProjectID AND pl.IsArchived = 0
    WHERE pt.IsArchived = 0 AND (pt.ThreadTitle LIKE @Term OR pt.Summary LIKE @Term)
    UNION ALL
    SELECT N'Story Asset', sa.StoryAssetID, sa.AssetName, sa.Description, CAST(NULL AS int)
    FROM dbo.StoryAssets sa
    WHERE sa.ProjectID = @ProjectID AND sa.IsArchived = 0 AND (sa.AssetName LIKE @Term OR sa.Description LIKE @Term)
    UNION ALL
    SELECT N'Location', lp.LocationID, lp.LocationPath, lp.Description, CAST(NULL AS int)
    FROM dbo.LocationPaths lp
    WHERE lp.ProjectID = @ProjectID AND (lp.LocationName LIKE @Term OR lp.LocationPath LIKE @Term OR lp.Description LIKE @Term)
    UNION ALL
    SELECT N'Relationship', cr.CharacterRelationshipID, CONCAT(ca.CharacterName, N' - ', cb.CharacterName),
        CONCAT(rt.TypeName, N'. ', ISNULL(cr.Notes, N'')), CAST(NULL AS int)
    FROM dbo.CharacterRelationships cr
    INNER JOIN dbo.Characters ca ON ca.CharacterID = cr.CharacterAID
    INNER JOIN dbo.Characters cb ON cb.CharacterID = cr.CharacterBID
    INNER JOIN dbo.RelationshipTypes rt ON rt.RelationshipTypeID = cr.RelationshipTypeID
    WHERE cr.ProjectID = @ProjectID AND cr.IsArchived = 0
        AND (ca.CharacterName LIKE @Term OR cb.CharacterName LIKE @Term OR rt.TypeName LIKE @Term OR cr.Notes LIKE @Term)
    UNION ALL
    SELECT N'Warning', cw.ContinuityWarningID, cw.Message, cw.Details, cw.SceneID
    FROM dbo.ContinuityWarnings cw
    WHERE cw.ProjectID = @ProjectID AND cw.IsDismissed = 0
        AND (cw.Message LIKE @Term OR cw.Details LIKE @Term OR cw.EntityType LIKE @Term)
    UNION ALL
    SELECT N'Scene Note', sn.SceneNoteID, COALESCE(sn.NoteTitle, CONCAT(snt.TypeName, N' for ', s.SceneTitle)),
        sn.NoteText, sn.SceneID
    FROM dbo.SceneNotes sn
    INNER JOIN dbo.SceneNoteTypes snt ON snt.SceneNoteTypeID = sn.SceneNoteTypeID
    INNER JOIN dbo.Scenes s ON s.SceneID = sn.SceneID AND s.IsArchived = 0
    INNER JOIN dbo.Chapters c ON c.ChapterID = s.ChapterID AND c.IsArchived = 0
    INNER JOIN dbo.Books b ON b.BookID = c.BookID AND b.ProjectID = @ProjectID AND b.IsArchived = 0
    WHERE sn.NoteTitle LIKE @Term OR sn.NoteText LIKE @Term OR snt.TypeName LIKE @Term
    UNION ALL
    SELECT N'Chapter Goal', cg.ChapterGoalID, CONCAT(N'Chapter ', c.ChapterNumber, N': ', c.ChapterTitle),
        CONCAT(ISNULL(cg.GoalSummary, N''), N' ', ISNULL(cg.EmotionalGoal, N''), N' ', ISNULL(cg.ReaderTakeaway, N''), N' ', ISNULL(cg.MustInclude, N''), N' ', ISNULL(cg.RisksOrConcerns, N'')),
        CAST(NULL AS int)
    FROM dbo.ChapterGoals cg
    INNER JOIN dbo.Chapters c ON c.ChapterID = cg.ChapterID AND c.IsArchived = 0
    INNER JOIN dbo.Books b ON b.BookID = c.BookID AND b.ProjectID = @ProjectID AND b.IsArchived = 0
    WHERE cg.GoalSummary LIKE @Term OR cg.EmotionalGoal LIKE @Term OR cg.ReaderTakeaway LIKE @Term OR cg.MustInclude LIKE @Term OR cg.RisksOrConcerns LIKE @Term
    UNION ALL
    SELECT N'Attachment', sa.SceneAttachmentID, sa.Title,
        CONCAT(ISNULL(sa.ExternalUrl, N''), N' ', ISNULL(sa.FilePath, N''), N' ', ISNULL(sa.Notes, N'')), sa.SceneID
    FROM dbo.SceneAttachments sa
    INNER JOIN dbo.Scenes s ON s.SceneID = sa.SceneID AND s.IsArchived = 0
    INNER JOIN dbo.Chapters c ON c.ChapterID = s.ChapterID AND c.IsArchived = 0
    INNER JOIN dbo.Books b ON b.BookID = c.BookID AND b.ProjectID = @ProjectID AND b.IsArchived = 0
    WHERE sa.Title LIKE @Term OR sa.ExternalUrl LIKE @Term OR sa.FilePath LIKE @Term OR sa.Notes LIKE @Term
    UNION ALL
    SELECT N'Workflow', sw.SceneWorkflowID, CONCAT(N'Workflow: ', s.SceneTitle),
        sw.BlockedReason, s.SceneID
    FROM dbo.SceneWorkflow sw
    INNER JOIN dbo.Scenes s ON s.SceneID = sw.SceneID AND s.IsArchived = 0
    INNER JOIN dbo.Chapters c ON c.ChapterID = s.ChapterID AND c.IsArchived = 0
    INNER JOIN dbo.Books b ON b.BookID = c.BookID AND b.ProjectID = @ProjectID AND b.IsArchived = 0
    WHERE sw.BlockedReason LIKE @Term OR sw.DraftStatus LIKE @Term
    ORDER BY ResultType, Title;
END;
GO
