@using CouchLog.Data
@using Microsoft.EntityFrameworkCore
@using Microsoft.AspNetCore.Authorization
@using Microsoft.AspNetCore.Identity
@using System.ComponentModel.DataAnnotations

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

<style>
    .drop-zone-hover-overlay {
        position: absolute;
        inset: 0;
        background: rgba(0, 0, 0, 0.45);
        display: flex;
        align-items: center;
        justify-content: center;
        opacity: 0;
        transition: opacity .2s ease;
        border-radius: 6px;
    }
    .drop-zone-wrapper:hover .drop-zone-hover-overlay {
        opacity: 1;
    }
</style>

<MudDialog>
    <TitleContent>
        <MudText Typo="Typo.h6">Add Global Entity</MudText>
    </TitleContent>

    <DialogContent>
        <EditForm EditContext="_editContext" OnSubmit="HandleSubmit">
            <DataAnnotationsValidator />

            <MudGrid Style="min-height: 400px;">
                <MudItem xs="5" Style="display: flex;">
                    <MudFileUpload T="IBrowserFile" @ref="_fileUpload" FilesChanged="OnPictureUploaded" Accept="image/*" Style="width: 100%; display: flex;">
                        <ActivatorContent>
                            <div @onclick="OpenFilePicker"
                                 @ondragenter="@(() => _isDragOver = true)"
                                 @ondragleave="@(() => _isDragOver = false)"
                                 @ondragover:preventDefault="true"
                                 @ondrop:preventDefault="true"
                                 @ondrop="@(() => _isDragOver = false)"
                                 style="@GetDropZoneStyle()"
                                 class="d-flex align-center justify-center cursor-pointer drop-zone-wrapper">

                                @if (_imagePreviewUrl is not null)
                                {
                                    <div style="position: relative; width: 100%; height: 100%;">
                                        <img src="@_imagePreviewUrl"
                                             alt="Preview"
                                             style="width: 100%; height: 100%; object-fit: cover; border-radius: 6px; display: block;" />
                                        <div class="drop-zone-hover-overlay">
                                            <MudStack AlignItems="AlignItems.Center" Spacing="1">
                                                <MudIcon Icon="@Icons.Material.Filled.Edit"
                                                         Color="Color.Surface"
                                                         Size="Size.Large" />
                                                <MudText Typo="Typo.caption" Style="color: white;">
                                                    Replace Image
                                                </MudText>
                                            </MudStack>
                                        </div>
                                    </div>
                                }
                                else
                                {
                                    <MudStack AlignItems="AlignItems.Center" Spacing="2">
                                        <MudIcon Icon="@Icons.Material.Filled.CloudUpload"
                                                 Size="Size.Large"
                                                 Color="@(_isDragOver ? Color.Primary : Color.Secondary)" />
                                        <MudText Typo="Typo.body2"
                                                 Align="Align.Center"
                                                 Color="@(_isDragOver ? Color.Primary : Color.Secondary)">
                                            Bild hierher ziehen<br />oder klicken zum Auswählen
                                        </MudText>
                                    </MudStack>
                                }

                            </div>
                        </ActivatorContent>
                    </MudFileUpload>
                </MudItem>
                
                <MudItem xs="7">
                    <MudStack Spacing="3">

                        <MudTextField @bind-Value="_form.Title"
                                      Label="Title"
                                      For="@(() => _form.Title)"
                                      Variant="Variant.Outlined" />

                        <MudSelect T="int"
                                   @bind-Value="_selectedMediaTypeId"
                                   Label="Type"
                                   Variant="Variant.Outlined">
                            @foreach (var type in _mediaTypes)
                            {
                                <MudSelectItem T="int" Value="@type.Id">@type.Name</MudSelectItem>
                            }
                        </MudSelect>

                        <MudSelect T="int"
                                   Label="Genres"
                                   MultiSelection="true"
                                   @bind-SelectedValues="_selectedGenreIds"
                                   Variant="Variant.Outlined">
                            @foreach (var genre in _genres)
                            {
                                <MudSelectItem T="int" Value="@genre.Id">@genre.Name</MudSelectItem>
                            }
                        </MudSelect>
                        <MudCheckBox @bind-Value="_isPrivate" Label="Is Private" Color="Color.Primary" />
                        <MudButton ButtonType="ButtonType.Submit" Variant="Variant.Filled" Color="Color.Success" Disabled="_isSaving" Class="mt-3">
                            @if (_isSaving)
                            {
                                <MudProgressCircular Indeterminate="true" Size="Size.Small" Class="mr-2" />
                                <span>Saving...</span>
                            }
                            else
                            {
                                <span>Create Global Entity</span>
                            }
                        </MudButton>
                    </MudStack>
                </MudItem>
            </MudGrid>
        </EditForm>
    </DialogContent>

    <DialogActions>
        <MudButton OnClick="Cancel" Variant="Variant.Text" Disabled="_isSaving">Cancel</MudButton>
    </DialogActions>
</MudDialog>

@code {
    [CascadingParameter]
    private IMudDialogInstance MudDialog { get; set; } = null!;

    private ApplicationUser? _appUser;
    private EditContext _editContext = null!;

    private List<MediaType> _mediaTypes = new();
    private List<Genre> _genres = new();

    private GlobalEntityFormModel _form = new();
    private MudFileUpload<IBrowserFile>? _fileUpload;
    private IBrowserFile? _picture;
    private string? _imagePreviewUrl;
    private bool _isDragOver;
    private int _selectedMediaTypeId;
    private bool _isPrivate;
    private bool _isSaving;
    private IEnumerable<int> _selectedGenreIds = new HashSet<int>();

    private class GlobalEntityFormModel
    {
        [Required(ErrorMessage = "Title is required.")]
        [MaxLength(200, ErrorMessage = "Title may not exceed 200 characters.")]
        public string Title { get; set; } = string.Empty;
    }

    private string GetDropZoneStyle() =>
        "width: 100%; height: 100%; min-height: 380px; border-radius: 6px; " +
        $"border: 2px dashed {(_isDragOver ? "var(--mud-palette-primary)" : "var(--mud-palette-lines-default)")}; " +
        $"background-color: {(_isDragOver ? "var(--mud-palette-primary-hover)" : "transparent")}; " +
        "transition: border-color .2s ease, background-color .2s ease;";

    private Task OpenFilePicker() =>
        _fileUpload?.OpenFilePickerAsync() ?? Task.CompletedTask;

    protected override async Task OnInitializedAsync()
    {
        _editContext = new EditContext(_form);

        var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
        _appUser = await UserManager.GetUserAsync(authState.User);

        if (_appUser is null)
        {
            Snackbar.Add("Not authenticated.", Severity.Error);
            MudDialog.Cancel();
            return;
        }

        _mediaTypes = await CouchLogDB.MediaType.OrderBy(t => t.Id).ToListAsync();
        _genres = await CouchLogDB.Genres.OrderBy(t => t.Id).ToListAsync();

        if (_mediaTypes.Count > 0)
            _selectedMediaTypeId = _mediaTypes.First().Id;
    }

    private async Task OnPictureUploaded(IBrowserFile file)
    {
        _picture = file;
        
        const long maxPreviewSize = 5 * 1024 * 1024;
        await using var stream = file.OpenReadStream(maxPreviewSize);
        using var ms = new MemoryStream();
        await stream.CopyToAsync(ms);

        var base64 = Convert.ToBase64String(ms.ToArray());
        _imagePreviewUrl = $"data:{file.ContentType};base64,{base64}";
    }

    private void Cancel() => MudDialog.Cancel();

    private async Task HandleSubmit(EditContext ctx)
    {
        if (!ctx.Validate()) return;

        if (_picture is null)
        {
            Snackbar.Add("Please upload a picture.", Severity.Warning);
            return;
        }

        if (_selectedMediaTypeId == 0)
        {
            Snackbar.Add("Please select a media type.", Severity.Warning);
            return;
        }

        _isSaving = true;

        try
        {
            string safeTitle = _form.Title.Replace(" ", "-");
            string fileName = $"{safeTitle}-{Guid.NewGuid()}{Path.GetExtension(_picture.Name)}";
            string picturePath = Path.Combine("wwwroot", "Pictures", fileName);

            await using (var fs = File.Create(picturePath))
            {
                await _picture.OpenReadStream(maxAllowedSize: 10_000_000).CopyToAsync(fs);
            }

            var entity = new GlobalEntity
            {
                Title = _form.Title,
                PicturePath = $"Pictures/{fileName}",
                CreatorId = _appUser!.Id,
                TypeId = _selectedMediaTypeId,
                CreationTime = DateTime.UtcNow,
                IsPrivate = _isPrivate
            };

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

            foreach (int genreId in _selectedGenreIds)
            {
                CouchLogDB.Add(new LinkTableGlobalGenre
                {
                    GenreId = genreId,
                    GlobalEntityId = entity.Id
                });
            }

            await CouchLogDB.SaveChangesAsync();

            Snackbar.Add("Global Entity created!", Severity.Success);
            MudDialog.Close(DialogResult.Ok(entity.Id));
            NavigationManager.NavigateTo(NavigationManager.Uri, true);
        }
        catch (Exception ex)
        {
            Snackbar.Add($"Error: {ex.Message}", Severity.Error);
        }
        finally
        {
            _isSaving = false;
        }
    }
}