@page "/import"
@using Core.Parsers
@using Microsoft.EntityFrameworkCore
@inject AppDbContext Context

@rendermode InteractiveServer

<PageTitle>Import Data</PageTitle>

<h1>Import Data</h1>

<h3>Events</h3>
<InputFile OnChange="UploadEvents"></InputFile>
    <text>@_events?.Length Events</text>
<button class="btn btn-primary" @onclick="SaveEvents">Save to Database</button>
<br/>

<h3>Students</h3>
<InputFile OnChange="UploadStudents"></InputFile>
<text>@_students?.Length Students</text>
<button class="btn btn-primary" @onclick="SaveStudents">Save to Database</button>

@code {
    private EventDefinition[]? _events;
    private Student[]? _students;

    async Task UploadEvents(InputFileChangeEventArgs arg)
    {
        await GetStreamReaderFromInputFile(arg, reader =>
        {
            var eventDefinitionParser = new EventDefinitionParser(reader);
            _events = eventDefinitionParser.Parse();
        });
    }

    async Task SaveEvents()
    {
        if (_events == null)
            return;

        foreach (var evt in _events)
        {
            // check if it already exists
            var exists
                = await Context.Events
                    .FirstOrDefaultAsync(e => e.Name == evt.Name);
            if (exists != null)
                continue;
            await Context.Events.AddAsync(evt);
        }

        await Context.SaveChangesAsync();
    }

    async Task UploadStudents(InputFileChangeEventArgs arg)
    {
        await GetStreamReaderFromInputFile(arg, reader =>
        {
            var studentParser = new StudentParser(reader);
            _students = studentParser.Parse();
        });
    }

    async Task SaveStudents()
    {
        if (_students == null)
            return;

        try
        {
            foreach (var student in _students)
            {
                // check if it already exists
                var exists
                    = await Context.Students
                        .FirstOrDefaultAsync(e 
                            => e.FirstName == student.FirstName 
                               && e.LastName == student.LastName);
                if (exists != null)
                    continue;
                await Context.Students.AddAsync(student);
            }
            await Context.SaveChangesAsync();
        }
        catch (Exception e)
        {
            Console.WriteLine(e);
            throw;
        }
    }

    static async Task GetStreamReaderFromInputFile(InputFileChangeEventArgs arg, Action<StreamReader> f)
    {
        StreamReader? streamReader = null;
        try
        {
            var browserFile = arg.File;

            await using var fs = browserFile.OpenReadStream();
            await using var ms = new MemoryStream();

            await fs.CopyToAsync(ms);
            ms.Seek(0,0);
            streamReader = new StreamReader(ms);
            f(streamReader);
        }
        catch
        {
            streamReader?.Dispose();
            throw;
        }
    }
}
