using System;
using System.Collections.Generic;
using System.Linq;
using CommunityToolkit.Mvvm.ComponentModel;
using Wino.Core.Domain.Interfaces;
namespace Wino.Mail.ViewModels.Data;
///
/// Thread mail item (multiple IMailItem) view model representation.
///
public partial class ThreadMailItemViewModel : ObservableRecipient, IDisposable, IMailListItem
{
private readonly string _threadId;
private readonly List _threadEmails = [];
private bool _disposed;
[ObservableProperty]
[NotifyPropertyChangedRecipients]
public partial bool IsThreadExpanded { get; set; }
[ObservableProperty]
public partial bool IsSelected { get; set; }
///
/// Gets the number of emails in this thread
///
public int EmailCount => _threadEmails.Count;
///
/// Gets the latest email's subject for display
///
public string Subject => _threadEmails
.OrderByDescending(e => e.MailCopy?.CreationDate)
.FirstOrDefault()?.MailCopy?.Subject;
///
/// Gets the latest email's sender name for display
///
public string FromName => _threadEmails
.OrderByDescending(e => e.MailCopy?.CreationDate)
.FirstOrDefault()?.MailCopy?.SenderContact.Name;
///
/// Gets the latest email's creation date for sorting
///
public DateTime CreationDate => _threadEmails
.OrderByDescending(e => e.MailCopy?.CreationDate)
.FirstOrDefault()?.MailCopy?.CreationDate ?? DateTime.MinValue;
///
/// Gets all emails in this thread (read-only)
///
public IReadOnlyList ThreadEmails => _threadEmails.AsReadOnly();
public MailItemViewModel LatestMailViewModel => _threadEmails.OrderByDescending(e => e.MailCopy?.CreationDate).FirstOrDefault()!;
public ThreadMailItemViewModel(string threadId)
{
_threadId = threadId;
}
protected virtual void Dispose(bool disposing)
{
if (_disposed)
return;
if (disposing)
{
_threadEmails.Clear();
}
_disposed = true;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
public void NotifyPropertyChanges()
{
OnPropertyChanged(nameof(Subject));
OnPropertyChanged(nameof(FromName));
OnPropertyChanged(nameof(CreationDate));
OnPropertyChanged(nameof(LatestMailViewModel));
}
///
/// Adds an email to this thread
///
public void AddEmail(MailItemViewModel email)
{
if (email.MailCopy.ThreadId != _threadId)
throw new ArgumentException($"Email ThreadId '{email.MailCopy.ThreadId}' does not match expander ThreadId '{_threadId}'");
_threadEmails.Add(email);
NotifyPropertyChanges();
}
///
/// Removes an email from this thread
///
public void RemoveEmail(MailItemViewModel email)
{
if (_threadEmails.Remove(email))
{
NotifyPropertyChanges();
}
}
///
/// Checks if this thread contains an email with the specified unique ID
///
public bool HasUniqueId(Guid uniqueId) => _threadEmails.Any(email => email.MailCopy.UniqueId == uniqueId);
public IEnumerable GetContainingIds() => ThreadEmails.Select(a => a.MailCopy.UniqueId);
public IEnumerable GetSelectedMailItems()
{
if (IsSelected)
{
// If the thread itself is selected, return all emails in the thread
return ThreadEmails;
}
else
{
// Otherwise, return only individually selected emails within the thread
return ThreadEmails.Where(e => e.IsSelected);
}
}
}