using Hc900Crawler.Core.Application.DTOs;
using Hc900Crawler.Core.Application.Interfaces;
using Hc900Crawler.Core.Domain.Entities;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using System;
using System.Threading.Tasks;

namespace Hc900Crawler.Infrastructure.Database;

public class DbStatusStore : IStatusStore
{
    private readonly IDbContextFactory<Hc900DbContext> _contextFactory;
    private readonly ILogger<DbStatusStore> _logger;

    public DbStatusStore(IDbContextFactory<Hc900DbContext> contextFactory, ILogger<DbStatusStore> logger)
    {
        _contextFactory = contextFactory;
        _logger = logger;
    }

    public async Task<AnalysisStatus?> GetStatusAsync(string taskId)
    {
        try
        {
            using var ctx = _contextFactory.CreateDbContext();
            var status = await ctx.PidGraphStatuses
                .FirstOrDefaultAsync(x => x.TaskId == taskId);

            if (status == null) return null;

            return new AnalysisStatus(
                status.TaskId,
                status.Progress,
                status.Status,
                status.Message
            );
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "[DbStatusStore] GetStatusAsync 실패: {TaskId}", taskId);
            return null;
        }
    }

    public async Task UpdateStatusAsync(AnalysisStatus status)
    {
        try
        {
            using var ctx = _contextFactory.CreateDbContext();
            var existing = await ctx.PidGraphStatuses
                .FirstOrDefaultAsync(x => x.TaskId == status.TaskId);

            if (existing == null)
            {
                ctx.PidGraphStatuses.Add(new PidGraphStatus
                {
                    TaskId = status.TaskId,
                    Progress = status.Progress,
                    Status = status.Status,
                    Message = status.Message,
                    UpdatedAt = DateTime.UtcNow
                });
            }
            else
            {
                existing.Progress = status.Progress;
                existing.Status = status.Status;
                existing.Message = status.Message;
                existing.UpdatedAt = DateTime.UtcNow;
            }

            await ctx.SaveChangesAsync();
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "[DbStatusStore] UpdateStatusAsync 실패: {TaskId}", status.TaskId);
        }
    }

    public async Task RemoveStatusAsync(string taskId)
    {
        try
        {
            using var ctx = _contextFactory.CreateDbContext();
            var status = await ctx.PidGraphStatuses
                .FirstOrDefaultAsync(x => x.TaskId == taskId);

            if (status != null)
            {
                ctx.PidGraphStatuses.Remove(status);
                await ctx.SaveChangesAsync();
            }
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "[DbStatusStore] RemoveStatusAsync 실패: {TaskId}", taskId);
        }
    }
}
