@namespace SufiChain.SufiBlazor.Components.Builder

<div class="sb-dropzone @(_isDragOver ? "sb-dropzone--drag-over" : "") @(Disabled ? "sb-dropzone--disabled" : "") @Class"
     @ondragover="OnDragOver"
     @ondragover:preventDefault="true"
     @ondragleave="OnDragLeave"
     @ondrop="OnDrop"
     @ondrop:preventDefault="true">
    
    @if (ChildContent != null)
    {
        @ChildContent
    }
    else if (_isDragOver)
    {
        <div class="sb-dropzone__indicator">
            <span class="sb-dropzone__icon">+</span>
            <span class="sb-dropzone__text">@DropText</span>
        </div>
    }
    else
    {
        <div class="sb-dropzone__placeholder">
            <span class="sb-dropzone__icon">↓</span>
            <span class="sb-dropzone__text">@PlaceholderText</span>
        </div>
    }
</div>

@code {
    private bool _isDragOver;
    
    /// <summary>
    /// Zone content.
    /// </summary>
    [Parameter]
    public RenderFragment? ChildContent { get; set; }
    
    /// <summary>
    /// Placeholder text when empty.
    /// </summary>
    [Parameter]
    public string PlaceholderText { get; set; } = "Drag items here";
    
    /// <summary>
    /// Text shown during drag over.
    /// </summary>
    [Parameter]
    public string DropText { get; set; } = "Drop here";
    
    /// <summary>
    /// Accepted data types.
    /// </summary>
    [Parameter]
    public string[]? AcceptedTypes { get; set; }
    
    /// <summary>
    /// Whether the zone is disabled.
    /// </summary>
    [Parameter]
    public bool Disabled { get; set; }
    
    /// <summary>
    /// Callback when item is dropped.
    /// </summary>
    [Parameter]
    public EventCallback<SbDropEventArgs> OnItemDropped { get; set; }
    
    /// <summary>
    /// Callback when drag enters.
    /// </summary>
    [Parameter]
    public EventCallback OnDragEnter { get; set; }
    
    /// <summary>
    /// Callback when drag leaves.
    /// </summary>
    [Parameter]
    public EventCallback OnDragExit { get; set; }
    
    /// <summary>
    /// Additional CSS classes.
    /// </summary>
    [Parameter]
    public string? Class { get; set; }
    
    private async Task OnDragOver(DragEventArgs e)
    {
        if (Disabled) return;
        
        if (!_isDragOver)
        {
            _isDragOver = true;
            await OnDragEnter.InvokeAsync();
        }
    }
    
    private async Task OnDragLeave(DragEventArgs e)
    {
        _isDragOver = false;
        await OnDragExit.InvokeAsync();
    }
    
    private async Task OnDrop(DragEventArgs e)
    {
        if (Disabled) return;
        
        _isDragOver = false;
        
        var args = new SbDropEventArgs
        {
            ClientX = e.ClientX,
            ClientY = e.ClientY
        };
        
        await OnItemDropped.InvokeAsync(args);
    }
}

/// <summary>
/// Drop event arguments.
/// </summary>
public class SbDropEventArgs
{
    /// <summary>
    /// X coordinate.
    /// </summary>
    public double ClientX { get; set; }
    
    /// <summary>
    /// Y coordinate.
    /// </summary>
    public double ClientY { get; set; }
    
    /// <summary>
    /// Dropped data.
    /// </summary>
    public object? Data { get; set; }
}
