using NUnit.Framework;
using System.Net.Http;
using System.Collections.Generic;
using System.Linq;
using OpenQA.Selenium;

namespace AOW4.SeleniumTests.Tests;

[TestFixture]
public class BrokenLinksTest : BaseTest
{
    [Test]
    public void ScanAndReportBrokenLinks()
    {
        GoHome();

        var anchors = Driver.FindElements(By.CssSelector("a[href]"))
            .Select(a => a.GetAttribute("href") ?? string.Empty)
            .Where(h => !string.IsNullOrWhiteSpace(h))
            .Distinct()
            .ToList();

        var failures = new List<string>();
        using var client = new HttpClient();

        foreach (var raw in anchors)
        {
            if (raw.StartsWith("javascript:", System.StringComparison.OrdinalIgnoreCase))
                continue;
            if (raw.StartsWith("mailto:", System.StringComparison.OrdinalIgnoreCase))
                continue;

            System.Uri uri;
            try
            {
                uri = new System.Uri(raw, System.UriKind.RelativeOrAbsolute);
                if (!uri.IsAbsoluteUri)
                {
                    uri = new System.Uri(new System.Uri(BaseUrl), raw);
                }
            }
            catch
            {
                failures.Add($"Invalid URI: {raw}");
                continue;
            }

            try
            {
                using var req = new HttpRequestMessage(HttpMethod.Head, uri);
                var resp = client.Send(req);
                if (!resp.IsSuccessStatusCode)
                {
                    // try GET as fallback
                    using var greq = new HttpRequestMessage(HttpMethod.Get, uri);
                    var gresp = client.Send(greq);
                    if (!gresp.IsSuccessStatusCode)
                    {
                        failures.Add($"{(int)gresp.StatusCode} {uri}");
                    }
                }
            }
            catch (System.Exception ex)
            {
                failures.Add($"Error checking {uri}: {ex.Message}");
            }
        }

        if (failures.Any())
        {
            Assert.Fail("Broken links found:\n" + string.Join("\n", failures));
        }
    }
}
