using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows.Documents;
using System.Windows.Media;
using ChatController.Core;
using ChatController.HauptKlassen;
using ChatController.Utilities;
using static System.Windows.HorizontalAlignment;
using Application = System.Windows.Application;
using HorizontalAlignment = System.Windows.HorizontalAlignment;

namespace ChatController.ChatKlassen
{
    public class ChatMessage : INotifyPropertyChanged
    {
        public long MessageId { get; set; }

        public int TimeStringMaxWidth => IsSeparator ? int.MaxValue : 350;

        public int MessageMaxWidth => IsSeparator ? int.MaxValue : 450;

        public string SeparatorTimeString => SendTime.ToString("dd. MMMM yyyy");

        public bool IsSeparator { get; set; }

        public long SenderId { get; }

        private ObservableCollection<Inline> _MessageInlines;

        public ObservableCollection<Inline> MessageInlines
        {
            get => _MessageInlines;
            set
            {
                if(false == (_MessageInlines?.Equals(value) ?? false))
                {
                    _MessageInlines = value;
                    OnPropertyChanged(nameof(MessageInlines));
                }
            }
        }

        public ChatMessage(long groupId, long messageId, string userName, string messageText, DateTime sendTime, bool isOwnMessage, long fileSize, string filePath, 
                           string originalImage, string imageName, string thumbnailPath, ImageSource logo, ChatMessageType chatMessageType, long senderId)
        {
            Id = Guid.NewGuid();

            SenderId = senderId;

            MessageType = chatMessageType;

            MessageId = messageId;
            GroupId = groupId;
            Username = userName;

            UserMessage = messageText;
            if(!string.IsNullOrEmpty(messageText))
            {
                Application.Current.Dispatcher.Invoke(() =>
                {
                    MessageInlines = Utils.ConvertLinksToHyperlinks(messageText);
                });
            }

            SendTime = sendTime;
            IsMyMessage = isOwnMessage;

            OriginalImage = originalImage;
            OriginalImageName = imageName;

            if(MessageId == 0 && MessageType == ChatMessageType.Image && logo != null)
            {
                PictureSource = logo;
                PicturePlaceholderHeight = (int) logo.Height;
            }

            FilePath = filePath;

            if(!string.IsNullOrWhiteSpace(thumbnailPath))
            {
                ThumbnailPlaceholderHeight = Utils.GetHeightFromThumbnailUri(thumbnailPath);
                Thumbnail = Utils.GetPicturePlaceholder();

                Utils.DownloadImageAsync(thumbnailPath, $"group-{groupId}", CacheCategory.Thumbnail, imageSource =>
                {
                    Thumbnail = imageSource;
                });
            }

            if(MessageType == ChatMessageType.Image && !string.IsNullOrWhiteSpace(filePath))
            {
                PicturePlaceholderHeight = Utils.GetHeightFromThumbnailUri(filePath);
                PictureSource = Utils.GetPicturePlaceholder();

                Utils.DownloadImageAsync(filePath, $"group-{groupId}", CacheCategory.Thumbnail, imageSource =>
                {
                    PictureSource = imageSource;
                });
            }

            IsSeparator = MessageType == ChatMessageType.Separator;
        }

        public ChatMessageType MessageType { get; }

        private ImageSource _Thumbnail;
        public ImageSource Thumbnail
        {
            get => _Thumbnail;
            set
            {
                if(!Equals(_Thumbnail, value))
                {
                    _Thumbnail = value;

                    OnPropertyChanged(nameof(Thumbnail));
                }
            }
        }

        private int _ThumbnailPlaceholderHeight;
        public int ThumbnailPlaceholderHeight
        {
            get => _ThumbnailPlaceholderHeight;
            set
            {
                if(!Equals(_ThumbnailPlaceholderHeight, value))
                {
                    _ThumbnailPlaceholderHeight = value;
                    OnPropertyChanged(nameof(ThumbnailPlaceholderHeight));
                }
            }
        }

        public bool IsMyMessage { get; set; }

        public string Username { get; }

        public string UserMessage { get; }

        public DateTime SendTime { get; }

        public string UserTimeStringLeft => IsMyMessage ? null : Username;

        public string UserTimeStringRight => SendTimeString;

        public string SendTimeString => SendTime.Date == DateTime.Today ? $"Heute {SendTime:HH:mm}" : SendTime.ToString("dd. MMM HH:mm");

        public Brush BorderBrush => IsSeparator ? new SolidColorBrush(Colors.Transparent) : IsMyMessage ? new SolidColorBrush(Color.FromRgb(255, 90, 0)) : new SolidColorBrush(Color.FromRgb(229, 229, 229));

        public Brush HighlightedBorderBrush => IsSeparator ? new SolidColorBrush(Colors.Transparent) : IsMyMessage ? new SolidColorBrush(Color.FromRgb(255, 153, 153)) : new SolidColorBrush(Color.FromRgb(247, 247, 247));

        public Brush Foreground => new BrushConverter().ConvertFromString("#505050") as SolidColorBrush;

        public HorizontalAlignment HorizontalAlignmentValue => IsSeparator ? HorizontalAlignment.Stretch : IsMyMessage ? Right : Left;

        public string OriginalImage { get; }

        public string OriginalImageName { get; }

        private ImageSource _PictureSource;
        public ImageSource PictureSource
        {
            get => _PictureSource;
            set
            {
                if(!Equals(_PictureSource, value))
                {
                    _PictureSource = value;
                    OnPropertyChanged(nameof(PictureSource));
                }
            }
        }

        private int _PicturePlaceholderHeight;
        public int PicturePlaceholderHeight
        {
            get => _PicturePlaceholderHeight;
            set
            {
                if (!Equals(_PicturePlaceholderHeight, value))
                {
                    _PicturePlaceholderHeight = value;
                    OnPropertyChanged(nameof(PicturePlaceholderHeight));
                }
            }
        }

        public string FilePath { get; }  

        public long GroupId { get; }

        public event PropertyChangedEventHandler PropertyChanged;

        public Guid Id { get; }

        public ImageSource ProfilePicture => OwnChatCache.GetInstance().GetUserProfilePictureFromCache(SenderId)?.ProfilePicture;

        protected virtual void OnPropertyChanged(string propertyName)
        {
            var handler = PropertyChanged;
            handler?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        public override bool Equals(object obj)
        {
            if(obj is ChatMessage message)
            {
                if(message.IsSeparator && IsSeparator)
                {
                    return SendTime == message.SendTime;
                }

                return Id.Equals(message.Id) && MessageId.Equals(message.MessageId);
            }

            return false;
        }

        public override string ToString()
        {
            return SendTime.ToString("dd.MM.yyyy HH:mm:ss");
        }

        public override int GetHashCode()
        {
            return Id.GetHashCode() << 16;
        }
    }
}
