using Application.Abstractions.Data;
using Application.Abstractions.Messaging;
using Application.Abstractions.YouTube;
using Microsoft.EntityFrameworkCore;
using SharedKernel.Results;

namespace Application.Features.Api.Studio.GetSettings;

internal sealed class Handler(IAppDbContext db, IYouTubeChannelCache channelCache) : IQueryHandler<Query, Result<Response>>
{
    private static readonly Response Empty = new(false, null, null, null, null, null, null, 0, 0, 0, null);

    public async Task<Result<Response>> Handle(Query request, CancellationToken ct)
    {
        var channel = await db.Channel.AsNoTracking().FirstOrDefaultAsync(c => c.MemberID == request.MemberID && c.IsActive, ct);

        if (channel is null)
        {
            return Result.Success(Empty);
        }

        // 채널 레코드가 존재하면 YouTube 연동된 상태
        // SID = YouTube 채널 ID (캐시 키로 사용)
        var ytChannelID = channel.YouTubeChannelID ?? channel.SID;
        var ytInfo = await channelCache.GetAsync(ytChannelID);

        if (ytInfo is not null)
        {
            // 캐시 데이터가 DB와 다르면 DB 동기화
            if (ytInfo.Title != channel.Name
                || ytInfo.SubscriberCount != channel.SubscriberCount
                || ytInfo.VideoCount != channel.VideoCount
                || ytInfo.ViewCount != channel.ViewCount
                || channel.YouTubeChannelID is null)
            {
                var tracked = await db.Channel.FindAsync([channel.ID], ct);
                if (tracked is not null)
                {
                    tracked.UpdateYouTubeInfo(
                        ytInfo.ChannelID, ytInfo.Title, ytInfo.CustomUrl,
                        ytInfo.Description, ytInfo.ThumbnailUrl, ytInfo.BannerUrl,
                        ytInfo.SubscriberCount, ytInfo.VideoCount, ytInfo.ViewCount,
                        ytInfo.Email, ytInfo.PublishedAt);
                    await db.SaveChangesAsync(ct);
                }
            }

            return Result.Success(new Response(
                true,
                ytInfo.Title,
                ytInfo.CustomUrl,
                ytInfo.Description,
                channel.YouTubeUrl,
                ytInfo.ThumbnailUrl,
                ytInfo.BannerUrl,
                ytInfo.SubscriberCount,
                ytInfo.VideoCount,
                ytInfo.ViewCount,
                ytInfo.PublishedAt));
        }

        // 캐시 미스 → DB 데이터로 응답
        var isConnected = channel.YouTubeChannelID is not null;

        return Result.Success(new Response(
            isConnected,
            channel.Name,
            channel.Handle,
            channel.Description,
            channel.YouTubeUrl,
            channel.ThumbnailUrl,
            channel.BannerUrl,
            channel.SubscriberCount,
            channel.VideoCount,
            channel.ViewCount,
            channel.YouTubePublishedAt));
    }
}