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

namespace PlotLine.Data;

public interface IProjectRestorePointRepository
{
    Task<IReadOnlyList<ProjectRestorePoint>> ListAsync(int projectId);
    Task<ProjectRestorePoint?> GetAsync(int projectRestorePointId, int projectId);
    Task<int> CountAsync(int projectId);
    Task<ProjectRestorePoint> CreateAsync(int projectId, string restorePointName, string restorePointType, string jsonData, string? notes);
    Task<bool> DeleteAsync(int projectRestorePointId, int projectId);
    Task RestoreAsync(int projectId, int sourceRestorePointId, int safetyRestorePointId, string jsonData);
}

public sealed class ProjectRestorePointRepository(ISqlConnectionFactory connectionFactory) : IProjectRestorePointRepository
{
    public async Task<IReadOnlyList<ProjectRestorePoint>> ListAsync(int projectId)
    {
        using var connection = connectionFactory.CreateConnection();
        var rows = await connection.QueryAsync<ProjectRestorePoint>(
            "dbo.ProjectRestorePoint_List",
            new { ProjectID = projectId },
            commandType: CommandType.StoredProcedure);
        return rows.ToList();
    }

    public async Task<ProjectRestorePoint?> GetAsync(int projectRestorePointId, int projectId)
    {
        using var connection = connectionFactory.CreateConnection();
        return await connection.QuerySingleOrDefaultAsync<ProjectRestorePoint>(
            "dbo.ProjectRestorePoint_Get",
            new { ProjectRestorePointID = projectRestorePointId, ProjectID = projectId },
            commandType: CommandType.StoredProcedure);
    }

    public async Task<int> CountAsync(int projectId)
    {
        using var connection = connectionFactory.CreateConnection();
        return await connection.QuerySingleAsync<int>(
            "dbo.ProjectRestorePoint_Count",
            new { ProjectID = projectId },
            commandType: CommandType.StoredProcedure);
    }

    public async Task<ProjectRestorePoint> CreateAsync(int projectId, string restorePointName, string restorePointType, string jsonData, string? notes)
    {
        using var connection = connectionFactory.CreateConnection();
        return await connection.QuerySingleAsync<ProjectRestorePoint>(
            "dbo.ProjectRestorePoint_Create",
            new
            {
                ProjectID = projectId,
                RestorePointName = restorePointName,
                RestorePointType = restorePointType,
                JsonData = jsonData,
                Notes = notes
            },
            commandType: CommandType.StoredProcedure);
    }

    public async Task<bool> DeleteAsync(int projectRestorePointId, int projectId)
    {
        using var connection = connectionFactory.CreateConnection();
        return await connection.QuerySingleAsync<bool>(
            "dbo.ProjectRestorePoint_Delete",
            new { ProjectRestorePointID = projectRestorePointId, ProjectID = projectId },
            commandType: CommandType.StoredProcedure);
    }

    public async Task RestoreAsync(int projectId, int sourceRestorePointId, int safetyRestorePointId, string jsonData)
    {
        using var connection = connectionFactory.CreateConnection();
        await connection.ExecuteAsync(
            "dbo.ProjectRestore_ApplyFromJson",
            new
            {
                ProjectID = projectId,
                SourceRestorePointID = sourceRestorePointId,
                SafetyRestorePointID = safetyRestorePointId,
                JsonData = jsonData
            },
            commandType: CommandType.StoredProcedure,
            commandTimeout: 180);
    }
}
