@page "/commission/withdrawal-reports"
@attribute [Authorize]

@using MudBlazor
@using CMSMicroservice.Protobuf.Protos.Commission
@using Google.Protobuf.WellKnownTypes
@using Microsoft.JSInterop
@using System.Text
@using BackOffice.Pages.AutoComplete

<div>
    <MudText Typo="Typo.h4" Class="mb-1">گزارش برداشت‌ها</MudText>
    <MudText Typo="Typo.body2" Color="Color.Secondary" Class="mb-4">
        گزارش تجمیعی برداشت‌های کمیسیون بر اساس بازه تاریخ و نوع دوره
    </MudText>

    <MudCard Class="mb-4">
        <MudCardContent>
            <MudGrid>
                <MudItem xs="12" md="3">
                    <MudDatePicker @bind-Date="_startDate"
                                   Label="از تاریخ"
                                   DateFormat="yyyy/MM/dd"
                                   Variant="Variant.Outlined"
                                   Margin="Margin.Dense" />
                </MudItem>
                <MudItem xs="12" md="3">
                    <MudDatePicker @bind-Date="_endDate"
                                   Label="تا تاریخ"
                                   DateFormat="yyyy/MM/dd"
                                   Variant="Variant.Outlined"
                                   Margin="Margin.Dense" />
                </MudItem>
                <MudItem xs="12" md="3">
                    <MudSelect T="PeriodType" @bind-Value="_periodType"
                               Label="نوع دوره"
                               Variant="Variant.Outlined"
                               Margin="Margin.Dense">
                        <MudSelectItem Value="PeriodType.Daily">روزانه</MudSelectItem>
                        <MudSelectItem Value="PeriodType.Weekly">هفتگی</MudSelectItem>
                        <MudSelectItem Value="PeriodType.Monthly">ماهانه</MudSelectItem>
                    </MudSelect>
                </MudItem>
                <MudItem xs="12" md="3">
                    <UserAutoComplete Label="جستجوی کاربر (اختیاری)" 
                                    @bind-SelectedUserId="_userId" />
                </MudItem>
            </MudGrid>

            <MudGrid Class="mt-2">
                <MudItem xs="12" md="4">
                    <MudSelect T="int?" @bind-Value="_status"
                               Label="وضعیت (اختیاری)"
                               Variant="Variant.Outlined"
                               Margin="Margin.Dense">
                        <MudSelectItem T="int?" Value="@(null as int?)">همه وضعیت‌ها</MudSelectItem>
                        <MudSelectItem T="int?" Value="0">در انتظار واریز به کیف پول</MudSelectItem>
                        <MudSelectItem T="int?" Value="1">واریز شده به پاداش تیمی</MudSelectItem>
                        <MudSelectItem T="int?" Value="2">درخواست برداشت ثبت شده</MudSelectItem>
                        <MudSelectItem T="int?" Value="3">برداشت انجام شده</MudSelectItem>
                        <MudSelectItem T="int?" Value="4">خطا در پرداخت بانکی</MudSelectItem>
                        <MudSelectItem T="int?" Value="5">لغو شده</MudSelectItem>
                    </MudSelect>
                </MudItem>
                <MudItem xs="12" md="4" Class="d-flex align-end">
                    <MudButton Variant="Variant.Filled"
                               Color="Color.Primary"
                               OnClick="LoadReports"
                               StartIcon="@Icons.Material.Filled.Search">
                        جستجو
                    </MudButton>
                </MudItem>
                <MudItem xs="12" md="4" Class="d-flex align-end justify-end">
                    <MudButton Variant="Variant.Outlined"
                               Color="Color.Success"
                               StartIcon="@Icons.Material.Filled.Download"
                               OnClick="ExportToExcel"
                               Class="ml-2">
                        خروجی Excel
                    </MudButton>
                    <MudButton Variant="Variant.Outlined"
                               Color="Color.Default"
                               StartIcon="@Icons.Material.Filled.PictureAsPdf"
                               OnClick="ExportToPdf">
                        خروجی PDF
                    </MudButton>
                </MudItem>
            </MudGrid>
        </MudCardContent>
    </MudCard>

    @if (_isLoading)
    {
        <MudPaper Class="pa-4">
            <MudProgressCircular Color="Color.Primary" Indeterminate="true" />
        </MudPaper>
    }
    else if (_periodReports.Count == 0)
    {
        <MudAlert Severity="Severity.Info">
            هیچ داده‌ای برای بازه و فیلترهای انتخاب‌شده یافت نشد.
        </MudAlert>
    }
    else
    {
        <MudGrid Class="mb-4">
            <MudItem xs="12" md="3">
                <MudPaper Elevation="1" Class="pa-4 text-center">
                    <MudText Typo="Typo.subtitle2" Color="Color.Primary">مجموع مبلغ برداشت‌ها</MudText>
                    <MudText Typo="Typo.h5">@_summary.TotalAmount.ToString("N0") تومان</MudText>
                </MudPaper>
            </MudItem>
            <MudItem xs="12" md="3">
                <MudPaper Elevation="1" Class="pa-4 text-center">
                    <MudText Typo="Typo.subtitle2" Color="Color.Success">مبلغ پرداخت شده</MudText>
                    <MudText Typo="Typo.h5">@_summary.TotalPaid.ToString("N0") تومان</MudText>
                </MudPaper>
            </MudItem>
            <MudItem xs="12" md="3">
                <MudPaper Elevation="1" Class="pa-4 text-center">
                    <MudText Typo="Typo.subtitle2" Color="Color.Warning">مبلغ در انتظار</MudText>
                    <MudText Typo="Typo.h5">@_summary.TotalPending.ToString("N0") تومان</MudText>
                </MudPaper>
            </MudItem>
            <MudItem xs="12" md="3">
                <MudPaper Elevation="1" Class="pa-4 text-center">
                    <MudText Typo="Typo.subtitle2" Color="Color.Info">نرخ موفقیت</MudText>
                    <MudText Typo="Typo.h5">@_summary.SuccessRate.ToString("0.##")%</MudText>
                    <MudText Typo="Typo.caption" Color="Color.Secondary">
                        @($"{_summary.TotalRequests} درخواست، {_summary.UniqueUsers} کاربر")
                    </MudText>
                </MudPaper>
            </MudItem>
        </MudGrid>

        <MudGrid Class="mb-4">
            <MudItem xs="12" md="6">
                <MudCard>
                    <MudCardHeader>
                        <MudText Typo="Typo.h6">نمودار مبلغ برداشت‌ها</MudText>
                    </MudCardHeader>
                    <MudCardContent>
                        <MudChart ChartType="ChartType.Line"
                                  ChartSeries="@_amountSeries"
                                  XAxisLabels="@_chartLabels"
                                  Width="100%"
                                  Height="300px" />
                    </MudCardContent>
                </MudCard>
            </MudItem>
            <MudItem xs="12" md="6">
                <MudCard>
                    <MudCardHeader>
                        <MudText Typo="Typo.h6">نمودار تعداد درخواست‌ها</MudText>
                    </MudCardHeader>
                    <MudCardContent>
                        <MudChart ChartType="ChartType.Line"
                                  ChartSeries="@_countSeries"
                                  XAxisLabels="@_chartLabels"
                                  Width="100%"
                                  Height="300px" />
                    </MudCardContent>
                </MudCard>
            </MudItem>
        </MudGrid>

        <MudCard>
            <MudCardContent>
                <MudDataGrid T="PeriodReportViewModel"
                             Items="_periodReports"
                             Hover="true"
                             Filterable="true"
                             SortMode="SortMode.Multiple">
                    <Columns>
                        <PropertyColumn Property="x => x.PeriodLabel" Title="دوره" />
                        <PropertyColumn Property="x => x.StartDate" Title="از تاریخ">
                            <CellTemplate>
                                @context.Item.StartDate.MiladiToJalali()
                            </CellTemplate>
                        </PropertyColumn>
                        <PropertyColumn Property="x => x.EndDate" Title="تا تاریخ">
                            <CellTemplate>
                                @context.Item.EndDate.MiladiToJalali()
                            </CellTemplate>
                        </PropertyColumn>
                        <PropertyColumn Property="x => x.TotalRequests" Title="تعداد درخواست‌ها" />
                        <PropertyColumn Property="x => x.CompletedCount" Title="موفق" />
                        <PropertyColumn Property="x => x.FailedCount" Title="ناموفق" />
                        <PropertyColumn Property="x => x.PendingCount" Title="در انتظار" />
                        <PropertyColumn Property="x => x.TotalAmount" Title="مبلغ کل" Format="N0">
                            <CellTemplate>
                                @context.Item.TotalAmount.ToString("N0") تومان
                            </CellTemplate>
                        </PropertyColumn>
                        <PropertyColumn Property="x => x.PaidAmount" Title="پرداخت شده" Format="N0">
                            <CellTemplate>
                                @context.Item.PaidAmount.ToString("N0") تومان
                            </CellTemplate>
                        </PropertyColumn>
                        <PropertyColumn Property="x => x.PendingAmount" Title="در انتظار پرداخت" Format="N0">
                            <CellTemplate>
                                @context.Item.PendingAmount.ToString("N0") تومان
                            </CellTemplate>
                        </PropertyColumn>
                    </Columns>
            <NoRecordsContent>
                <MudAlert Severity="Severity.Info" Dense="true" Variant="Variant.Text" Class="my-4">موردی یافت نشد.</MudAlert>
            </NoRecordsContent>
                </MudDataGrid>
            </MudCardContent>
        </MudCard>
    }
</div>

@code {
    [Inject] public CommissionContract.CommissionContractClient CommissionClient { get; set; }
    [Inject] public IJSRuntime JsRuntime { get; set; }

    private DateTime? _startDate = DateTime.Today.AddDays(-30);
    private DateTime? _endDate = DateTime.Today;
    private PeriodType _periodType = PeriodType.Daily;
    private int? _status;
    private long? _userId;

    private bool _isLoading;
    private WithdrawalSummaryViewModel _summary = new();
    private List<PeriodReportViewModel> _periodReports = new();
    private string[] _chartLabels = Array.Empty<string>();
    private List<ChartSeries> _amountSeries = new();
    private List<ChartSeries> _countSeries = new();

    protected override async Task OnInitializedAsync()
    {
        await LoadReports();
    }

    private async Task LoadReports()
    {
        if (!_startDate.HasValue || !_endDate.HasValue)
        {
            Snackbar.Add("لطفاً بازه تاریخ را مشخص کنید.", Severity.Warning);
            return;
        }

        if (_startDate.Value.Date > _endDate.Value.Date)
        {
            Snackbar.Add("تاریخ شروع نباید بعد از تاریخ پایان باشد.", Severity.Warning);
            return;
        }

        _isLoading = true;
        _periodReports.Clear();

        try
        {
            var request = new GetWithdrawalReportsRequest
            {
                PeriodType = (int)_periodType
            };

            var start = DateTime.SpecifyKind(_startDate.Value.Date, DateTimeKind.Local).ToUniversalTime();
            var end = DateTime.SpecifyKind(_endDate.Value.Date.AddDays(1).AddTicks(-1), DateTimeKind.Local).ToUniversalTime();

            request.StartDate = Timestamp.FromDateTime(start);
            request.EndDate = Timestamp.FromDateTime(end);

            if (_status.HasValue)
            {
                request.Status = _status.Value;
            }

            if (_userId.HasValue)
            {
                request.UserId = _userId.Value;
            }

            var response = await CommissionClient.GetWithdrawalReportsAsync(request);

            if (response?.Summary != null)
            {
                _summary = new WithdrawalSummaryViewModel
                {
                    TotalRequests = response.Summary.TotalRequests,
                    TotalAmount = response.Summary.TotalAmount,
                    TotalPaid = response.Summary.TotalPaid,
                    TotalPending = response.Summary.TotalPending,
                    TotalRejected = response.Summary.TotalRejected,
                    AverageAmount = response.Summary.AverageAmount,
                    UniqueUsers = response.Summary.UniqueUsers,
                    SuccessRate = (decimal)response.Summary.SuccessRate
                };
            }
            else
            {
                _summary = new WithdrawalSummaryViewModel();
            }

            _periodReports = response?.PeriodReports
                .Select(p => new PeriodReportViewModel
                {
                    PeriodLabel = p.PeriodLabel,
                    StartDate = p.StartDate.ToDateTime().ToLocalTime().Date,
                    EndDate = p.EndDate.ToDateTime().ToLocalTime().Date,
                    TotalRequests = p.TotalRequests,
                    PendingCount = p.PendingCount,
                    ApprovedCount = p.ApprovedCount,
                    RejectedCount = p.RejectedCount,
                    CompletedCount = p.CompletedCount,
                    FailedCount = p.FailedCount,
                    TotalAmount = p.TotalAmount,
                    PaidAmount = p.PaidAmount,
                    PendingAmount = p.PendingAmount
                })
                .ToList() ?? new List<PeriodReportViewModel>();

            BuildCharts();
        }
        catch (Exception ex)
        {
            Snackbar.Add($"خطا در بارگذاری گزارش‌ها: {ex.Message}", Severity.Error);
            _summary = new WithdrawalSummaryViewModel();
            _periodReports.Clear();
            _chartLabels = Array.Empty<string>();
            _amountSeries = new List<ChartSeries>();
            _countSeries = new List<ChartSeries>();
        }
        finally
        {
            _isLoading = false;
        }
    }

    private void BuildCharts()
    {
        if (_periodReports.Count == 0)
        {
            _chartLabels = Array.Empty<string>();
            _amountSeries = new List<ChartSeries>();
            _countSeries = new List<ChartSeries>();
            return;
        }

        var ordered = _periodReports.OrderBy(r => r.StartDate).ToList();
        _chartLabels = ordered.Select(r => r.PeriodLabel).ToArray();

        _amountSeries = new List<ChartSeries>
        {
            new ChartSeries
            {
                Name = "مبلغ کل",
                Data = ordered.Select(r => (double)r.TotalAmount).ToArray()
            },
            new ChartSeries
            {
                Name = "پرداخت شده",
                Data = ordered.Select(r => (double)r.PaidAmount).ToArray()
            },
            new ChartSeries
            {
                Name = "در انتظار پرداخت",
                Data = ordered.Select(r => (double)r.PendingAmount).ToArray()
            }
        };

        _countSeries = new List<ChartSeries>
        {
            new ChartSeries
            {
                Name = "کل درخواست‌ها",
                Data = ordered.Select(r => (double)r.TotalRequests).ToArray()
            },
            new ChartSeries
            {
                Name = "موفق",
                Data = ordered.Select(r => (double)r.CompletedCount).ToArray()
            },
            new ChartSeries
            {
                Name = "ناموفق",
                Data = ordered.Select(r => (double)r.FailedCount).ToArray()
            }
        };
    }

    private async Task ExportToExcel()
    {
        if (_periodReports.Count == 0)
        {
            Snackbar.Add("داده‌ای برای خروجی وجود ندارد.", Severity.Info);
            return;
        }

        var sb = new StringBuilder();
        sb.AppendLine("Period,StartDate,EndDate,TotalRequests,Completed,Failed,Pending,TotalAmount,PaidAmount,PendingAmount");

        foreach (var r in _periodReports.OrderBy(r => r.StartDate))
        {
            sb.AppendLine(string.Join(",",
                EscapeCsv(r.PeriodLabel),
                r.StartDate.MiladiToJalali(),
                r.EndDate.MiladiToJalali(),
                r.TotalRequests,
                r.CompletedCount,
                r.FailedCount,
                r.PendingCount,
                r.TotalAmount,
                r.PaidAmount,
                r.PendingAmount));
        }

        var bytes = Encoding.UTF8.GetBytes(sb.ToString());
        var base64 = Convert.ToBase64String(bytes);
        var filename = $"withdrawal-reports-{DateTime.Now:yyyyMMddHHmmss}.csv";

        await JsRuntime.InvokeVoidAsync("jsSaveAsFile", filename, base64);
        Snackbar.Add("خروجی Excel (CSV) آماده شد.", Severity.Success);
    }

    private async Task ExportToPdf()
    {
        if (_periodReports.Count == 0)
        {
            Snackbar.Add("داده‌ای برای خروجی وجود ندارد.", Severity.Info);
            return;
        }

        var sb = new StringBuilder();
        sb.AppendLine("گزارش برداشت‌ها");
        sb.AppendLine($"دوره: {_periodType}  از تاریخ: {_startDate?.MiladiToJalali() ?? "-"} تا تاریخ: {_endDate?.MiladiToJalali() ?? "-"}");
        sb.AppendLine();

        sb.AppendLine("خلاصه:");
        sb.AppendLine($"تعداد کل درخواست‌ها: {_summary.TotalRequests}");
        sb.AppendLine($"مبلغ کل برداشت‌ها: {_summary.TotalAmount:N0} تومان");
        sb.AppendLine($"مبلغ پرداخت شده: {_summary.TotalPaid:N0} تومان");
        sb.AppendLine($"مبلغ در انتظار: {_summary.TotalPending:N0} تومان");
        sb.AppendLine($"تعداد کاربران یکتا: {_summary.UniqueUsers}");
        sb.AppendLine($"نرخ موفقیت: {_summary.SuccessRate:N2}%");
        sb.AppendLine();

        sb.AppendLine("جزئیات دوره‌ای:");
        sb.AppendLine("دوره | تاریخ شروع | تاریخ پایان | تعداد کل | موفق | ناموفق | در انتظار | مبلغ کل | پرداخت شده | در انتظار پرداخت");

        foreach (var r in _periodReports.OrderBy(r => r.StartDate))
        {
            sb.AppendLine(
                $"{r.PeriodLabel} | {r.StartDate.MiladiToJalali()} | {r.EndDate.MiladiToJalali()} | {r.TotalRequests} | {r.CompletedCount} | {r.FailedCount} | {r.PendingCount} | {r.TotalAmount:N0} | {r.PaidAmount:N0} | {r.PendingAmount:N0}");
        }

        var bytes = Encoding.UTF8.GetBytes(sb.ToString());
        var base64 = Convert.ToBase64String(bytes);
        var filename = $"withdrawal-reports-{DateTime.Now:yyyyMMddHHmmss}.txt";

        await JsRuntime.InvokeVoidAsync("jsSaveAsFile", filename, base64);
        Snackbar.Add("خروجی PDF (نسخه متنی) آماده شد.", Severity.Success);
    }

    private static string EscapeCsv(string value)
    {
        if (string.IsNullOrEmpty(value))
            return "";

        var needsQuotes = value.Contains(',') || value.Contains('"') || value.Contains('\n');
        var escaped = value.Replace("\"", "\"\"");
        return needsQuotes ? $"\"{escaped}\"" : escaped;
    }

    private enum PeriodType
    {
        Daily = 1,
        Weekly = 2,
        Monthly = 3
    }

    private class WithdrawalSummaryViewModel
    {
        public int TotalRequests { get; set; }
        public long TotalAmount { get; set; }
        public long TotalPaid { get; set; }
        public long TotalPending { get; set; }
        public long TotalRejected { get; set; }
        public long AverageAmount { get; set; }
        public int UniqueUsers { get; set; }
        public decimal SuccessRate { get; set; }
    }

    private class PeriodReportViewModel
    {
        public string PeriodLabel { get; set; } = string.Empty;
        public DateTime StartDate { get; set; }
        public DateTime EndDate { get; set; }
        public int TotalRequests { get; set; }
        public int PendingCount { get; set; }
        public int ApprovedCount { get; set; }
        public int RejectedCount { get; set; }
        public int CompletedCount { get; set; }
        public int FailedCount { get; set; }
        public long TotalAmount { get; set; }
        public long PaidAmount { get; set; }
        public long PendingAmount { get; set; }
    }
}
