using System;
using System.IO;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Media.Imaging;
using Wino.Core.Domain;
using Wino.Core.Domain.Entities.Shared;
using Wino.Core.Domain.Interfaces;
using Wino.Mail.WinUI;

namespace Wino.Dialogs;

public sealed partial class ContactEditDialog : ContentDialog
{
    private AccountContact _contact;
    private IDialogServiceBase? _dialogService;
    private IContactPictureFileService? _contactPictureFileService;
    private bool _isEditMode;

    public AccountContact Contact => _contact;

    public ContactEditDialog(AccountContact? contact = null, IDialogServiceBase? dialogService = null)
    {
        InitializeComponent();

        _contact = contact ?? new AccountContact();
        _dialogService = dialogService;
        _contactPictureFileService = App.Current.Services.GetService<IContactPictureFileService>();
        _isEditMode = contact != null && !string.IsNullOrEmpty(contact.Address);

        Title = _isEditMode ? Translator.ContactEditDialog_Title : Translator.ContactEditDialog_AddTitle;

        LoadContactData();
        ValidateInput();
    }

    private void LoadContactData()
    {
        if (_contact != null)
        {
            ContactNameTextBox.Text = _contact.Name ?? string.Empty;
            EmailAddressTextBox.Text = _contact.Address ?? string.Empty;

            // Disable email editing for existing contacts (Address is PK).
            EmailAddressTextBox.IsEnabled = !_isEditMode;

            if (_contact.IsRootContact)
                RootContactInfoBorder.Visibility = Visibility.Visible;

            if (_contact.IsOverridden)
                OverriddenContactInfoBorder.Visibility = Visibility.Visible;

            // Load existing photo — prefer file-based picture, fall back to legacy base64.
            if (_contact.ContactPictureFileId.HasValue && _contactPictureFileService != null)
            {
                var filePath = _contactPictureFileService.GetContactPicturePath(_contact.ContactPictureFileId.Value);
                if (!string.IsNullOrEmpty(filePath))
                {
                    LoadContactPhotoFromFile(filePath);
                    RemovePhotoButton.Visibility = Visibility.Visible;
                }
            }
            else
            {
                ContactPhotoPersonPicture.DisplayName = _contact.Name ?? string.Empty;
                RemovePhotoButton.Visibility = Visibility.Collapsed;
            }
        }
    }

    private async void ChoosePhotoClicked(object sender, RoutedEventArgs e)
    {
        if (_dialogService == null) return;

        try
        {
            var files = await _dialogService.PickFilesAsync(".png", ".jpg", ".jpeg");

            if (files?.Count > 0)
            {
                var file = files[0];

                if (_contactPictureFileService != null)
                {
                    // Delete existing file if replacing.
                    if (_contact.ContactPictureFileId.HasValue)
                        await _contactPictureFileService.DeleteContactPictureAsync(_contact.ContactPictureFileId.Value);

                    var fileId = await _contactPictureFileService.SaveContactPictureAsync(file.Data);
                    _contact.ContactPictureFileId = fileId;

                    var filePath = _contactPictureFileService.GetContactPicturePath(fileId);
                    if (!string.IsNullOrEmpty(filePath))
                        LoadContactPhotoFromFile(filePath);
                }
                else
                {
                    LoadContactPhoto(file.Data);
                }

                RemovePhotoButton.Visibility = Visibility.Visible;
            }
        }
        catch (Exception)
        {
            // Failed to pick photo, ignore.
        }
    }

    private void RemovePhotoClicked(object sender, RoutedEventArgs e)
    {
        if (_contact.ContactPictureFileId.HasValue && _contactPictureFileService != null)
            _ = _contactPictureFileService.DeleteContactPictureAsync(_contact.ContactPictureFileId.Value);

        _contact.ContactPictureFileId = null;
        ContactPhotoPersonPicture.ProfilePicture = null;
        ContactPhotoPersonPicture.DisplayName = ContactNameTextBox.Text;
        RemovePhotoButton.Visibility = Visibility.Collapsed;
    }

    private void LoadContactPhotoFromFile(string filePath)
    {
        try
        {
            var bytes = File.ReadAllBytes(filePath);
            using var stream = new MemoryStream(bytes);
            var bitmap = new BitmapImage();
            bitmap.SetSource(stream.AsRandomAccessStream());
            ContactPhotoPersonPicture.ProfilePicture = bitmap;
        }
        catch
        {
            // Failed to load image, ignore.
        }
    }

    private void LoadContactPhoto(byte[] imageBytes)
    {
        try
        {
            using var stream = new MemoryStream(imageBytes);
            var bitmap = new BitmapImage();
            bitmap.SetSource(stream.AsRandomAccessStream());
            ContactPhotoPersonPicture.ProfilePicture = bitmap;
        }
        catch
        {
            // Failed to load image, ignore.
        }
    }

    private void ValidateInput(object? sender = null, TextChangedEventArgs? e = null)
    {
        var hasName = !string.IsNullOrWhiteSpace(ContactNameTextBox.Text);
        var hasEmail = !string.IsNullOrWhiteSpace(EmailAddressTextBox.Text);

        var isValidEmail = hasEmail && EmailValidation.EmailValidator.Validate(EmailAddressTextBox.Text);

        if (_isEditMode)
        {
            // In edit mode, only name is required (email is locked).
            IsPrimaryButtonEnabled = hasName;
        }
        else
        {
            // In create mode, both name and valid email are required.
            IsPrimaryButtonEnabled = hasName && isValidEmail;
        }
    }

    private void SaveClicked(ContentDialog sender, ContentDialogButtonClickEventArgs args)
    {
        _contact.Name = ContactNameTextBox.Text?.Trim();

        if (!_isEditMode)
            _contact.Address = EmailAddressTextBox.Text?.Trim();

        // Mark as overridden if this was a user edit of an existing contact.
        if (_isEditMode)
            _contact.IsOverridden = true;
    }

    private void CancelClicked(ContentDialog sender, ContentDialogButtonClickEventArgs args)
    {
        // Nothing to do, dialog will close.
    }
}
