using SecureSharing.Business.Interfaces;
using SecureSharing.Models;

namespace SecureSharing.Infrastructure;

public sealed class ModelFactory : IModelFactory
{
    private readonly IMessageService _messageService;
    private readonly string _basePath;

    public ModelFactory(IMessageService messageService, IWebHostEnvironment webHostEnvironment)
    {
        _basePath = Path.Combine(webHostEnvironment.WebRootPath.Split('/')[0], "files");
        _messageService = messageService;
    }

    public async Task<LinkModel> PrepareLinkVM(Guid code, bool? share, bool? edit)
    {
        //share is true when the link is created

        LinkModel model = null;
        try
        {
            var message = await _messageService.GetByCode(code);

            model = new LinkModel
            {
                MessageModel = new MessageModel
                {
                    Id = message.Id,
                    Code = code,
                    Text = message.Text,
                    FileNames = message.FileNames.Select(x => x.Name).ToList(),
                    Anonymous = message.Anonymous,
                    AllowEditing = message.AllowEditing
                },
                Share = share,
                IsValid = message.IsValid
            };

            if (model.IsValid)
            {
                if (message.ExpiryDate != null)
                {
                    model.TimeLeft = message.ExpiryDate - DateTime.UtcNow;
                    if (message.ExpiryDate <= DateTime.UtcNow)
                    {
                        await _messageService.InvalidateMessage(message.Id);
                        model.IsValid = false;
                    }
                }
                else
                {
                    //ONE_TIME sharing: make the message invalid now so that it can't be accessed next time
                    if (share is null or false && edit is null or false) await _messageService.InvalidateMessage(message.Id);
                }
            }
            else
            {
                Directory.Delete(Path.Combine(_basePath, message.Code.ToString()), true);
                await _messageService.Delete(message.Id);
            }
        }
        catch (Exception _)
        {
            model = new LinkModel { IsValid = false };
        }

        return model;
    }

    public async Task<LinkModel> PrepareLinkAnonymous(Guid code, bool? edit)
    {
        var model = await PrepareLinkVM(code, false, edit);

        return model.MessageModel.Anonymous ? model : new LinkModel { IsValid = false };
    }

    public async Task<LinkModel> PrepareLinkEdit(Guid code, bool? edit)
    {
        var model = await PrepareLinkVM(code, false, edit);

        return model.MessageModel.Anonymous && model.MessageModel.AllowEditing ? model : new LinkModel { IsValid = false };
    }
    
    //public MessageModel PrepareMessageVM(MessageDto message)
    //{
    //    throw new System.NotImplementedException();
    //}
}