using System;
using System.Collections.Generic;
using System.Linq;
using isnd.Data.Packages;
using Newtonsoft.Json;
using NuGet.Versioning;

namespace isnd.Data.Catalog
{
    public class CatalogPage : Permalink
    {
        private readonly string pkgid;
        private readonly List<Package> items;

        private readonly string apiBase;


        public CatalogPage (string pkgid, string apiBase) : base(apiBase + $"/registration/{pkgid}/index.json")
        {
            Parent = apiBase + $"/registration/{pkgid}/index.json";
            this.items = new List<Package>();
            this.pkgid = pkgid;
            this.apiBase = apiBase;
        }

        public CatalogPage(string bid, string pkgid, string apiBase, List<PackageVersion> versions) : this(pkgid, apiBase)
        {
             AddVersionRange(versions);
        }

        public string GetPackageId()
        {
            return pkgid;
        }

        /// <summary>
        /// The array of registration leaves and their associate metadata
        /// </summary>
        /// <value></value>
        [JsonProperty("items")]

        public Package[] Items { get => items.ToArray(); }

        public void AddVersionRange(IEnumerable<PackageVersion> vitems)
        {
            if (vitems.Count() == 0) return;
            NuGetVersion upper = null;
            NuGetVersion lower = null;
            PackageVersion latest = null;
            if (Lower!=null) lower = new NuGetVersion(Lower);
            if (Upper!=null) upper = new NuGetVersion(Upper);

            // Assert.True(items.All(p=>p.Id == id));
            long commitMax = 0;
            foreach (var p in vitems)
            {
                var pkg = p.ToPackage(apiBase);
                if (items.Contains(pkg)) continue;

                if (upper == null) upper = p.NugetVersion;
                else if ( upper < p.NugetVersion) upper = p.NugetVersion;

                if (lower == null) lower = p.NugetVersion;
                else if (lower > p.NugetVersion) lower = p.NugetVersion;

                if (p.CommitNId > commitMax)
                 {
                    latest = p;
                 } 
                items.Add(pkg);
            }
            Upper = upper.ToFullString();
            Lower = lower.ToFullString();
        }

        /// <summary>
        /// The highest SemVer 2.0.0 version in the page (inclusive)
        /// </summary>
        /// <value></value>
        [JsonProperty("upper"), JsonRequired]
        public string Upper { get; private set; }
        /// <summary>
        /// The lowest SemVer 2.0.0 version in the page (inclusive)
        /// </summary>
        /// <value></value>
        [JsonProperty("lower"), JsonRequired]
        public string Lower { get; private set; }

        /// <summary>
        /// The URL to the registration index
        /// </summary>
        /// <value></value>
        [JsonProperty("parent")]
        public string Parent { get; set; }

        [JsonProperty("count")]
        public int Count { get => items.Count; }
    }
}