SET ANSI_NULLS ON;
GO
SET QUOTED_IDENTIFIER ON;
GO

IF OBJECT_ID(N'dbo.IllustrationLibraryItems', N'U') IS NULL
BEGIN
    CREATE TABLE dbo.IllustrationLibraryItems
    (
        IllustrationLibraryItemID int IDENTITY(1,1) NOT NULL CONSTRAINT PK_IllustrationLibraryItems PRIMARY KEY,
        Category nvarchar(40) NOT NULL,
        StableCode nvarchar(120) NOT NULL,
        DisplayTitle nvarchar(200) NOT NULL,
        ShortDescription nvarchar(500) NULL,
        MetadataJson nvarchar(max) NULL,
        SpecificationJson nvarchar(max) NULL,
        FilePath nvarchar(500) NULL,
        ThumbnailPath nvarchar(500) NULL,
        Width int NULL,
        Height int NULL,
        FileSizeBytes bigint NULL,
        MimeType nvarchar(100) NULL,
        Status nvarchar(40) NOT NULL CONSTRAINT DF_IllustrationLibraryItems_Status DEFAULT N'Planned',
        IsActive bit NOT NULL CONSTRAINT DF_IllustrationLibraryItems_IsActive DEFAULT 1,
        IsApproved bit NOT NULL CONSTRAINT DF_IllustrationLibraryItems_IsApproved DEFAULT 0,
        CreatedUtc datetime2(0) NOT NULL CONSTRAINT DF_IllustrationLibraryItems_CreatedUtc DEFAULT SYSUTCDATETIME(),
        UpdatedUtc datetime2(0) NOT NULL CONSTRAINT DF_IllustrationLibraryItems_UpdatedUtc DEFAULT SYSUTCDATETIME(),
        ApprovedUtc datetime2(0) NULL,
        ApprovedByUserID int NULL,
        Provider nvarchar(80) NULL,
        Model nvarchar(120) NULL,
        PromptText nvarchar(max) NULL,
        PromptTemplateVersion nvarchar(40) NULL,
        ProviderRequestID nvarchar(160) NULL,
        AttemptCount int NOT NULL CONSTRAINT DF_IllustrationLibraryItems_AttemptCount DEFAULT 0,
        ParentItemID int NULL,
        RejectionReason nvarchar(500) NULL,
        AdminNotes nvarchar(1000) NULL,
        UsageCount int NOT NULL CONSTRAINT DF_IllustrationLibraryItems_UsageCount DEFAULT 0,
        LastError nvarchar(1000) NULL,
        QueuedUtc datetime2(0) NULL,
        StartedUtc datetime2(0) NULL,
        CompletedUtc datetime2(0) NULL,
        CONSTRAINT CK_IllustrationLibraryItems_Category CHECK (Category IN (N'Character', N'Location', N'Asset')),
        CONSTRAINT CK_IllustrationLibraryItems_Status CHECK (Status IN (N'Planned', N'Queued', N'Generating', N'Generated', N'Approved', N'Rejected', N'Failed', N'Disabled'))
    );
END;
GO

IF NOT EXISTS (SELECT 1 FROM sys.foreign_keys WHERE name = N'FK_IllustrationLibraryItems_Parent')
BEGIN
    ALTER TABLE dbo.IllustrationLibraryItems
        ADD CONSTRAINT FK_IllustrationLibraryItems_Parent
        FOREIGN KEY (ParentItemID) REFERENCES dbo.IllustrationLibraryItems(IllustrationLibraryItemID);
END;
GO

IF NOT EXISTS (SELECT 1 FROM sys.foreign_keys WHERE name = N'FK_IllustrationLibraryItems_ApprovedBy')
    AND OBJECT_ID(N'dbo.AppUser', N'U') IS NOT NULL
BEGIN
    ALTER TABLE dbo.IllustrationLibraryItems
        ADD CONSTRAINT FK_IllustrationLibraryItems_ApprovedBy
        FOREIGN KEY (ApprovedByUserID) REFERENCES dbo.AppUser(UserID);
END;
GO

IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = N'IX_IllustrationLibraryItems_Status' AND object_id = OBJECT_ID(N'dbo.IllustrationLibraryItems'))
    CREATE INDEX IX_IllustrationLibraryItems_Status ON dbo.IllustrationLibraryItems(Status, Category, UpdatedUtc DESC);
GO

IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = N'IX_IllustrationLibraryItems_Code' AND object_id = OBJECT_ID(N'dbo.IllustrationLibraryItems'))
    CREATE INDEX IX_IllustrationLibraryItems_Code ON dbo.IllustrationLibraryItems(StableCode, Status, IsActive);
GO

IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = N'UX_IllustrationLibraryItems_ActivePlannedCode' AND object_id = OBJECT_ID(N'dbo.IllustrationLibraryItems'))
    CREATE UNIQUE INDEX UX_IllustrationLibraryItems_ActivePlannedCode
    ON dbo.IllustrationLibraryItems(StableCode)
    WHERE ParentItemID IS NULL AND Status IN (N'Planned', N'Queued', N'Generating', N'Generated', N'Approved') AND IsActive = 1;
GO

CREATE OR ALTER PROCEDURE dbo.IllustrationLibraryItem_List
    @Category nvarchar(40) = NULL,
    @Status nvarchar(40) = NULL,
    @Search nvarchar(120) = NULL
AS
BEGIN
    SET NOCOUNT ON;

    SELECT *
    FROM dbo.IllustrationLibraryItems
    WHERE (@Category IS NULL OR Category = @Category)
        AND (@Status IS NULL OR Status = @Status)
        AND (
            @Search IS NULL
            OR StableCode LIKE N'%' + @Search + N'%'
            OR DisplayTitle LIKE N'%' + @Search + N'%'
            OR ShortDescription LIKE N'%' + @Search + N'%'
        )
    ORDER BY
        CASE Status
            WHEN N'Generating' THEN 1
            WHEN N'Queued' THEN 2
            WHEN N'Generated' THEN 3
            WHEN N'Planned' THEN 4
            WHEN N'Failed' THEN 5
            WHEN N'Rejected' THEN 6
            WHEN N'Approved' THEN 7
            ELSE 8
        END,
        UpdatedUtc DESC,
        IllustrationLibraryItemID DESC;
END;
GO

CREATE OR ALTER PROCEDURE dbo.IllustrationLibraryItem_Summary
AS
BEGIN
    SET NOCOUNT ON;

    SELECT
        COUNT(1) AS TotalCount,
        ISNULL(SUM(CASE WHEN Status = N'Planned' THEN 1 ELSE 0 END), 0) AS PlannedCount,
        ISNULL(SUM(CASE WHEN Status = N'Queued' THEN 1 ELSE 0 END), 0) AS QueuedCount,
        ISNULL(SUM(CASE WHEN Status = N'Generating' THEN 1 ELSE 0 END), 0) AS GeneratingCount,
        ISNULL(SUM(CASE WHEN Status = N'Generated' THEN 1 ELSE 0 END), 0) AS GeneratedCount,
        ISNULL(SUM(CASE WHEN Status = N'Approved' THEN 1 ELSE 0 END), 0) AS ApprovedCount,
        ISNULL(SUM(CASE WHEN Status = N'Rejected' THEN 1 ELSE 0 END), 0) AS RejectedCount,
        ISNULL(SUM(CASE WHEN Status = N'Failed' THEN 1 ELSE 0 END), 0) AS FailedCount,
        ISNULL(SUM(CASE WHEN Status = N'Disabled' THEN 1 ELSE 0 END), 0) AS DisabledCount
    FROM dbo.IllustrationLibraryItems;
END;
GO

CREATE OR ALTER PROCEDURE dbo.IllustrationLibraryItem_Get
    @IllustrationLibraryItemID int
AS
BEGIN
    SET NOCOUNT ON;
    SELECT * FROM dbo.IllustrationLibraryItems WHERE IllustrationLibraryItemID = @IllustrationLibraryItemID;
END;
GO

CREATE OR ALTER PROCEDURE dbo.IllustrationLibraryItem_UpsertPlanned
    @Category nvarchar(40),
    @StableCode nvarchar(120),
    @DisplayTitle nvarchar(200),
    @ShortDescription nvarchar(500) = NULL,
    @MetadataJson nvarchar(max) = NULL,
    @SpecificationJson nvarchar(max) = NULL
AS
BEGIN
    SET NOCOUNT ON;

    IF EXISTS (
        SELECT 1
        FROM dbo.IllustrationLibraryItems
        WHERE StableCode = @StableCode
            AND ParentItemID IS NULL
            AND IsActive = 1
            AND Status IN (N'Planned', N'Queued', N'Generating', N'Generated', N'Approved')
    )
    BEGIN
        SELECT * FROM dbo.IllustrationLibraryItems
        WHERE StableCode = @StableCode
            AND ParentItemID IS NULL
            AND IsActive = 1
            AND Status IN (N'Planned', N'Queued', N'Generating', N'Generated', N'Approved');
        RETURN;
    END;

    INSERT dbo.IllustrationLibraryItems
        (Category, StableCode, DisplayTitle, ShortDescription, MetadataJson, SpecificationJson, Status)
    VALUES
        (@Category, @StableCode, @DisplayTitle, @ShortDescription, @MetadataJson, @SpecificationJson, N'Planned');

    SELECT * FROM dbo.IllustrationLibraryItems WHERE IllustrationLibraryItemID = SCOPE_IDENTITY();
END;
GO

CREATE OR ALTER PROCEDURE dbo.IllustrationLibraryItem_Queue
    @IllustrationLibraryItemID int = NULL,
    @Category nvarchar(40) = NULL
AS
BEGIN
    SET NOCOUNT ON;

    UPDATE dbo.IllustrationLibraryItems
    SET Status = N'Queued',
        QueuedUtc = SYSUTCDATETIME(),
        UpdatedUtc = SYSUTCDATETIME(),
        LastError = NULL
    WHERE (@IllustrationLibraryItemID IS NULL OR IllustrationLibraryItemID = @IllustrationLibraryItemID)
        AND (@Category IS NULL OR Category = @Category)
        AND Status IN (N'Planned', N'Failed', N'Rejected')
        AND IsActive = 1;

    SELECT @@ROWCOUNT AS AffectedRows;
END;
GO

CREATE OR ALTER PROCEDURE dbo.IllustrationLibraryItem_ClaimNext
AS
BEGIN
    SET NOCOUNT ON;
    SET XACT_ABORT ON;

    BEGIN TRANSACTION;

    DECLARE @Claimed TABLE (IllustrationLibraryItemID int NOT NULL);

    ;WITH nextItem AS
    (
        SELECT TOP (1) *
        FROM dbo.IllustrationLibraryItems WITH (UPDLOCK, READPAST, ROWLOCK)
        WHERE Status = N'Queued' AND IsActive = 1
        ORDER BY QueuedUtc, IllustrationLibraryItemID
    )
    UPDATE nextItem
    SET Status = N'Generating',
        AttemptCount = AttemptCount + 1,
        StartedUtc = SYSUTCDATETIME(),
        UpdatedUtc = SYSUTCDATETIME()
    OUTPUT inserted.IllustrationLibraryItemID INTO @Claimed;

    SELECT item.*
    FROM dbo.IllustrationLibraryItems item
    INNER JOIN @Claimed claimed ON claimed.IllustrationLibraryItemID = item.IllustrationLibraryItemID;

    COMMIT TRANSACTION;
END;
GO

CREATE OR ALTER PROCEDURE dbo.IllustrationLibraryItem_MarkGenerated
    @IllustrationLibraryItemID int,
    @FilePath nvarchar(500),
    @ThumbnailPath nvarchar(500),
    @Width int,
    @Height int,
    @FileSizeBytes bigint,
    @MimeType nvarchar(100),
    @Provider nvarchar(80),
    @Model nvarchar(120),
    @PromptText nvarchar(max),
    @PromptTemplateVersion nvarchar(40),
    @ProviderRequestID nvarchar(160) = NULL
AS
BEGIN
    SET NOCOUNT ON;

    UPDATE dbo.IllustrationLibraryItems
    SET Status = N'Generated',
        FilePath = @FilePath,
        ThumbnailPath = @ThumbnailPath,
        Width = @Width,
        Height = @Height,
        FileSizeBytes = @FileSizeBytes,
        MimeType = @MimeType,
        Provider = @Provider,
        Model = @Model,
        PromptText = @PromptText,
        PromptTemplateVersion = @PromptTemplateVersion,
        ProviderRequestID = @ProviderRequestID,
        CompletedUtc = SYSUTCDATETIME(),
        UpdatedUtc = SYSUTCDATETIME(),
        LastError = NULL
    WHERE IllustrationLibraryItemID = @IllustrationLibraryItemID
        AND Status = N'Generating';
END;
GO

CREATE OR ALTER PROCEDURE dbo.IllustrationLibraryItem_MarkFailed
    @IllustrationLibraryItemID int,
    @LastError nvarchar(1000)
AS
BEGIN
    SET NOCOUNT ON;

    UPDATE dbo.IllustrationLibraryItems
    SET Status = N'Failed',
        LastError = @LastError,
        CompletedUtc = SYSUTCDATETIME(),
        UpdatedUtc = SYSUTCDATETIME()
    WHERE IllustrationLibraryItemID = @IllustrationLibraryItemID
        AND Status = N'Generating';
END;
GO

CREATE OR ALTER PROCEDURE dbo.IllustrationLibraryItem_Approve
    @IllustrationLibraryItemID int,
    @ApprovedByUserID int
AS
BEGIN
    SET NOCOUNT ON;

    DECLARE @StableCode nvarchar(120);
    SELECT @StableCode = StableCode FROM dbo.IllustrationLibraryItems WHERE IllustrationLibraryItemID = @IllustrationLibraryItemID;

    UPDATE dbo.IllustrationLibraryItems
    SET IsApproved = 0,
        Status = CASE WHEN Status = N'Approved' THEN N'Generated' ELSE Status END,
        UpdatedUtc = SYSUTCDATETIME()
    WHERE StableCode = @StableCode
        AND IllustrationLibraryItemID <> @IllustrationLibraryItemID
        AND Status = N'Approved';

    UPDATE dbo.IllustrationLibraryItems
    SET Status = N'Approved',
        IsApproved = 1,
        ApprovedUtc = SYSUTCDATETIME(),
        ApprovedByUserID = @ApprovedByUserID,
        UpdatedUtc = SYSUTCDATETIME()
    WHERE IllustrationLibraryItemID = @IllustrationLibraryItemID
        AND Status = N'Generated'
        AND FilePath IS NOT NULL;
END;
GO

CREATE OR ALTER PROCEDURE dbo.IllustrationLibraryItem_Reject
    @IllustrationLibraryItemID int,
    @RejectionReason nvarchar(500) = NULL
AS
BEGIN
    SET NOCOUNT ON;

    UPDATE dbo.IllustrationLibraryItems
    SET Status = N'Rejected',
        IsApproved = 0,
        RejectionReason = @RejectionReason,
        UpdatedUtc = SYSUTCDATETIME()
    WHERE IllustrationLibraryItemID = @IllustrationLibraryItemID
        AND Status IN (N'Generated', N'Approved');
END;
GO

CREATE OR ALTER PROCEDURE dbo.IllustrationLibraryItem_Disable
    @IllustrationLibraryItemID int
AS
BEGIN
    SET NOCOUNT ON;

    UPDATE dbo.IllustrationLibraryItems
    SET Status = N'Disabled',
        IsActive = 0,
        IsApproved = 0,
        UpdatedUtc = SYSUTCDATETIME()
    WHERE IllustrationLibraryItemID = @IllustrationLibraryItemID;
END;
GO

CREATE OR ALTER PROCEDURE dbo.IllustrationLibraryItem_UpdateMetadata
    @IllustrationLibraryItemID int,
    @DisplayTitle nvarchar(200),
    @ShortDescription nvarchar(500) = NULL,
    @MetadataJson nvarchar(max) = NULL,
    @AdminNotes nvarchar(1000) = NULL
AS
BEGIN
    SET NOCOUNT ON;

    UPDATE dbo.IllustrationLibraryItems
    SET DisplayTitle = @DisplayTitle,
        ShortDescription = @ShortDescription,
        MetadataJson = @MetadataJson,
        AdminNotes = @AdminNotes,
        UpdatedUtc = SYSUTCDATETIME()
    WHERE IllustrationLibraryItemID = @IllustrationLibraryItemID;
END;
GO

CREATE OR ALTER PROCEDURE dbo.IllustrationLibraryItem_GetApproved
AS
BEGIN
    SET NOCOUNT ON;

    SELECT *
    FROM dbo.IllustrationLibraryItems
    WHERE Status = N'Approved'
        AND IsApproved = 1
        AND IsActive = 1
        AND FilePath IS NOT NULL
    ORDER BY StableCode, ApprovedUtc DESC;
END;
GO
