using System.Data;
using Dapper;
using PlotLine.Models;

namespace PlotLine.Data;

public interface IStoryIntelligencePipelineRepository
{
    Task<StoryIntelligenceBookPipelineState?> GetByIdForUserAsync(int importSessionId, int userId);
    Task<StoryIntelligenceBookPipelineState?> GetByBookAsync(int bookId);
    Task<StoryIntelligenceBookPipelineState?> GetByBookForUserAsync(int bookId, int userId);
    Task<IReadOnlyList<StoryIntelligenceBookPipelineState>> ListForUserAsync(int userId);
    Task<StoryIntelligenceBookPipelineState> UpsertAsync(StoryIntelligenceBookPipelineSaveRequest request);
    Task<IReadOnlyList<StoryIntelligenceCommittedRunSummary>> ListCommittedRunsByBookAsync(int bookId, int userId);
}

public sealed class StoryIntelligencePipelineRepository(ISqlConnectionFactory connectionFactory) : IStoryIntelligencePipelineRepository
{
    public async Task<StoryIntelligenceBookPipelineState?> GetByIdForUserAsync(int importSessionId, int userId)
    {
        using var connection = connectionFactory.CreateConnection();
        return await connection.QuerySingleOrDefaultAsync<StoryIntelligenceBookPipelineState>(
            "dbo.StoryIntelligenceBookPipeline_GetByIDForUser",
            new { StoryIntelligenceBookPipelineID = importSessionId, UserID = userId },
            commandType: CommandType.StoredProcedure);
    }

    public async Task<StoryIntelligenceBookPipelineState?> GetByBookAsync(int bookId)
    {
        using var connection = connectionFactory.CreateConnection();
        return await connection.QuerySingleOrDefaultAsync<StoryIntelligenceBookPipelineState>(
            "dbo.StoryIntelligenceBookPipeline_GetByBook",
            new { BookID = bookId },
            commandType: CommandType.StoredProcedure);
    }

    public async Task<StoryIntelligenceBookPipelineState?> GetByBookForUserAsync(int bookId, int userId)
    {
        using var connection = connectionFactory.CreateConnection();
        return await connection.QuerySingleOrDefaultAsync<StoryIntelligenceBookPipelineState>(
            "dbo.StoryIntelligenceBookPipeline_GetByBookForUser",
            new { BookID = bookId, UserID = userId },
            commandType: CommandType.StoredProcedure);
    }

    public async Task<IReadOnlyList<StoryIntelligenceBookPipelineState>> ListForUserAsync(int userId)
    {
        using var connection = connectionFactory.CreateConnection();
        var rows = await connection.QueryAsync<StoryIntelligenceBookPipelineState>(
            "dbo.StoryIntelligenceBookPipeline_ListForUser",
            new { UserID = userId },
            commandType: CommandType.StoredProcedure);
        return rows.ToList();
    }

    public async Task<StoryIntelligenceBookPipelineState> UpsertAsync(StoryIntelligenceBookPipelineSaveRequest request)
    {
        using var connection = connectionFactory.CreateConnection();
        return await connection.QuerySingleAsync<StoryIntelligenceBookPipelineState>(
            "dbo.StoryIntelligenceBookPipeline_Upsert",
            new
            {
                request.ProjectID,
                request.BookID,
                request.CurrentStage,
                request.LastCompletedStage,
                request.CurrentReviewStage,
                request.Status,
                request.CompletedUtc,
                request.LastRunID
            },
            commandType: CommandType.StoredProcedure);
    }

    public async Task<IReadOnlyList<StoryIntelligenceCommittedRunSummary>> ListCommittedRunsByBookAsync(int bookId, int userId)
    {
        using var connection = connectionFactory.CreateConnection();
        var rows = await connection.QueryAsync<StoryIntelligenceCommittedRunSummary>(
            "dbo.StoryIntelligenceBookPipeline_ListCommittedRunsByBook",
            new { BookID = bookId, UserID = userId },
            commandType: CommandType.StoredProcedure);
        return rows.ToList();
    }
}
