using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using skyscraper5.Dvb.Descriptors;

namespace skyscraper5.Dvb.Psi.Model
{
    public class BatBouquet
    {
        public ushort BouquetId { get; }

        //0x47 Bouquet Name Descriptor
        public string BouquetName { get; set; }

        //0x4A Linkage Descriptor
        public List<LinkageDescriptor> Linkages { get; set; }

        //0x49 Country Availability Descriptor
        public Dictionary<string, bool> CountryAvailabilityDictionary { get; }

        //0x5f Private Data Specifier Descriptor
        public uint? PrivateDataSpecifier { get; set; }

        //extension 0x13 uri linkage descriptor
        public byte? UriLinkageType { get; set; }
        public string Uri { get; set; }
        public ushort? MinPollingInterval { get; set; }

        //0x5b multilingual network name descriptor
        public MultilingualBouquetNameDescriptor MultilingualBouquetName { get; set; }

        //0x7e fta content management descriptor
        public int? ControlRemoteAccessOverInternet { get; set; }
        public bool? DoNotApplyRevocation { get; set; }
        public bool? DoNotScramble { get; set; }
		public ReadOnlyCollection<BatTransportStream> TransportStreams { get; internal set; }

		public BatBouquet(ushort bouquetId)
        {
            BouquetId = bouquetId;
            Linkages = new List<LinkageDescriptor>();
            CountryAvailabilityDictionary = new Dictionary<string, bool>();
        }

        public bool NeedUpdate(BatBouquet other)
        {
            if ("Irdeto BAT".Equals(this.BouquetName) && "IrĦeto BAT".Equals(other.BouquetName))
                return false;

            if (this.BouquetName != null)
            {
                if (other.BouquetName != null)
                    if (!this.BouquetName.Equals(other.BouquetName))
                        return true;
            }
            
            if (other.PrivateDataSpecifier.HasValue)
                if (this.PrivateDataSpecifier != other.PrivateDataSpecifier)
                    return true;

            if (!this.UriLinkageType.HasValue && other.UriLinkageType.HasValue)
                return true;

            if (this.Uri != null)
                if (other.Uri != null)
                    if (!this.Uri.Equals(other.Uri))
                        return true;

            if (this.MinPollingInterval != other.MinPollingInterval)
                return true;

            if (other.MultilingualBouquetName != null && this.MultilingualBouquetName == null)
                return true;

            if (other.MultilingualBouquetName != null)
            {
                if (other.MultilingualBouquetName.MultilingualBouquetName.Count > 0 && this.MultilingualBouquetName.MultilingualBouquetName.Count == 0)
                    return true;
            }

            if (other.MultilingualBouquetName != null && this.MultilingualBouquetName != null)
            {
                foreach (KeyValuePair<string, string> keyValuePair in other.MultilingualBouquetName.MultilingualBouquetName)
                {
                    bool found = false;
                    foreach (KeyValuePair<string, string> innerKv in this.MultilingualBouquetName
                                 .MultilingualBouquetName)
                    {
                        if (innerKv.Key.Equals(keyValuePair.Key))
                            found = true;
                    }

                    if (!found)
                        return true;
                }
            }

            if (this.ControlRemoteAccessOverInternet != other.ControlRemoteAccessOverInternet)
                return true;

            if (this.DoNotApplyRevocation != other.DoNotApplyRevocation)
                return true;

            if (this.DoNotScramble != other.DoNotScramble)
                return true;

            return false;
        }

        public string TryGetName()
        {
            if (!string.IsNullOrEmpty(BouquetName))
                return BouquetName;

            if (MultilingualBouquetName != null)
            {
                foreach (KeyValuePair<string, string> keyValuePair in MultilingualBouquetName.MultilingualBouquetName)
                {
                    return keyValuePair.Value;
                }
            }

            return String.Format("??? (0x{0:X4})", BouquetId);
        }
    }
}
