using Microsoft.AspNetCore.Components;
using MudBlazor;
using System.Globalization;
using System.Reflection;

namespace BackOffice.Common.BaseComponents;

public partial class DateRangePicker
{
    private DateRange _dateRange = new();
    private MudDateRangePicker _picker = default!;
    private DateTime? _lastSyncedFrom;
    private DateTime? _lastSyncedTo;

    [Parameter] public string Label { get; set; } = "انتخاب بازه زمانی";
    [Parameter] public DateTime? DefaultStart { get; set; }
    [Parameter] public DateTime? DefaultEnd { get; set; }
    [Parameter] public EventCallback<DateRange> OnChanged { get; set; }

    [Parameter] public DateTime? From { get; set; }
    [Parameter] public EventCallback<DateTime?> FromChanged { get; set; }
    [Parameter] public DateTime? To { get; set; }
    [Parameter] public EventCallback<DateTime?> ToChanged { get; set; }

    protected override void OnInitialized()
    {
        base.OnInitialized();
        var start = From ?? DefaultStart;
        var end = To ?? DefaultEnd;
        ApplyExternalRange(start, end);
        _lastSyncedFrom = From;
        _lastSyncedTo = To;
    }

    protected override void OnParametersSet()
    {
        // فقط وقتی والد From/To را عوض کرده (مثلاً پاک کردن فیلتر)، نه هنگام انتخاب داخل پیکر
        if (From == _lastSyncedFrom && To == _lastSyncedTo)
            return;

        _lastSyncedFrom = From;
        _lastSyncedTo = To;
        ApplyExternalRange(From, To);
    }

    private void ApplyExternalRange(DateTime? start, DateTime? end)
    {
        _dateRange = new DateRange(start?.Date, end?.Date);
    }

    public CultureInfo GetPersianCulture()
    {
        var culture = new CultureInfo("fa-IR");
        DateTimeFormatInfo formatInfo = culture.DateTimeFormat;
        formatInfo.AbbreviatedDayNames = new[] { "ی", "د", "س", "چ", "پ", "ج", "ش" };
        formatInfo.DayNames = new[] { "یکشنبه", "دوشنبه", "سه شنبه", "چهار شنبه", "پنجشنبه", "جمعه", "شنبه" };
        var monthNames = new[]
        {
            "فروردین", "اردیبهشت", "خرداد", "تیر", "مرداد", "شهریور", "مهر", "آبان", "آذر", "دی", "بهمن",
            "اسفند",
            "",
        };
        formatInfo.AbbreviatedMonthNames =
            formatInfo.MonthNames =
                formatInfo.MonthGenitiveNames = formatInfo.AbbreviatedMonthGenitiveNames = monthNames;
        formatInfo.AMDesignator = "ق.ظ";
        formatInfo.PMDesignator = "ب.ظ";
        formatInfo.ShortDatePattern = "yyyy/MM/dd";
        formatInfo.LongDatePattern = "dddd, dd MMMM,yyyy";
        formatInfo.FirstDayOfWeek = DayOfWeek.Saturday;
        Calendar cal = new PersianCalendar();
        FieldInfo fieldInfo = culture.GetType().GetField("calendar", BindingFlags.NonPublic | BindingFlags.Instance);
        fieldInfo?.SetValue(culture, cal);
        FieldInfo info = formatInfo.GetType().GetField("calendar", BindingFlags.NonPublic | BindingFlags.Instance);
        info?.SetValue(formatInfo, cal);
        culture.NumberFormat.NumberDecimalSeparator = "/";
        culture.NumberFormat.DigitSubstitution = DigitShapes.NativeNational;
        culture.NumberFormat.NumberNegativePattern = 0;
        return culture;
    }

    private async Task OnClickOK()
    {
        var range = _picker.DateRange ?? _dateRange;
        _dateRange = range ?? new DateRange();
        await NotifyRangeChangedAsync(_dateRange);
        await _picker.CloseAsync();
    }

    private async Task OnClickClear()
    {
        _dateRange = new DateRange();
        await NotifyRangeChangedAsync(_dateRange);
        await _picker.CloseAsync();
    }

    private async Task NotifyRangeChangedAsync(DateRange range)
    {
        var start = range.Start?.Date;
        var end = range.End?.Date;

        _lastSyncedFrom = start;
        _lastSyncedTo = end;

        if (From != start)
            await FromChanged.InvokeAsync(start);
        if (To != end)
            await ToChanged.InvokeAsync(end);

        await OnChanged.InvokeAsync(range);
    }
}
