using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Media;
using System.ComponentModel;
using System.Runtime.CompilerServices;

namespace Sonex.Client.Layouts;

public sealed class ItemsAndContentListItem : INotifyPropertyChanged
{
    private long _id;
    private string _key = string.Empty;
    private string _title = string.Empty;
    private string _subtitle = string.Empty;
    private string _description = string.Empty;
    private string _searchText = string.Empty;
    private string _initials = string.Empty;
    private string _deleteToolTip = "Delete";
    private double _pictureSize = 32;
    private bool _isEnabled = true;
    private bool _isSelected;

    private bool _showPicture = true;
    private bool _showSubtitle = true;
    private bool _showDescription = true;
    private bool _showDeleteButton = true;

    private ImageSource? _picture;

    public long Id
    {
        get => _id;
        set => SetField(ref _id, value);
    }

    public string Key
    {
        get => _key;
        set => SetField(ref _key, value);
    }

    public string Title
    {
        get => _title;
        set => SetField(ref _title, value);
    }

    public string Subtitle
    {
        get => _subtitle;
        set => SetField(ref _subtitle, value);
    }

    public string Description
    {
        get => _description;
        set => SetField(ref _description, value);
    }

    public string SearchText
    {
        get => _searchText;
        set => SetField(ref _searchText, value);
    }

    public string Initials
    {
        get => _initials;
        set => SetField(ref _initials, value);
    }

    public string DeleteToolTip
    {
        get => _deleteToolTip;
        set => SetField(ref _deleteToolTip, value);
    }

    public double PictureSize
    {
        get => _pictureSize;
        set => SetField(ref _pictureSize, value);
    }

    public ImageSource? Picture
    {
        get => _picture;
        set
        {
            if (SetField(ref _picture, value))
                OnPropertyChanged(nameof(PreferSmallImage));
        }
    }

    public bool PreferSmallImage => Picture != null;

    public bool IsEnabled
    {
        get => _isEnabled;
        set
        {
            if (SetField(ref _isEnabled, value))
                OnPropertyChanged(nameof(Opacity));
        }
    }

    public double Opacity => IsEnabled ? 1d : 0.45d;

    public bool IsSelected
    {
        get => _isSelected;
        set
        {
            if (SetField(ref _isSelected, value))
                OnPropertyChanged(nameof(ItemDeleteButtonVisibility));
        }
    }

    public bool ShowPicture
    {
        get => _showPicture;
        set
        {
            if (SetField(ref _showPicture, value))
                OnPropertyChanged(nameof(PictureVisibility));
        }
    }

    public bool ShowSubtitle
    {
        get => _showSubtitle;
        set
        {
            if (SetField(ref _showSubtitle, value))
                OnPropertyChanged(nameof(SubtitleVisibility));
        }
    }

    public bool ShowDescription
    {
        get => _showDescription;
        set
        {
            if (SetField(ref _showDescription, value))
                OnPropertyChanged(nameof(DescriptionVisibility));
        }
    }

    public bool ShowDeleteButton
    {
        get => _showDeleteButton;
        set
        {
            if (SetField(ref _showDeleteButton, value))
                OnPropertyChanged(nameof(ItemDeleteButtonVisibility));
        }
    }

    public Visibility PictureVisibility => ShowPicture ? Visibility.Visible : Visibility.Collapsed;
    public Visibility SubtitleVisibility => ShowSubtitle ? Visibility.Visible : Visibility.Collapsed;
    public Visibility DescriptionVisibility => ShowDescription ? Visibility.Visible : Visibility.Collapsed;
    public Visibility ItemDeleteButtonVisibility => ShowDeleteButton && IsSelected ? Visibility.Visible : Visibility.Collapsed;

    public event PropertyChangedEventHandler? PropertyChanged;

    private bool SetField<T>(ref T field, T value, [CallerMemberName] string? propertyName = null)
    {
        if (Equals(field, value))
            return false;

        field = value;
        OnPropertyChanged(propertyName);
        return true;
    }

    private void OnPropertyChanged([CallerMemberName] string? propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}
