@namespace Lumeo
@inject Lumeo.Services.Localization.ILumeoLocalizer L

@* Uses a transparent <input type="range"> for drag handling — the browser does all the math,
   so the slider tracks the pointer exactly whether the container is fixed px or fluid %. *@
<div class="@CssClass"
     style="width: @Width; height: @Height; position: relative; overflow: hidden; user-select: none;"
     @attributes="AdditionalAttributes">

    @* After image (full size, behind) *@
    <img src="@AfterSrc" alt="@AfterLabel" draggable="false"
         style="position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; pointer-events: none;" />

    @* Before image (clipped via clip-path — no scaling tricks, exact pixel-for-pixel reveal) *@
    <img src="@BeforeSrc" alt="@BeforeLabel" draggable="false"
         style="position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; pointer-events: none; clip-path: @ClipPath;" />

    @* Divider line *@
    @if (Orientation == ImageCompareOrientation.Horizontal)
    {
        <div class="bg-background/90 pointer-events-none" style="position: absolute; top: 0; bottom: 0; left: @(PositionPct); transform: translateX(-50%); width: 2px;"></div>
    }
    else
    {
        <div class="bg-background/90 pointer-events-none" style="position: absolute; left: 0; right: 0; top: @(PositionPct); transform: translateY(-50%); height: 2px;"></div>
    }

    @* Handle *@
    @if (Orientation == ImageCompareOrientation.Horizontal)
    {
        <div class="bg-background text-foreground shadow-md pointer-events-none flex items-center justify-center rounded-full" style="position: absolute; top: 50%; left: @(PositionPct); transform: translate(-50%, -50%); width: 36px; height: 36px;">
            <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none"
                 stroke="currentColor" stroke-width="2.25" stroke-linecap="round" stroke-linejoin="round">
                <path d="M9 6 3 12l6 6" />
                <path d="m15 6 6 6-6 6" />
            </svg>
        </div>
    }
    else
    {
        <div class="bg-background text-foreground shadow-md pointer-events-none flex items-center justify-center rounded-full" style="position: absolute; left: 50%; top: @(PositionPct); transform: translate(-50%, -50%); width: 36px; height: 36px;">
            <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none"
                 stroke="currentColor" stroke-width="2.25" stroke-linecap="round" stroke-linejoin="round">
                <path d="m6 9 6-6 6 6" />
                <path d="m6 15 6 6 6-6" />
            </svg>
        </div>
    }

    @* Labels *@
    @if (!string.IsNullOrEmpty(BeforeLabel))
    {
        <span class="bg-foreground/60 text-background pointer-events-none" style="position: absolute; top: 10px; left: 10px; font-size: 12px; font-weight: 500; padding: 2px 8px; border-radius: 4px;">
            @BeforeLabel
        </span>
    }
    @if (!string.IsNullOrEmpty(AfterLabel))
    {
        <span class="bg-foreground/60 text-background pointer-events-none" style="position: absolute; top: 10px; right: 10px; font-size: 12px; font-weight: 500; padding: 2px 8px; border-radius: 4px;">
            @AfterLabel
        </span>
    }

    @* Transparent range input layered on top — the browser handles drag math. *@
    <input type="range" min="0" max="100" step="0.1"
           value="@_position.ToString("F2", System.Globalization.CultureInfo.InvariantCulture)"
           @oninput="OnInput"
           aria-label="@L["ImageCompare.Slider"]"
           class="lumeo-image-compare-slider"
           style="@SliderStyle" />
</div>

@code {
    [Parameter] public string BeforeSrc { get; set; } = "";
    [Parameter] public string AfterSrc { get; set; } = "";
    [Parameter] public string? BeforeLabel { get; set; } = "Before";
    [Parameter] public string? AfterLabel { get; set; } = "After";
    [Parameter] public int InitialPosition { get; set; } = 50;
    [Parameter] public string Width { get; set; } = "100%";
    [Parameter] public string Height { get; set; } = "400px";
    [Parameter] public ImageCompareOrientation Orientation { get; set; } = ImageCompareOrientation.Horizontal;
    [Parameter] public string? Class { get; set; }
    [Parameter(CaptureUnmatchedValues = true)] public Dictionary<string, object>? AdditionalAttributes { get; set; }

    private double _position;

    private string CssClass => $"rounded-lg overflow-hidden {Class}".Trim();

    private string PositionPct => $"{_position.ToString("F2", System.Globalization.CultureInfo.InvariantCulture)}%";

    private string ClipPath => Orientation == ImageCompareOrientation.Horizontal
        ? $"inset(0 {(100 - _position).ToString("F2", System.Globalization.CultureInfo.InvariantCulture)}% 0 0)"
        : $"inset(0 0 {(100 - _position).ToString("F2", System.Globalization.CultureInfo.InvariantCulture)}% 0)";

    private string SliderStyle =>
        Orientation == ImageCompareOrientation.Horizontal
            ? "position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; cursor: ew-resize; appearance: none; -webkit-appearance: none; background: transparent; margin: 0;"
            : "position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; cursor: ns-resize; appearance: none; -webkit-appearance: none; background: transparent; margin: 0; writing-mode: vertical-lr; direction: ltr;";

    public enum ImageCompareOrientation { Horizontal, Vertical }

    protected override void OnInitialized()
    {
        _position = Math.Clamp(InitialPosition, 1, 99);
    }

    private void OnInput(ChangeEventArgs e)
    {
        if (e.Value is string s && double.TryParse(s, System.Globalization.NumberStyles.Any, System.Globalization.CultureInfo.InvariantCulture, out var v))
        {
            _position = Math.Clamp(v, 1, 99);
        }
    }
}
