@page "/GlobalList"
@rendermode InteractiveServer

@using Microsoft.AspNetCore.Authorization
@using CouchLog.Data
@using Microsoft.AspNetCore.Identity
@using Microsoft.EntityFrameworkCore

@inject ApplicationDbContext CouchLogDB
@inject UserManager<ApplicationUser> UserManager
@inject AuthenticationStateProvider AuthenticationStateProvider
@inject NavigationManager NavigationManager

@attribute [Authorize]

<PageTitle>GlobalList</PageTitle>

<div class="container-fluid mt-4">
    <div class="d-flex justify-content-between align-items-center mb-4">
        <h2>Global List</h2>
        <button class="btn btn-info" type="button" @onclick="ToogleCollapseNewGlobalEntity">@(isCollapseNewGlobalEntityOpen ? "X" : "Add Entity")</button>
    </div>
    <div class="collapse @(isCollapseNewGlobalEntityOpen ? "show" : "")" id="CollapseCreateNewGlobalEntity">
        <div class="mb-4 align-items-center CreateNewGlobalEntity-Container">
            <EditForm Model="@GlobalEntity" OnSubmit="CreateNewGlobalEntity" FormName="CreateNewGlobalEntityForm">
                <DataAnnotationsValidator />
                <ValidationSummary />

                <div class="mb-3">
                    <label for="Title" class="form-label">Title</label>
                    <InputText id="Title" class="form-control" @bind-Value="GlobalEntity.Title"></InputText>
                    <ValidationMessage For="@(() => GlobalEntity.Title)"></ValidationMessage>
                </div>
                <div class="mb-3">
                    <label for="Type" class="form-label">Type</label>
                    <select id="Type" class="form-select" @bind="SelectedMediaTypeId">
                        @foreach(MediaType Type in MediaTypes)
                        {
                            <option value="@Type.Id">@Type.Name</option>
                        }
                    </select>
                </div>
                <div class="mb-3">
                    <label for="Picture" class="form-label">Picture</label>
                    <InputFile OnChange="@LoadFiles" accept="image/*"/>
                    @if (!string.IsNullOrEmpty(ImagePreviewUrl))
                    {
                        <img src="@ImagePreviewUrl" style="max-width: 256px; max-height: 256px;" />
                    }
                </div>
                <div class="mb-3">
                    <label for="Genres" class="form-label">Genres</label>
                    @foreach(Genre Genre in Genres)
                    {
                        <button class="btn-primary btn me-2" value="@Genre.Id" type="button" @onclick="() => AddGenreToList(Genre.Id)">@Genre.Name</button>
                    }
                </div>
                <button type="submit" class="btn-success btn">Create new Global Entity</button>
            </EditForm>
        </div>
    </div>
    <div class="row">
        @foreach (var Entity in GlobalEntities)
        {
            <div name="Enity-Container" class="col-12 col-md-6 col-lg-3 mb-4 Entity-Container">
                <div name="Entity-Container-Card" class="Entity-Container-Card">
                    <div class="Entity-Container-Menu-Button">
                        <button type="button" class="Entity-Container-Menu-Button" data-bs-toogle="modal" data-bs-target="@Entity.Id">&#8942;</button>
                    </div>

                    <div class="modal fade" id="@Entity.Id" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
                        <div class="modal-dialog">
                            <div class="modal-content">
                                <div class="modal-header">
                                    <h5 class="modal-title" id="staticBackdropLabel">Modal title</h5>
                                    <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
                                </div>
                                <div class="modal-body">
                                    This is a vertically centered modal.
                                </div>
                                <div class="modal-footer">
                                    <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
                                    <button type="button" class="btn btn-primary">Understood</button>
                                </div>
                            </div>
                        </div>
                    </div>


                    <div name="Enity-Container-Image" class="">
                        <a href="javascript:void(0)" class="Entity-Container-Image">
                            <img src="@Entity.PicturePath" alt="" class="Entity-Container-Image" />
                        </a>
                    </div>
                    <div name="Entity-Container-Data" class="">
                        <h3 class="">@Entity.Title</h3>
                    </div>
                    <div name="Entity-Container-Button" class="d-flex Entity-Container-Button" style="gap: 10px;">
                        <button class="btn btn-info" type="button" @onclick="() => AddToPrivateList(Entity)">
                            @(IsInPrivateList(Entity.Id) ? "Added" : "Add to Private List")
                        </button>
                        <button class="btn btn-info" type="button" @onclick="() => throw new NotImplementedException()">Add to Shared List</button>
                    </div>
                </div>
            </div>
        }
    </div>
</div>

@code
{
    private List<MediaType> MediaTypes = new List<MediaType>();
    private List<Genre> Genres = new List<Genre>();
    private List<GlobalEntity> GlobalEntities = new List<GlobalEntity>();
    private List<int> GenreIds = new List<int>();
    private HashSet<int> UserPrivateEntityIds = new();
    private string? ImagePreviewUrl;
    private IBrowserFile? Picture;
    System.Security.Claims.ClaimsPrincipal User = new();
    ApplicationUser? AppUser = new();
    private GlobalEntity GlobalEntity = new();
    private bool isCollapseNewGlobalEntityOpen = false;
    private int SelectedMediaTypeId;

    /// <summary>
    /// 
    /// </summary>
    /// <returns></returns>
    /// <exception cref="NotImplementedException"></exception>
    protected override async Task OnInitializedAsync()
    {
        GlobalEntities = await CouchLogDB.GlobalEntities.OrderByDescending(Entity => Entity.Id).ToListAsync();
        MediaTypes = await CouchLogDB.MediaType.OrderBy(Type => Type.Id).ToListAsync();
        Genres = await CouchLogDB.Genres.OrderBy(Genre => Genre.Id).ToListAsync();

        var AuthState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
        User = AuthState.User;

        AppUser = await UserManager.GetUserAsync(User);

        if (AppUser == null)
        {
            throw new NotImplementedException();
        }

        var TempUserPrivateEntityIds = await CouchLogDB.PrivateEntities
            .Where(p => p.UserId == AppUser.Id)
            .Select(p => p.GlobalEntityId)
            .ToListAsync();

        UserPrivateEntityIds = TempUserPrivateEntityIds.ToHashSet();
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="eventArgs"></param>
    /// <returns></returns>
    private async Task LoadFiles(InputFileChangeEventArgs eventArgs)
    {
        Picture = eventArgs.File;

        //Byte[] Buffer = new byte[Picture.Size];
        //await Picture.OpenReadStream().ReadAsync(Buffer);
        //await Picture.OpenReadStream(maxAllowedSize: 10_000_000).ReadAsync(Buffer);

        //string Base64 = Convert.ToBase64String(Buffer);
        //ImagePreviewUrl = $"data:{Picture.ContentType};base64,{Base64}";
    }

    /// <summary>
    /// 
    /// </summary>
    private void ToogleCollapseNewGlobalEntity()
    {
        isCollapseNewGlobalEntityOpen = !isCollapseNewGlobalEntityOpen;
        StateHasChanged();
    }

    /// <summary>
    /// 
    /// </summary>
    /// <returns></returns>
    private async Task CreateNewGlobalEntity()
    {
        if (Picture is null)
        {
            throw new InvalidOperationException("No Picture selected.");
        }

        if (AppUser is null)
        {
            throw new InvalidOperationException("User not loaded or not logged in.");
        }

        //Save Picture and Name it
        string NewFileName = $"{GlobalEntity.Title.Replace(" ", "_")}_{Guid.NewGuid()}{Path.GetExtension(Picture.Name)}";
        string PicturePath = Path.Combine("wwwroot", "Pictures", NewFileName);
        using FileStream FileStream = File.Create(PicturePath);
        await Picture.OpenReadStream().CopyToAsync(FileStream);
        //await Picture.OpenReadStream(maxAllowedSize: 10_000_000).CopyToAsync(FileStream);

        GlobalEntity.PicturePath = $"Pictures/{NewFileName}";
        GlobalEntity.CreatorId = AppUser.Id;
        GlobalEntity.TypeId = SelectedMediaTypeId;
        GlobalEntity.CreationTime = DateTime.Now;

        CouchLogDB.Add(GlobalEntity);
        await CouchLogDB.SaveChangesAsync();

        foreach(int GenreId in GenreIds)
        {
            LinkTableGlobalGenre LinkTableGlobalGenre = new() { GenreId = GenreId, GlobalEntityId = GlobalEntity.Id };
            CouchLogDB.Add(LinkTableGlobalGenre);
        }

        await CouchLogDB.SaveChangesAsync();
        NavigationManager.NavigateTo(NavigationManager.Uri, true);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="GolbalEntityId"></param>
    /// <returns></returns>
    private bool IsInPrivateList(int GolbalEntityId)
    {
        return UserPrivateEntityIds.Contains(GolbalEntityId);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="GlobalEntity"></param>
    /// <returns></returns>
    private async Task AddToPrivateList(GlobalEntity GlobalEntity)
    {
        if(User.Identity?.IsAuthenticated == true)
        {
            if(!IsInPrivateList(GlobalEntity.Id))
            {
                if (AppUser is null)
                {
                    throw new InvalidOperationException("User not loaded or not logged in.");
                }

                PrivateEntity PrivateEntity = new()
                {
                    UserId = AppUser.Id,
                    CreationTime = DateTime.Now,
                    GlobalEntityId = GlobalEntity.Id,
                    UserWatchStatusId = 1,
                };

                CouchLogDB.PrivateEntities.Add(PrivateEntity);
                await CouchLogDB.SaveChangesAsync();

                UserPrivateEntityIds.Add(GlobalEntity.Id);
                StateHasChanged();
            }
        }
    }

    private void AddGenreToList(int GenreId)
    {
        if (!GenreIds.Contains(GenreId))
        {
            GenreIds.Add(GenreId);
        }
    }
}