using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.Playwright;

namespace TestersAI.PlaywrightSupport;

public sealed class TestersAIPage
{
    private readonly IPage _page;
    private readonly TestersAIClient _client;
    private readonly List<Action<AnalysisResult>> _sinks;
    private readonly List<IDictionary<string, object?>> _console = new();
    private readonly List<IDictionary<string, object?>> _network = new();

    public TestersAIPage(IPage page, Action<AnalysisResult>? frameworkLog = null)
    {
        _page = page;
        var cfg = Config.FromEnv();
        _client = new TestersAIClient(cfg);
        _sinks = Sinks.Build(cfg, frameworkLog);
        page.Console += (_, m) => _console.Add(new Dictionary<string, object?> {
            ["level"] = m.Type, ["text"] = m.Text });
        page.PageError += (_, e) => _console.Add(new Dictionary<string, object?> {
            ["level"] = "error", ["text"] = e });
        page.Response += (_, r) =>
        {
            try
            {
                _network.Add(new Dictionary<string, object?> {
                    ["url"] = r.Url, ["status"] = r.Status, ["method"] = r.Request.Method });
            }
            catch { }
        };
    }

    IReadOnlyDictionary<string, object?> Ctx()
    {
        try { return new Dictionary<string, object?> { ["url"] = _page.Url }; }
        catch { return new Dictionary<string, object?>(); }
    }

    public async Task<AnalysisResult> AnalyzeScreenshotAsync()
    {
        var bytes = await _page.ScreenshotAsync(new PageScreenshotOptions { FullPage = true });
        return Sinks.Dispatch(await _client.AnalyzeScreenshotAsync(bytes, Ctx()), _sinks);
    }

    public async Task<AnalysisResult> AnalyzeConsoleAsync()
        => Sinks.Dispatch(await _client.AnalyzeConsoleAsync(_console, Ctx()), _sinks);

    public async Task<AnalysisResult> AnalyzeNetworkAsync()
        => Sinks.Dispatch(await _client.AnalyzeNetworkAsync(_network, Ctx()), _sinks);

    public async Task<AnalysisResult> AnalyzePageTextAsync()
    {
        var text = await _page.ContentAsync();
        return Sinks.Dispatch(await _client.AnalyzePageTextAsync(text, Ctx()), _sinks);
    }
}
