@using Radzen.Blazor
@using Radzen.Blazor.Spreadsheet
@using Radzen.Documents.Spreadsheet

<RadzenStack Gap="0.5rem" Style="min-width: 400px">
    <RadzenStack Orientation="Orientation.Horizontal" Gap="0.5rem" AlignItems="AlignItems.Center">
        <RadzenLabel Text=@L(nameof(RadzenStrings.Spreadsheet_ValidationType)) Component="validationType" class="rz-text-subtitle2" Style="width: 8rem; text-align: end" />
        <RadzenDropDown @bind-Value=@ValidationType Data=@ValidationTypes TextProperty="Name" ValueProperty="Value" Name="validationType" InputSize="InputSize.Small" Style="flex: 1" Change=@OnTypeChanged />
    </RadzenStack>

    @if (ValidationType != DataValidationType.List && ValidationType != DataValidationType.Custom)
    {
        <RadzenStack Orientation="Orientation.Horizontal" Gap="0.5rem" AlignItems="AlignItems.Center">
            <RadzenLabel Text=@L(nameof(RadzenStrings.Spreadsheet_Operator)) Component="operator" class="rz-text-subtitle2" Style="width: 8rem; text-align: end" />
            <RadzenDropDown @bind-Value=@Operator Data=@Operators TextProperty="Name" ValueProperty="Value" Name="operator" InputSize="InputSize.Small" Style="flex: 1" />
        </RadzenStack>
    }

    @if (ValidationType == DataValidationType.Custom)
    {
        <RadzenStack Orientation="Orientation.Vertical" Gap="0.25rem">
            <RadzenLabel Text=@L(nameof(RadzenStrings.Spreadsheet_Formula)) Component="formula" class="rz-text-subtitle2" Style="align-self: start" />
            <RadzenTextBox @bind-Value=@Formula1 Name="formula" InputSize="InputSize.Small" Style="width: 100%" />
        </RadzenStack>
    }
    else if (ValidationType == DataValidationType.List)
    {
        <RadzenStack Orientation="Orientation.Horizontal" Gap="0.5rem" AlignItems="AlignItems.Start">
            <RadzenLabel Text=@L(nameof(RadzenStrings.Spreadsheet_ValuesCommaSeparated)) Component="valuesList" class="rz-text-subtitle2" Style="width: 8rem; text-align: end" />
            <RadzenTextArea @bind-Value=@Formula1 Name="valuesList" Rows="3" InputSize="InputSize.Small" Style="flex: 1" />
        </RadzenStack>
    }
    else if (Operator == DataValidationOperator.Between || Operator == DataValidationOperator.NotBetween)
    {
        @if (ValidationType == DataValidationType.Date)
        {
            <RadzenStack Orientation="Orientation.Horizontal" Gap="0.5rem" AlignItems="AlignItems.Center">
                <RadzenLabel Text=@L(nameof(RadzenStrings.Spreadsheet_Minimum)) Component="minimum" class="rz-text-subtitle2" Style="width: 8rem; text-align: end" />
                <RadzenDatePicker @bind-Value=@Formula1Date DateFormat="yyyy-MM-dd" Name="minimum" InputSize="InputSize.Small" Style="flex: 1" />
            </RadzenStack>
            <RadzenStack Orientation="Orientation.Horizontal" Gap="0.5rem" AlignItems="AlignItems.Center">
                <RadzenLabel Text=@L(nameof(RadzenStrings.Spreadsheet_Maximum)) Component="maximum" class="rz-text-subtitle2" Style="width: 8rem; text-align: end" />
                <RadzenDatePicker @bind-Value=@Formula2Date DateFormat="yyyy-MM-dd" Name="maximum" InputSize="InputSize.Small" Style="flex: 1" />
            </RadzenStack>
        }
        else if (ValidationType == DataValidationType.Time)
        {
            <RadzenStack Orientation="Orientation.Horizontal" Gap="0.5rem" AlignItems="AlignItems.Center">
                <RadzenLabel Text=@L(nameof(RadzenStrings.Spreadsheet_Minimum)) Component="minimum" class="rz-text-subtitle2" Style="width: 8rem; text-align: end" />
                <RadzenDatePicker @bind-Value=@Formula1Date ShowTime="true" TimeOnly="true" Name="minimum" InputSize="InputSize.Small" Style="flex: 1" />
            </RadzenStack>
            <RadzenStack Orientation="Orientation.Horizontal" Gap="0.5rem" AlignItems="AlignItems.Center">
                <RadzenLabel Text=@L(nameof(RadzenStrings.Spreadsheet_Maximum)) Component="maximum" class="rz-text-subtitle2" Style="width: 8rem; text-align: end" />
                <RadzenDatePicker @bind-Value=@Formula2Date ShowTime="true" TimeOnly="true" Name="maximum" InputSize="InputSize.Small" Style="flex: 1" />
            </RadzenStack>
        }
        else
        {
            <RadzenStack Orientation="Orientation.Horizontal" Gap="0.5rem" AlignItems="AlignItems.Center">
                <RadzenLabel Text=@L(nameof(RadzenStrings.Spreadsheet_Minimum)) Component="minimum" class="rz-text-subtitle2" Style="width: 8rem; text-align: end" />
                <RadzenTextBox @bind-Value=@Formula1 Name="minimum" InputSize="InputSize.Small" Style="flex: 1" />
            </RadzenStack>
            <RadzenStack Orientation="Orientation.Horizontal" Gap="0.5rem" AlignItems="AlignItems.Center">
                <RadzenLabel Text=@L(nameof(RadzenStrings.Spreadsheet_Maximum)) Component="maximum" class="rz-text-subtitle2" Style="width: 8rem; text-align: end" />
                <RadzenTextBox @bind-Value=@Formula2 Name="maximum" InputSize="InputSize.Small" Style="flex: 1" />
            </RadzenStack>
        }
    }
    else
    {
        @if (ValidationType == DataValidationType.Date)
        {
            <RadzenStack Orientation="Orientation.Horizontal" Gap="0.5rem" AlignItems="AlignItems.Center">
                <RadzenLabel Text=@L(nameof(RadzenStrings.Spreadsheet_Value)) Component="value" class="rz-text-subtitle2" Style="width: 8rem; text-align: end" />
                <RadzenDatePicker @bind-Value=@Formula1Date DateFormat="yyyy-MM-dd" Name="value" InputSize="InputSize.Small" Style="flex: 1" />
            </RadzenStack>
        }
        else if (ValidationType == DataValidationType.Time)
        {
            <RadzenStack Orientation="Orientation.Horizontal" Gap="0.5rem" AlignItems="AlignItems.Center">
                <RadzenLabel Text=@L(nameof(RadzenStrings.Spreadsheet_Value)) Component="value" class="rz-text-subtitle2" Style="width: 8rem; text-align: end" />
                <RadzenDatePicker @bind-Value=@Formula1Date ShowTime="true" TimeOnly="true" Name="value" InputSize="InputSize.Small" Style="flex: 1" />
            </RadzenStack>
        }
        else
        {
            <RadzenStack Orientation="Orientation.Horizontal" Gap="0.5rem" AlignItems="AlignItems.Center">
                <RadzenLabel Text=@L(nameof(RadzenStrings.Spreadsheet_Value)) Component="value" class="rz-text-subtitle2" Style="width: 8rem; text-align: end" />
                <RadzenTextBox @bind-Value=@Formula1 Name="value" InputSize="InputSize.Small" Style="flex: 1" />
            </RadzenStack>
        }
    }

    <RadzenStack Orientation="Orientation.Horizontal" AlignItems="AlignItems.Center" Gap="0.5rem" Style="padding-inline-start: 8.5rem">
        <RadzenCheckBox @bind-Value=@AllowBlank TValue="bool" Name="allowBlank" />
        <RadzenLabel Text=@L(nameof(RadzenStrings.Spreadsheet_AllowBlank)) Component="allowBlank" class="rz-text-subtitle2" />
    </RadzenStack>

    <RadzenFieldset Text=@L(nameof(RadzenStrings.Spreadsheet_ErrorAlert))>
        <RadzenStack Gap="0.5rem">
            <RadzenStack Orientation="Orientation.Horizontal" Gap="0.5rem" AlignItems="AlignItems.Center">
                <RadzenLabel Text=@L(nameof(RadzenStrings.Spreadsheet_Style)) Component="errorStyle" class="rz-text-subtitle2" Style="width: 7rem; text-align: end" />
                <RadzenDropDown @bind-Value=@ErrorStyle Data=@ErrorStyles TextProperty="Name" ValueProperty="Value" Name="errorStyle" InputSize="InputSize.Small" Style="flex: 1" />
            </RadzenStack>
            <RadzenStack Orientation="Orientation.Horizontal" Gap="0.5rem" AlignItems="AlignItems.Center">
                <RadzenLabel Text=@L(nameof(RadzenStrings.Spreadsheet_Title)) Component="errorTitle" class="rz-text-subtitle2" Style="width: 7rem; text-align: end" />
                <RadzenTextBox @bind-Value=@ErrorTitle Name="errorTitle" InputSize="InputSize.Small" Style="flex: 1" />
            </RadzenStack>
            <RadzenStack Orientation="Orientation.Horizontal" Gap="0.5rem" AlignItems="AlignItems.Start">
                <RadzenLabel Text=@L(nameof(RadzenStrings.Spreadsheet_Message)) Component="errorMessage" class="rz-text-subtitle2" Style="width: 7rem; text-align: end" />
                <RadzenTextArea @bind-Value=@ErrorMessage Name="errorMessage" Rows="2" InputSize="InputSize.Small" Style="flex: 1" />
            </RadzenStack>
        </RadzenStack>
    </RadzenFieldset>

    <RadzenFieldset Text=@L(nameof(RadzenStrings.Spreadsheet_InputPrompt))>
        <RadzenStack Gap="0.5rem">
            <RadzenStack Orientation="Orientation.Horizontal" AlignItems="AlignItems.Center" Gap="0.5rem" Style="padding-inline-start: 7.5rem">
                <RadzenCheckBox @bind-Value=@ShowInputMessage TValue="bool" Name="showInputMessage" />
                <RadzenLabel Text=@L(nameof(RadzenStrings.Spreadsheet_ShowInputMessage)) Component="showInputMessage" class="rz-text-subtitle2" />
            </RadzenStack>
            <RadzenStack Orientation="Orientation.Horizontal" Gap="0.5rem" AlignItems="AlignItems.Center">
                <RadzenLabel Text=@L(nameof(RadzenStrings.Spreadsheet_Title)) Component="inputTitle" class="rz-text-subtitle2" Style="width: 7rem; text-align: end" />
                <RadzenTextBox @bind-Value=@InputTitle Name="inputTitle" InputSize="InputSize.Small" Style="flex: 1" />
            </RadzenStack>
            <RadzenStack Orientation="Orientation.Horizontal" Gap="0.5rem" AlignItems="AlignItems.Start">
                <RadzenLabel Text=@L(nameof(RadzenStrings.Spreadsheet_Message)) Component="inputMessage" class="rz-text-subtitle2" Style="width: 7rem; text-align: end" />
                <RadzenTextArea @bind-Value=@InputMessage Name="inputMessage" Rows="2" InputSize="InputSize.Small" Style="flex: 1" />
            </RadzenStack>
        </RadzenStack>
    </RadzenFieldset>

    <RadzenStack Orientation="Orientation.Horizontal" JustifyContent="JustifyContent.End" Gap="0.5rem" class="rz-spreadsheet-dialog-actions">
        <RadzenButton Text=@L(nameof(RadzenStrings.Spreadsheet_Cancel)) Click=@OnCancel ButtonStyle="ButtonStyle.Base" Variant="Variant.Outlined" />
        <RadzenButton Text=@L(nameof(RadzenStrings.Spreadsheet_OK)) Click=@OnOk ButtonStyle="ButtonStyle.Primary" Variant="Variant.Flat" />
    </RadzenStack>
</RadzenStack>

@code {
#nullable enable
    [Inject]
    public DialogService DialogService { get; set; } = default!;

    [Inject]
    Localizer Localizer { get; set; } = default!;

    string L(string key) => Localizer.Get(key, System.Globalization.CultureInfo.CurrentUICulture);

    private DataValidationType ValidationType { get; set; } = DataValidationType.WholeNumber;
    private DataValidationOperator Operator { get; set; } = DataValidationOperator.Between;
    private string Formula1 { get; set; } = "";
    private string Formula2 { get; set; } = "";
    private bool AllowBlank { get; set; } = true;
    private DataValidationErrorStyle ErrorStyle { get; set; } = DataValidationErrorStyle.Stop;
    private string ErrorTitle { get; set; } = "";
    private string ErrorMessage { get; set; } = "";
    private bool ShowInputMessage { get; set; }
    private string InputTitle { get; set; } = "";
    private string InputMessage { get; set; } = "";
    private DateTime? Formula1Date { get; set; }
    private DateTime? Formula2Date { get; set; }

    protected override void OnInitialized()
    {
        ErrorMessage = L(nameof(RadzenStrings.Spreadsheet_DefaultValidationError));
    }

    private List<DropDownItem<DataValidationType>>? validationTypes;
    private List<DropDownItem<DataValidationType>> ValidationTypes => validationTypes ??=
    [
        new(L(nameof(RadzenStrings.Spreadsheet_ValidationWholeNumber)), DataValidationType.WholeNumber),
        new(L(nameof(RadzenStrings.Spreadsheet_ValidationDecimal)), DataValidationType.Decimal),
        new(L(nameof(RadzenStrings.Spreadsheet_ValidationList)), DataValidationType.List),
        new(L(nameof(RadzenStrings.Spreadsheet_ValidationDate)), DataValidationType.Date),
        new(L(nameof(RadzenStrings.Spreadsheet_ValidationTime)), DataValidationType.Time),
        new(L(nameof(RadzenStrings.Spreadsheet_ValidationTextLength)), DataValidationType.TextLength),
        new(L(nameof(RadzenStrings.Spreadsheet_ValidationCustom)), DataValidationType.Custom)
    ];

    private List<DropDownItem<DataValidationOperator>>? allOperators;
    private List<DropDownItem<DataValidationOperator>> AllOperators => allOperators ??=
    [
        new(L(nameof(RadzenStrings.Spreadsheet_OperatorBetween)), DataValidationOperator.Between),
        new(L(nameof(RadzenStrings.Spreadsheet_OperatorNotBetween)), DataValidationOperator.NotBetween),
        new(L(nameof(RadzenStrings.Spreadsheet_OperatorEqualTo)), DataValidationOperator.Equal),
        new(L(nameof(RadzenStrings.Spreadsheet_OperatorNotEqualTo)), DataValidationOperator.NotEqual),
        new(L(nameof(RadzenStrings.Spreadsheet_OperatorGreaterThan)), DataValidationOperator.GreaterThan),
        new(L(nameof(RadzenStrings.Spreadsheet_OperatorLessThan)), DataValidationOperator.LessThan),
        new(L(nameof(RadzenStrings.Spreadsheet_OperatorGreaterThanOrEqual)), DataValidationOperator.GreaterThanOrEqual),
        new(L(nameof(RadzenStrings.Spreadsheet_OperatorLessThanOrEqual)), DataValidationOperator.LessThanOrEqual)
    ];

    private List<DropDownItem<DataValidationErrorStyle>>? errorStyles;
    private List<DropDownItem<DataValidationErrorStyle>> ErrorStyles => errorStyles ??=
    [
        new(L(nameof(RadzenStrings.Spreadsheet_ErrorStyleStop)), DataValidationErrorStyle.Stop),
        new(L(nameof(RadzenStrings.Spreadsheet_ErrorStyleWarning)), DataValidationErrorStyle.Warning),
        new(L(nameof(RadzenStrings.Spreadsheet_ErrorStyleInformation)), DataValidationErrorStyle.Information)
    ];

    private List<DropDownItem<DataValidationOperator>> Operators => AllOperators;

    private void OnTypeChanged()
    {
        if (ValidationType == DataValidationType.List)
        {
            Operator = DataValidationOperator.Equal;
        }
    }

    private void OnOk()
    {
        var formula1 = Formula1;
        var formula2 = Formula2;

        if (ValidationType == DataValidationType.Date)
        {
            if (Formula1Date.HasValue)
            {
                formula1 = Formula1Date.Value.ToString("yyyy-MM-dd", System.Globalization.CultureInfo.InvariantCulture);
            }
            if (Formula2Date.HasValue)
            {
                formula2 = Formula2Date.Value.ToString("yyyy-MM-dd", System.Globalization.CultureInfo.InvariantCulture);
            }
        }
        else if (ValidationType == DataValidationType.Time)
        {
            if (Formula1Date.HasValue)
            {
                formula1 = (Formula1Date.Value.TimeOfDay.TotalDays).ToString(System.Globalization.CultureInfo.InvariantCulture);
            }
            if (Formula2Date.HasValue)
            {
                formula2 = (Formula2Date.Value.TimeOfDay.TotalDays).ToString(System.Globalization.CultureInfo.InvariantCulture);
            }
        }

        var rule = new DataValidationRule
        {
            Type = ValidationType,
            Operator = Operator,
            Formula1 = formula1,
            Formula2 = formula2,
            AllowBlank = AllowBlank,
            ErrorStyle = ErrorStyle,
            ErrorTitle = string.IsNullOrEmpty(ErrorTitle) ? null : ErrorTitle,
            Error = string.IsNullOrEmpty(ErrorMessage) ? L(nameof(RadzenStrings.Spreadsheet_DefaultValidationError)) : ErrorMessage,
            ShowErrorMessage = true,
            ShowInputMessage = ShowInputMessage,
            InputTitle = string.IsNullOrEmpty(InputTitle) ? null : InputTitle,
            InputMessage = string.IsNullOrEmpty(InputMessage) ? null : InputMessage
        };

        DialogService.Close(rule);
    }

    private void OnCancel()
    {
        DialogService.Close(null);
    }

    private sealed class DropDownItem<T>(string name, T value)
    {
        public string Name { get; } = name;
        public T Value { get; } = value;
    }
}
