using AIStudio.Wpf.DiagramDesigner;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Serialization;
using AIStudio.Wpf.Flowchart;
using AIStudio.Wpf.DiagramHelper.Extensions.ViewModels;
using AIStudio.Wpf.DiagramHelper.Extensions.Models;
using Newtonsoft.Json;
using AIStudio.Wpf.Flowchart.Models;
using AIStudio.Wpf.Flowchart.ViewModels;
using AIStudio.Wpf.SFC.Models;
using AIStudio.Wpf.SFC.ViewModels;
using System.Windows;
using System.Windows.Media;

namespace AIStudio.Wpf.DiagramApp.Models
{
    [Serializable]
    public class DiagramItem
    {
        public DiagramItem()
        {
            this.ConnectionIds = new List<Guid>();
            this.Connections = new List<ConnectionItem>();
        }

        [XmlAttribute]
        public string Name { get; set; }

        [XmlAttribute]
        public DiagramType DiagramType { get; set; }

        [XmlAttribute]
        public bool ShowGrid { get; set; }

        [XmlIgnore]
        public Size GridCellSize { get; set; }

        [JsonIgnore]
        [XmlAttribute("GridCellSize")]
        public string XmlGridCellSize
        {
            get
            {
                return SerializeHelper.SerializeSize(GridCellSize);
            }
            set
            {
                GridCellSize = SerializeHelper.DeserializeSize(value);
            }
        }

        [XmlAttribute]
        public CellHorizontalAlignment CellHorizontalAlignment { get; set; }

        [XmlAttribute]
        public CellVerticalAlignment CellVerticalAlignment { get; set; }

        [XmlAttribute]
        public PageSizeOrientation PageSizeOrientation { get; set; }

        [XmlIgnore]
        public Size PageSize { get; set; }

        [JsonIgnore]
        [XmlAttribute("PageSize")]
        public string XmlPageSize
        {
            get
            {
                return SerializeHelper.SerializeSize(PageSize);
            }
            set
            {
                PageSize = SerializeHelper.DeserializeSize(value);
            }
        }

        [XmlAttribute]
        public PageSizeType PageSizeType { get; set; }

        [XmlAttribute]
        public double GridMargin { get; set; }

        [XmlIgnore]
        public Color GridColor { get; set; }

        [JsonIgnore]
        [XmlAttribute("GridColor")]
        public string XmlGridColor
        {
            get
            {
                return SerializeHelper.SerializeColor(GridColor);
            }
            set
            {
                GridColor = SerializeHelper.DeserializeColor(value);
            }
        }

        [XmlArray]
        public List<DesignerItemBase> DesignerItems { get; set; } = new List<DesignerItemBase>();

        [XmlArray]
        public List<PersistDesignerItem> PersistDesignerItems { get; set; } = new List<PersistDesignerItem>();

        [XmlArray]
        public List<SettingsDesignerItem> SettingsDesignerItems { get; set; } = new List<SettingsDesignerItem>();

        [XmlArray]
        public List<PathDesignerItem> PathDesignerItems { get; set; } = new List<PathDesignerItem>();

        [XmlArray]
        public List<MediaDesignerItem> MediaDesignerItems { get; set; } = new List<MediaDesignerItem>();

        [XmlArray]
        public List<ImageDesignerItem> ImageDesignerItems { get; set; } = new List<ImageDesignerItem>();

        [XmlArray]
        public List<TextDesignerItem> TextDesignerItems { get; set; } = new List<TextDesignerItem>();

        [XmlArray]
        public List<LogicalGateDesignerItemBase> LogicalGateItems { get; set; } = new List<LogicalGateDesignerItemBase>();

        [XmlArray]
        public List<FlowNodeDesignerItem> FlowNodeDesignerItems { get; set; } = new List<FlowNodeDesignerItem>();

        [XmlArray]
        public List<SFCNodeDesignerItem> SFCNodeDesignerItems { get; set; } = new List<SFCNodeDesignerItem>();

        [JsonIgnore]
        [XmlIgnore]
        public List<DesignerItemBase> AllDesignerItems
        {
            get
            {
                return
DesignerItems.OfType<DesignerItemBase>()
.Union(TextDesignerItems.OfType<DesignerItemBase>())
.Union(LogicalGateItems.OfType<DesignerItemBase>())
.Union(MediaDesignerItems.OfType<DesignerItemBase>())
.Union(ImageDesignerItems.OfType<DesignerItemBase>())
.Union(PathDesignerItems.OfType<DesignerItemBase>())
.Union(PersistDesignerItems.OfType<DesignerItemBase>())
.Union(SettingsDesignerItems.OfType<DesignerItemBase>())
.Union(FlowNodeDesignerItems.OfType<DesignerItemBase>())
.Union(SFCNodeDesignerItems.OfType<DesignerItemBase>())
.ToList();
            }
        }

        [XmlArray]
        public List<Guid> ConnectionIds { get; set; }

        [XmlArray]
        public List<ConnectionItem> Connections { get; set; }

        public void AddItems(IEnumerable<SelectableDesignerItemViewModelBase> selectedDesignerItems)
        {
            var items = selectedDesignerItems.OfType<DesignerItemViewModelBase>().Select(p => p.ToXmlObject());
            foreach (var item in items)
            {
                if (item is PersistDesignerItem persistDesignerItem)
                {
                    PersistDesignerItems.Add(persistDesignerItem);
                }
                else if (item is SettingsDesignerItem settingsDesignerItem)
                {
                    SettingsDesignerItems.Add(settingsDesignerItem);
                }
                else if (item is PathDesignerItem pathDesignerItem)
                {
                    PathDesignerItems.Add(pathDesignerItem);
                }
                else if (item is MediaDesignerItem mediaDesignerItem)
                {
                    MediaDesignerItems.Add(mediaDesignerItem);
                }
                else if (item is ImageDesignerItem imageDesignerItem)
                {
                    ImageDesignerItems.Add(imageDesignerItem);
                }
                else if (item is TextDesignerItem textDesignerItem)
                {
                    TextDesignerItems.Add(textDesignerItem);
                }
                else if (item is LogicalGateDesignerItemBase logicalGateDesignerItemBase)
                {
                    LogicalGateItems.Add(logicalGateDesignerItemBase);
                }
                else if (item is FlowNodeDesignerItem flowNodeDesignerItem)
                {
                    FlowNodeDesignerItems.Add(flowNodeDesignerItem);
                }
                else if (item is SFCNodeDesignerItem sFCNodeDesignerItem)
                {
                    SFCNodeDesignerItems.Add(sFCNodeDesignerItem);
                }
                else if (item is DesignerItemBase designerItemBase)
                {
                    DesignerItems.Add(designerItemBase);
                }
            }
        }      
    }
}
