using FrontOffice.Main.Utilities;
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
using MudBlazor;

namespace FrontOffice.Main.Pages;

public partial class Index : IDisposable
{
    [Inject] private BlogPostService BlogPostService { get; set; } = default!;
    [Inject] private AuthService AuthService { get; set; } = default!;
    [Inject] private SitePageSettingsService PageSettingsService { get; set; } = default!;
    [Inject] private ProductService ProductService { get; set; } = default!;
    [Inject] private DiscountProductService DiscountProductService { get; set; } = default!;
    [Inject] private CartService Cart { get; set; } = default!;
    [Inject] private DiscountCartService DiscountCart { get; set; } = default!;
    [Inject] private GuestActionGate GuestGate { get; set; } = default!;
    [Inject] private VATService VAT { get; set; } = default!;

    private bool _isAuthenticated;

    // ── CMS page data ──
    private PageSettingsDto? _pageData;
    private LandingSettings? _settings;

    // ── Top-selling product sections ──
    private const int LandingTopProductCount = 6;

    private List<Product> _topRegularProducts = new();
    private List<DiscountProductCard> _topDiscountProducts = new();
    private bool _loadingTopProducts = true;

    // ── Latest blog posts (loaded from CMS) ──
    private List<BlogPostCardDto> _latestPosts = new();

    // ── Data lists (populated from DB or fallback) ──
    private List<(string Icon, string Text)> _trustBadges = new();
    private List<(string Title, string Desc)> _steps = new();
    private List<(string Icon, string Title, string Desc, int Delay)> _features = new();
    private List<StatItem> _stats = new();
    private List<TestimonialItem> _testimonials = new();
    private List<QA> _faqs = new();

    // Track whether animations need re-initialization after data load
    private bool _dataLoaded;
    private bool _animationsInitialized;

    protected override async Task OnInitializedAsync()
    {
        MainService.OnChangeHandler += OnStateChanged;
        _isAuthenticated = await AuthService.IsAuthenticatedAsync();

        // Load landing page settings from CMS
        try
        {
            _pageData = await PageSettingsService.GetPageAsync("landing");
            if (_pageData != null)
            {
                _settings = _pageData.GetSettings<LandingSettings>();
            }
        }
        catch
        {
            // Fallback: settings remain null → defaults below
        }

        PopulateFromSettings();
        _dataLoaded = true;

        // Load top-selling in-stock products and blog posts in parallel
        var topRegTask = ProductService.GetTopSellingAsync(LandingTopProductCount, inStock: true);
        var topDiscTask = DiscountProductService.GetTopSellingAsync(LandingTopProductCount, inStock: true);
        var featuredPostsTask = BlogPostService.GetFeaturedPostsAsync(2);

        try
        {
            await Task.WhenAll(topRegTask, topDiscTask, featuredPostsTask);
            _topRegularProducts = topRegTask.Result.Products;
            _topDiscountProducts = topDiscTask.Result.Products;
        }
        catch
        {
            // Fallback: sections remain empty
        }
        _loadingTopProducts = false;

        // Load latest published blog posts
        try
        {
            _latestPosts = featuredPostsTask.IsCompletedSuccessfully
                ? featuredPostsTask.Result
                : await BlogPostService.GetFeaturedPostsAsync(2);

            if (_latestPosts.Count < 2)
            {
                var result = await BlogPostService.GetPublishedPostsAsync(page: 1, pageSize: 2);
                var existing = _latestPosts.Select(p => p.Id).ToHashSet();
                foreach (var post in result.Posts)
                {
                    if (!existing.Contains(post.Id))
                    {
                        _latestPosts.Add(post);
                        if (_latestPosts.Count >= 2) break;
                    }
                }
            }
        }
        catch
        {
            _latestPosts = new();
        }
    }

    private void PopulateFromSettings()
    {
        // ── Trust badges ──
        if (_settings?.TrustBadges?.Any() == true)
        {
            _trustBadges = _settings.TrustBadges
                .Select(b => (ResolveIcon(b.IconName), b.Text ?? ""))
                .ToList();
        }
        else
        {
            _trustBadges = new()
            {
                (Icons.Material.Outlined.Timer, "ثبت‌نام زیر ۲ دقیقه"),
                (Icons.Material.Outlined.SupportAgent, "پشتیبانی ۷×۲۴"),
                (Icons.Material.Outlined.Lock, "پرداخت ایمن"),
                (Icons.Material.Outlined.Verified, "تضمین کیفیت"),
            };
        }

        // ── Steps ──
        if (_settings?.Steps?.Any() == true)
        {
            _steps = _settings.Steps
                .Select(s => (s.Title ?? "", s.Description ?? ""))
                .ToList();
        }
        else
        {
            _steps = new()
            {
                ("ثبت‌نام و احراز هویت", "یک حساب بسازید، شماره موبایل را تأیید و اطلاعات هویتی را تکمیل کنید."),
                ("دعوت دوستان", "لینک دعوت اختصاصی خود را با دوستان و آشنایان به اشتراک بگذارید."),
                ("دریافت پاداش", "از خریدهای واقعی اعضای تیمتان پاداش شفاف و لحظه‌ای دریافت کنید."),
            };
        }

        // ── Features ──
        if (_settings?.Features?.Any() == true)
        {
            _features = _settings.Features
                .Select((f, i) => (ResolveIcon(f.IconName), f.Title ?? "", f.Description ?? "", i * 100))
                .ToList();
        }
        else
        {
            _features = new()
            {
                (Icons.Material.Outlined.VerifiedUser, "ثبت‌نام سریع و ساده", "در چند گام کوتاه حساب بسازید و شروع کنید.", 0),
                (Icons.Material.Outlined.StarBorder, "پاداش‌های شفاف", "قوانین روشن، دسترسی آسان به سوابق و گزارش‌ها.", 100),
                (Icons.Material.Outlined.Devices, "طراحی واکنش‌گرا", "تجربه‌ای روان در موبایل و دسکتاپ.", 200),
                (Icons.Material.Outlined.Groups, "تیم‌سازی هوشمند", "ساختار درختی شبکه و مدیریت تیم‌های فروش.", 300),
                (Icons.Material.Outlined.Insights, "گزارش‌های لحظه‌ای", "داشبورد پویا برای مشاهده عملکرد و کمیسیون.", 400),
                (Icons.Material.Outlined.Lock, "امنیت بالا", "رمزنگاری اطلاعات و احراز هویت چندمرحله‌ای.", 500),
            };
        }

        // ── Stats ──
        if (_settings?.Stats?.Any() == true)
        {
            _stats = _settings.Stats
                .Select((s, i) => new StatItem(
                    $"stat-{i}",
                    $"{s.Value}{s.Suffix}",
                    s.Value,
                    s.Suffix ?? "",
                    ResolveColor(s.Color),
                    s.Label ?? ""))
                .ToList();
        }
        else
        {
            _stats = new()
            {
                new("stat-growth", "+۵۰٪", 50, "%+", Color.Success, "رشد میانگین تیم"),
                new("stat-uptime", "۹۹.۹٪", 99.9, "%", Color.Primary, "آپ‌تایم سرویس"),
                new("stat-deploy", "۳ روز", 3, " روز", Color.Warning, "میانگین زمان استقرار"),
                new("stat-coverage", "+۲۰ کشور", 20, "+", Color.Secondary, "پوشش ارسال کد"),
            };
        }

        // ── Testimonials ──
        // اگر تنظیمات از CMS لود شده، لیست خالی یعنی ادمین عمداً حذف کرده — بدون fallback hardcode
        if (_settings is not null)
        {
            _testimonials = (_settings.Testimonials ?? [])
                .Select((t, i) => new TestimonialItem(t.Quote ?? "", t.Name ?? "", t.Role ?? "", i * 150))
                .ToList();
        }
        else
        {
            _testimonials = new()
            {
                new("با کارا بازار سلامت، محاسبه کارمزدها و پایش تیم‌ها بدون اکسل و دردسر انجام می‌شود.", "شرکت سینا نت", "مدیر عملیات", 0),
                new("سازمان فروش بصری و گزارش‌های دقیق باعث شد رشد تیم را لحظه‌ای ببینیم.", "هولدینگ آریانا", "مدیر فروش", 150),
                new("سادگی ثبت‌نام و شفافیت پاداش‌ها مهم‌ترین مزیت این پلتفرم است.", "گروه بهداشتی نوین", "مدیر توسعه", 300),
            };
        }

        // ── FAQs ──
        if (_settings?.Faqs?.Any() == true)
        {
            _faqs = _settings.Faqs
                .Select(f => new QA(f.Question ?? "", f.Answer ?? ""))
                .ToList();
        }
        else
        {
            _faqs = new()
            {
                new("دامنه اختصاصی دارم؛ قابل اتصال است؟", "بله، پشت دامنه و گواهی SSL خودتان مستقر می‌شود."),
                new("با دیتابیس خودم کار می‌کند؟", "کاملاً. SQL Server، PostgreSQL و MySQL پشتیبانی می‌شود."),
                new("چه درگاه‌هایی پشتیبانی می‌شود؟", "Stripe و PayPal یا درگاه اختصاصی از طریق وب‌هوک‌ها."),
                new("می‌توانم داده‌ها را خروجی بگیرم؟", "هر زمان از داشبورد ادمین خروجی CSV/Excel بگیرید."),
            };
        }
    }

    /// <summary>
    /// Resolve icon name from SettingsJson to MudBlazor icon string.
    /// Falls back to a generic icon.
    /// </summary>
    private static string ResolveIcon(string? iconName)
    {
        if (string.IsNullOrWhiteSpace(iconName)) return Icons.Material.Outlined.Info;

        // Try to get from MudBlazor Icons via reflection
        var field = typeof(Icons.Material.Outlined).GetField(iconName,
            System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static);
        if (field != null) return (string)(field.GetValue(null) ?? Icons.Material.Outlined.Info);

        // Also try Filled
        field = typeof(Icons.Material.Filled).GetField(iconName,
            System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static);
        if (field != null) return (string)(field.GetValue(null) ?? Icons.Material.Outlined.Info);

        return Icons.Material.Outlined.Info;
    }

    private static Color ResolveColor(string? colorName) => colorName?.ToLowerInvariant() switch
    {
        "primary" => Color.Primary,
        "secondary" => Color.Secondary,
        "success" => Color.Success,
        "warning" => Color.Warning,
        "error" => Color.Error,
        "info" => Color.Info,
        _ => Color.Default
    };

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        // Init/re-init scroll animations after data is loaded and rendered
        if ((firstRender || (_dataLoaded && !_animationsInitialized)) && _steps.Any())
        {
            _animationsInitialized = true;

            // Init scroll-triggered fade-in animations
            await JS.InvokeVoidAsync("initScrollAnimations");

            // Animate stat counters
            foreach (var stat in _stats)
            {
                await JS.InvokeVoidAsync("animateCounter", stat.ElementId, stat.Target, 2200, stat.Suffix);
            }
        }

        if (await AuthService.IsAuthenticatedAsync())
        {
            if (await AuthService.IsCompleteRegisterAsync())
            {
                Navigation.NavigateTo(RouteConstants.Profile.Index);
            }
            else
            {
                Navigation.NavigateTo(RouteConstants.Registration.Wizard);
            }
        }

        await base.OnAfterRenderAsync(firstRender);
    }

    private void NavigateToRegistrationWizard()
    {
        Navigation.NavigateTo(RouteConstants.Registration.Wizard);
    }

    private void NavigateToPost(string slug)
    {
        Navigation.NavigateTo($"/blog/{slug}");
    }

    private void NavigateToRegularProduct(long id)
        => Navigation.NavigateTo(RouteConstants.Store.ProductDetail + id);

    private void NavigateToDiscountProduct(long id)
        => Navigation.NavigateTo(RouteConstants.DiscountStore.ProductDetail + id);

    private async Task AddRegularToCart(Product p)
        => await GuestGate.RunAsync(() => Cart.Add(p, 1));

    private async Task AddDiscountToCart(DiscountProductCard p)
        => await GuestGate.RunAsync(() => DiscountCart.AddAsync(p.Id));

    private string FormatPrice(long price) => $"{VAT.AddVAT(price):N0} تومان";
    private string FormatDiscountPrice(long price) => $"{price:N0} تومان";

    private async void OnStateChanged()
    {
        await InvokeAsync(StateHasChanged);
    }

    // ── Records ──
    private record QA(string Q, string A);
    private record StatItem(string ElementId, string Display, double Target, string Suffix, Color Color, string Label);
    private record TestimonialItem(string Quote, string Name, string Role, int Delay);

    // ── SettingsJson DTO ──
    private class LandingSettings
    {
        public string? HeroButtonPrimaryText { get; set; }
        public string? HeroButtonSecondaryText { get; set; }
        public List<TrustBadgeItem>? TrustBadges { get; set; }
        public string? StepsTitle { get; set; }
        public List<StepItem>? Steps { get; set; }
        public string? FeaturesTitle { get; set; }
        public List<FeatureItem>? Features { get; set; }
        public string? StatsTitle { get; set; }
        public List<StatSettingItem>? Stats { get; set; }
        public string? TestimonialsTitle { get; set; }
        public List<TestimonialSettingItem>? Testimonials { get; set; }
        public string? FaqTitle { get; set; }
        public List<FaqItem>? Faqs { get; set; }
        public string? CtaTitle { get; set; }
        public string? CtaDescription { get; set; }
        public string? CtaButtonText { get; set; }
        public bool? FeaturedBlogEnabled { get; set; }
    }

    private class TrustBadgeItem { public string? IconName { get; set; } public string? Text { get; set; } }
    private class StepItem { public string? Title { get; set; } public string? Description { get; set; } }
    private class FeatureItem { public string? IconName { get; set; } public string? Title { get; set; } public string? Description { get; set; } }
    private class StatSettingItem { public string? Label { get; set; } public double Value { get; set; } public string? Suffix { get; set; } public string? Color { get; set; } }
    private class TestimonialSettingItem { public string? Quote { get; set; } public string? Name { get; set; } public string? Role { get; set; } }
    private class FaqItem { public string? Question { get; set; } public string? Answer { get; set; } }

    public void Dispose()
    {
        MainService.OnChangeHandler -= OnStateChanged;
    }
}