using System.Text;
using BackOffice.Common.BaseComponents;
using BackOffice.Common.Utilities;
using BackOffice.Services.DiscountProduct;
using BackOffice.Services.DiscountCategory;
using BackOffice.Pages.DiscountShop.Components;
using BackOffice.Pages.Products.Components;
using BackOffice.Pages.Tag.Components;
using static BackOffice.Pages.DiscountShop.Components.ProductFormDialog;
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
using MudBlazor;

namespace BackOffice.Pages.DiscountShop;

public partial class DiscountProductsMainPage
{
    [Inject] public IDiscountProductService DiscountProductService { get; set; } = default!;
    [Inject] public IDiscountCategoryService DiscountCategoryService { get; set; } = default!;

    private MudDataGrid<DiscountProductDto>? _dataGrid;
    private BasePageComponent _basePage = default!;
    private List<DiscountProductDto> _products = new();
    private List<DiscountCategoryDto> _categories = new();
    private bool _loading;

    private string? _searchQuery;
    private long? _categoryFilter;
    private bool? _statusFilter;
    private bool? _stockFilter;

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

    private async Task LoadCategories()
    {
        try
        {
            _categories = await DiscountCategoryService.GetCategoriesAsync(isActive: true);
        }
        catch
        {
            _categories = new();
        }
    }

    private async Task<GridData<DiscountProductDto>> LoadServerData(GridState<DiscountProductDto> state)
    {
        _loading = true;
        try
        {
            var filter = new ProductFilterDto
            {
                SearchQuery = _searchQuery,
                CategoryId = _categoryFilter,
                IsActive = _statusFilter,
                InStock = _stockFilter,
                PageNumber = state.Page + 1,
                PageSize = state.PageSize
            };

            var (products, totalCount, _) = await DiscountProductService.GetProductsAsync(filter);
            _products = products;

            return new GridData<DiscountProductDto>
            {
                Items = products,
                TotalItems = totalCount
            };
        }
        catch (Exception ex)
        {
            Snackbar.Add($"خطا در بارگذاری محصولات: {ex.Message}", Severity.Error);
            return new GridData<DiscountProductDto> { Items = new List<DiscountProductDto>(), TotalItems = 0 };
        }
        finally
        {
            _loading = false;
        }
    }

    private void ReLoadData()
    {
        _dataGrid?.ReloadServerData();
    }

    private async Task OnFilterSubmit()
    {
        _basePage.IsFiltered = true;
        StateHasChanged();
        ReLoadData();
    }

    private async Task OnFilterCleared()
    {
        _basePage.IsFiltered = false;
        _searchQuery = null;
        _categoryFilter = null;
        _statusFilter = null;
        _stockFilter = null;
        StateHasChanged();
        ReLoadData();
    }

    private async Task OpenCreateDialog()
    {
        var model = new ProductFormModel();
        var parameters = new DialogParameters<ProductFormDialog>
        {
            { x => x.Model, model },
            { x => x.IsEditMode, false }
        };

        var options = new DialogOptions { MaxWidth = MaxWidth.Medium, FullWidth = true };
        var dialog = await DialogService.ShowAsync<ProductFormDialog>("ایجاد محصول جدید", parameters, options);
        var result = await dialog.Result;

        if (result is { Canceled: false, Data: ProductFormModel formData })
        {
            try
            {
                var dto = new CreateDiscountProductDto
                {
                    Title = formData.Title,
                    ShortInformation = formData.ShortInformation,
                    FullInformation = formData.FullInformation,
                    ImagePath = formData.ImagePath,
                    ThumbnailPath = formData.ThumbnailPath,
                    Price = formData.Price,
                    MaxDiscountPercent = formData.MaxDiscountPercent,
                    InitialCount = 0,
                    SortOrder = formData.SortOrder,
                    IsActive = formData.IsActive,
                    CategoryIds = formData.CategoryIds,
                    ImageFile = formData.ImageFile,
                    ImageMime = formData.ImageMime,
                    ImageFileName = formData.ImageFileName,
                    ThumbnailFile = formData.ThumbnailFile,
                    ThumbnailMime = formData.ThumbnailMime,
                    ThumbnailFileName = formData.ThumbnailFileName
                };

                await DiscountProductService.CreateAsync(dto);
                Snackbar.Add("محصول با موفقیت ایجاد شد", Severity.Success);
                ReLoadData();
            }
            catch (Exception ex)
            {
                Snackbar.Add($"خطا در ایجاد محصول: {ex.Message}", Severity.Error);
            }
        }
    }

    private async Task OpenEditDialog(long productId)
    {
        try
        {
            var product = await DiscountProductService.GetByIdAsync(productId);
            if (product == null)
            {
                Snackbar.Add("محصول یافت نشد", Severity.Error);
                return;
            }

            var model = new ProductFormModel
            {
                Title = product.Title,
                ShortInformation = product.ShortInformation,
                FullInformation = product.FullInformation,
                ImagePath = product.ImagePath,
                ThumbnailPath = product.ThumbnailPath,
                Price = product.Price,
                MaxDiscountPercent = product.MaxDiscountPercent,
                SortOrder = product.SortOrder,
                IsActive = product.IsActive,
                CategoryIds = product.Categories?.Select(c => c.Id).ToList() ?? new()
            };

            var parameters = new DialogParameters<ProductFormDialog>
            {
                { x => x.Model, model },
                { x => x.IsEditMode, true }
            };

            var options = new DialogOptions { MaxWidth = MaxWidth.Medium, FullWidth = true };
            var dialog = await DialogService.ShowAsync<ProductFormDialog>("ویرایش محصول", parameters, options);
            var result = await dialog.Result;

            if (result is { Canceled: false, Data: ProductFormModel formData })
            {
                var dto = new UpdateDiscountProductDto
                {
                    Title = formData.Title,
                    ShortInformation = formData.ShortInformation,
                    FullInformation = formData.FullInformation,
                    ImagePath = formData.ImagePath,
                    ThumbnailPath = formData.ThumbnailPath,
                    Price = formData.Price,
                    MaxDiscountPercent = formData.MaxDiscountPercent,
                    SortOrder = formData.SortOrder,
                    IsActive = formData.IsActive,
                    CategoryIds = formData.CategoryIds,
                    ImageFile = formData.ImageFile,
                    ImageMime = formData.ImageMime,
                    ImageFileName = formData.ImageFileName,
                    ThumbnailFile = formData.ThumbnailFile,
                    ThumbnailMime = formData.ThumbnailMime,
                    ThumbnailFileName = formData.ThumbnailFileName
                };

                await DiscountProductService.UpdateAsync(productId, dto);
                Snackbar.Add("محصول با موفقیت ویرایش شد", Severity.Success);
                ReLoadData();
            }
        }
        catch (Exception ex)
        {
            Snackbar.Add($"خطا در ویرایش محصول: {ex.Message}", Severity.Error);
        }
    }

    private async Task DeleteProduct(long productId)
    {
        var product = _products.FirstOrDefault(p => p.Id == productId);
        var options = new DialogOptions { CloseOnEscapeKey = true, MaxWidth = MaxWidth.Small };
        bool? result = await DialogService.ShowMessageBox(
            "اخطار",
            $"آیا از حذف محصول «{product?.Title}» مطمئن هستید؟",
            yesText: "حذف", cancelText: "لغو",
            options: options);

        if (result == true)
        {
            try
            {
                await DiscountProductService.DeleteAsync(productId);
                Snackbar.Add("محصول با موفقیت حذف شد", Severity.Success);
                ReLoadData();
            }
            catch (Exception ex)
            {
                Snackbar.Add($"خطا در حذف محصول: {ex.Message}", Severity.Error);
            }
        }
    }

    private async Task OpenGallery(DiscountProductDto product)
    {
        var parameters = new DialogParameters<GalleryDialog>
        {
            { x => x.ProductId, product.Id },
            { x => x.ProductTitle, product.Title }
        };
        await DialogService.ShowAsync<GalleryDialog>("گالری تصاویر", parameters,
            new DialogOptions { CloseButton = true, FullWidth = true, MaxWidth = MaxWidth.Medium });
    }

    public void OpenCategoryMapping(DiscountProductDto product)
    {
        Navigation.NavigateTo($"{RouteConstance.ProductCategories}{product.Id}");
    }

    private async Task OpenImagePreview(string? imagePath, string? title)
    {
        if (string.IsNullOrWhiteSpace(imagePath))
            return;

        var parameters = new DialogParameters<ImagePreviewDialog>
        {
            { x => x.ImageUrl, imagePath },
            { x => x.Title, title }
        };

        await DialogService.ShowAsync<ImagePreviewDialog>("پیش‌نمایش تصویر محصول", parameters,
            new DialogOptions { CloseButton = true, MaxWidth = MaxWidth.Medium, FullWidth = true });
    }

    private async Task ExportToExcel()
    {
        try
        {
            var filter = new ProductFilterDto
            {
                SearchQuery = _searchQuery,
                CategoryId = _categoryFilter,
                IsActive = _statusFilter,
                InStock = _stockFilter,
                PageNumber = 1,
                PageSize = 1000
            };

            var (products, _, _) = await DiscountProductService.GetProductsAsync(filter);

            if (products == null || products.Count == 0)
            {
                Snackbar.Add("داده‌ای برای خروجی وجود ندارد.", Severity.Info);
                return;
            }

            var sb = new StringBuilder();
            sb.AppendLine("شناسه,عنوان,قیمت,حداکثر تخفیف,موجودی,بازدید,وضعیت");

            foreach (var p in products)
            {
                sb.AppendLine(string.Join(",",
                    p.Id,
                    EscapeCsv(p.Title),
                    p.Price,
                    p.MaxDiscountPercent,
                    p.RemainingCount,
                    p.ViewCount,
                    p.IsActive ? "فعال" : "غیرفعال"));
            }

            var bytes = Encoding.UTF8.GetPreamble().Concat(Encoding.UTF8.GetBytes(sb.ToString())).ToArray();
            var base64 = Convert.ToBase64String(bytes);
            var filename = $"discount-products-{DateTime.Now:yyyyMMddHHmmss}.csv";

            await jsRuntime.InvokeVoidAsync("jsSaveAsFile", filename, base64);
            Snackbar.Add("خروجی Excel (CSV) آماده شد.", Severity.Success);
        }
        catch (Exception ex)
        {
            Snackbar.Add($"خطا در خروجی Excel: {ex.Message}", Severity.Error);
        }
    }

    public async Task OpenTagAssignment(DiscountProductDto model)
    {
        var parameters = new DialogParameters<AssignTagsDialog>
        {
            { x => x.ProductId, model.Id },
            { x => x.ProductTitle, model.Title }
        };

        await DialogService.ShowAsync<AssignTagsDialog>("مدیریت تگ‌های محصول", parameters,
            new DialogOptions { CloseButton = true, MaxWidth = MaxWidth.Small, FullWidth = true });
    }

    private static string EscapeCsv(string? value)
    {
        if (string.IsNullOrEmpty(value)) return "";
        if (value.Contains(',') || value.Contains('"') || value.Contains('\n'))
            return "\"" + value.Replace("\"", "\"\"") + "\"";
        return value;
    }
}
