using HtmlAgilityPack;

namespace JSMR.Infrastructure.Scanning.Models;

public class DLSiteHtmlNode
{
    public HtmlNode LeftNode { get; }
    public HtmlNode RightNode { get; }
    public HtmlNode ThumbNode { get; }

    public HtmlNode ProductNode { get; private set; }
    public HtmlNode ProductLinkNode { get; private set; }
    public HtmlNode ProductTextNode { get; private set; }
    public HtmlNode? DescriptionNode { get; private set; }
    public HtmlNode MakerNode { get; private set; }
    public HtmlNode MakerLinkNode { get; private set; }
    public HtmlNode? ExpectedDateNode { get; private set; }
    public HtmlNode? WorkInfoBox { get; private set; }
    public HtmlNode? SalesDateNode { get; private set; }
    public HtmlNode DownloadsNode { get; private set; }
    public HtmlNode? StarRatingNode { get; private set; }
    public HtmlNode? ImageNode { get; private set; }
    public HtmlNode? ThumbWithNgFilterBlockNode { get; private set; }
    public HtmlNode[] GenreNodes { get; private set; }
    public HtmlNode[] SearchTagNodes { get; private set; }
    public HtmlNode[] CreatorNodes { get; private set; }

    public DLSiteHtmlNode(HtmlNode leftNode, HtmlNode rightNode, HtmlNode thumbNode)
    {
        LeftNode = leftNode;
        RightNode = rightNode;
        ThumbNode = thumbNode;

        ProductNode = LeftNode.SelectNodes(".//dt[@class='work_name']")[0];
        ProductLinkNode = ProductNode.SelectNodes(".//a")[0];
        ProductTextNode = GetProductTextNode();

        //DescriptionNode = LeftNode.SelectNodes(".//dd[@class='work_text']")[0];
        DescriptionNode = LeftNode.SelectNodes(".//dd[@class='work_text']")?.FirstOrDefault();

        MakerNode = LeftNode.SelectNodes(".//dd[@class='maker_name']")[0];
        MakerLinkNode = MakerNode.SelectNodes(".//a[contains(@href, 'maker_id')]")[0];

        //ExpectedDateNode = GetExpectedDateNode();
        ExpectedDateNode = ProductNode.SelectNodes(".//p[@class='expected_date']")?.FirstOrDefault();

        GenreNodes = GetGenreNodes();
        SearchTagNodes = GetSearchTagNodes();
        CreatorNodes = GetCreatorNodes();
        WorkInfoBox = RightNode.SelectNodes(".//ul[@class='work_info_box']")?.FirstOrDefault();
        SalesDateNode = WorkInfoBox?.SelectNodes(".//li[@class='sales_date']")?.FirstOrDefault();

        // TODO: Fix!
        //DownloadsNode = RightNode.SelectSingleNode(".//span[@class='_dl_count_" + works[rightsIndex].ProductId + "']");
        DownloadsNode = RightNode.SelectSingleNode(".//span[contains(@class, '_dl_count_')]");

        //InitializeSalesAndDownloadsNodes();
        StarRatingNode = GetStarRatingNode();
        ImageNode = TryGetImageNode();
        ThumbWithNgFilterBlockNode = ThumbNode.SelectSingleNode(".//thumb-with-ng-filter-block");
    }

    private HtmlNode[] GetGenreNodes()
    {
        HtmlNode genreNode = LeftNode.SelectNodes(".//dd[@class='work_genre']")[0];

        return [.. genreNode.SelectNodes(".//span")];
    }

    private HtmlNode[] GetSearchTagNodes()
    {
        HtmlNodeCollection searchTagNodes = LeftNode.SelectNodes(".//dd[@class='search_tag']");

        if (searchTagNodes == null || searchTagNodes.Count == 0)
        {
            return [];
        }
        else
        {
            HtmlNodeCollection searchTagNodesLinks = searchTagNodes[0].SelectNodes(".//a");

            if (searchTagNodesLinks == null || searchTagNodesLinks.Count == 0)
            {
                return [];
            }
            else
            {
                return [.. searchTagNodesLinks];
            }
        }
    }

    private HtmlNode[] GetCreatorNodes()
    {
        HtmlNodeCollection creatorNodes = MakerNode.SelectNodes(".//a[contains(@href, 'keyword_creater')]");

        if (creatorNodes == null || creatorNodes.Count == 0)
        {
            return [];
        }
        else
        {
            return [.. creatorNodes];
        }
    }

    //private void InitializeSalesAndDownloadsNodes()
    //{
    //    HtmlNodeCollection workInfoBox = RightNode.SelectNodes(".//ul[@class='work_info_box']");

    //    if (workInfoBox != null)
    //    {
    //        HtmlNodeCollection salesDateNodes = workInfoBox[0].SelectNodes(".//li[@class='sales_date']");

    //        if (salesDateNodes != null && salesDateNodes.Count > 0)
    //        {
    //            SalesDateNode = salesDateNodes[0];
    //        }

    //        // TODO: Fix!
    //        //DownloadsNode = RightNode.SelectSingleNode(".//span[@class='_dl_count_" + works[rightsIndex].ProductId + "']");
    //        DownloadsNode = RightNode.SelectSingleNode(".//span[contains(@class, '_dl_count_')]");
    //    }
    //}

    //private HtmlNode? GetSalesDateNode()
    //{
    //    if (WorkInfoBox is null)
    //        return null;

    //    return WorkInfoBox.SelectNodes(".//li[@class='sales_date']").FirstOrDefault();
    //}

    private HtmlNode? GetStarRatingNode()
    {
        var ratingsNode = RightNode.SelectSingleNode(".//li[@class='work_rating']");

        if (ratingsNode == null)
            return null;

        return ratingsNode.SelectSingleNode(".//div[contains(@class, 'star_rating')]");
    }

    private HtmlNode GetProductTextNode()
    {
        if (ProductLinkNode.ChildNodes.Count > 1 && ProductLinkNode.ChildNodes[0].Name == "#text")
        {
            return ProductLinkNode.ChildNodes[0];
        }
        else
        {
            return ProductLinkNode;
        }
    }

    //private HtmlNode? GetExpectedDateNode()
    //{
    //    HtmlNodeCollection expectedDateNodes = ProductNode.SelectNodes(".//p[@class='expected_date']").FirstOrDefault();

    //    if (expectedDateNodes != null && expectedDateNodes.Count > 0)
    //    {
    //        return expectedDateNodes[0];
    //    }
    //    else
    //    {
    //        return null;
    //    }
    //}

    private HtmlNode? TryGetImageNode()
    {
        HtmlNode? linkNode = ThumbNode.SelectSingleNode(".//a");

        if (linkNode is null)
            return null;

        return linkNode.SelectSingleNode(".//img");
    }
}