@using BlazorDateRangePicker

@*
 *                                dbMango
 *
 * Copyright 2025 Deutsche Bank AG
 * SPDX-License-Identifier: Apache-2.0
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *@

<div class="@Class">
    <div class="form-group" style="width: 150pt;">
        @if (ShowLabel)
        {
            <div class="flex-stack-horizontal form-mw">
                @if (SupportsCobRanges)
                {
                    <label for="@_id" class="input-group-text w-50">@(string.IsNullOrWhiteSpace(Label) ? "COB" : Label)</label>
                    <label class="toggle-switch toggle-switch-xs input-group-text w-50">
                        <input type="checkbox" @bind="UseCobRange"/>
                        <span class="slider" data-label-on="range" data-label-off="date"></span>
                    </label>
                }
                else
                {
                    <label for="cob" class="input-group-text w-100">@(string.IsNullOrWhiteSpace(Label) ? "COB date" : Label)</label>
                }
            </div>
        }
        <!--- COB selector -->
        <div class="input-group mr-sm-2">
            <DateRangePicker id="@_id" Opens="SideType.Left" SingleDatePicker="@NotUseCobRange" @bind-StartDate="Cob" @bind-EndDate="CobRangeEnd" OnRangeSelect="@SelectCob" DaysEnabledFunction="@DaysEnabledFunction">
                <PickerTemplate Context="pickerContext">
                    <div id="@pickerContext.ParentId" @onclick="pickerContext.Toggle" class="form-control float-right datepicker-control">
                        <span class="ui-icon-font icon-calendar"></span>&nbsp;
                        <span>@pickerContext.FormattedRange @(string.IsNullOrEmpty(pickerContext.FormattedRange) ? "Latest COB" : "")</span>
                        <span class="ui-icon-font icon-caret-down float-right"></span>
                    </div>
                </PickerTemplate>
            </DateRangePicker>
        </div>
    </div>
</div>

@code {
    private string _id = $"h{Random.Shared.Next():X8}";

    private DateOnly? _cob         = null;
    private DateOnly? _cobRangeEnd = null;

    private bool NotUseCobRange => !UseCobRange;

    [Parameter] public EventCallback<string?>     CobStrChanged       { get; set; }
    [Parameter] public EventCallback<string?>     CobEndStrChanged    { get; set; }
    [Parameter] public EventCallback<bool  >      UseCobRangeChanged  { get; set; }
    [Parameter] public EventCallback<DateRange>   OnCobRangeChanged   { get; set; }
    [Parameter] public Func<DateTimeOffset, bool> DaysEnabledFunction { get; set; } = _ => true;

    [Parameter] public string? Label { get; set; }

    [Parameter]
    public string Format
    {
        get;
        set => field = string.IsNullOrWhiteSpace(value) ? "yyyy-MM-dd" : value; // Set default value if empty
    } = "yyyy-MM-dd";

    [Parameter]
    public string? CobStr
    {
        get => _cob?.ToString(Format);
        set
        {
            if (string.IsNullOrWhiteSpace(value))
                return;

            var d = DateOnly.ParseExact(value, Format, System.Globalization.CultureInfo.InvariantCulture);
            if (_cob == d)
                return;
            _cob = d;
            CobStrChanged.InvokeAsync(CobStr);
        }
    }

    [Parameter]
    public string? CobEndStr
    {
        get => !SupportsCobRanges || !UseCobRange || _cobRangeEnd == null || _cobRangeEnd == _cob || _cobRangeEnd.Value == default ? null : _cobRangeEnd.Value.ToString(Format);
        set
        {
            DateOnly d = default;
            if (!string.IsNullOrWhiteSpace(value))
            {
                d = DateOnly.ParseExact(value, Format, System.Globalization.CultureInfo.InvariantCulture);
            }

            if (_cobRangeEnd == d)
                return;
            _cobRangeEnd = d;
            CobEndStrChanged.InvokeAsync(CobEndStr);
        }
    }

    [Parameter]
    public bool UseCobRange
    {
        get;
        set
        {
            if (field == value)
                return;
            field = value;
            UseCobRangeChanged.InvokeAsync(UseCobRange);
            CobEndStrChanged.InvokeAsync(CobEndStr);
        }
    }


    [Parameter] public bool   SupportsCobRanges { get; set; }
    [Parameter] public bool   ShowLabel         { get; set; } = true;
    [Parameter] public string Class             { get; set; } = "";

    private DateTimeOffset? Cob
    {
        get => CobHelper.ConvertStringToOffset(CobStr);
        set
        {
            var v = value?.ToString(Format);
            if (CobStr == v)
                return;
            CobStr = v;
        }
    }

    private DateTimeOffset? CobRangeEnd
    {
        get => UseCobRange ? CobHelper.ConvertStringToOffset(CobEndStr) : Cob;
        set
        {
            var v = value?.ToString(Format);
            if (CobEndStr == v)
                return;
            CobEndStr = v;
        }
    }

    protected override void OnAfterRender(bool firstRender)
    {
        if (!firstRender) 
            return;

        if (string.IsNullOrWhiteSpace(Format)) 
            Format = "yyyy-MM-dd";

        Cob         ??= CobHelper.GetLatestCob();
        CobRangeEnd ??= CobHelper.GetLatestCob();
    }

    private Task SelectCob(DateRange d)
    {
        if (d == null)
        {
            CobStr    = null;
            CobEndStr = null;
            return OnCobRangeChanged.InvokeAsync(null);
        }

        if (!UseCobRange)
            d.End = d.Start;

        CobStr      = d.Start.ToString(Format);
        CobEndStr   = d.End.ToString(Format);
        return OnCobRangeChanged.InvokeAsync(d);
    }
}
