/* eslint-disable @typescript-eslint/no-explicit-any */
import Navbar from "@/components/shared/Navbar";
import Hero from "@/components/sections/hero/Hero";
import TrackOrder from "@/components/sections/orders/TrackOrder";
import Footer from "@/components/shared/Footer";
import ProductGrid from "@/components/sections/products/ProductGrid";
import BlogsSection from "@/components/sections/blogs/BlogsSection";
import BlogsSkeleton from "@/components/skeletons/BlogsSkeleton";
import ProductsSkeleton from "@/components/skeletons/ProductsSkeleton";
import ReviewsSection from "@/components/sections/reviews/ReviewsSection";

import { getCategories, getProducts, getFeaturedProducts, getBrands } from "@/services/products/product.service";
import { getBlogs } from "@/services/cms/cms.service";
import { getHero } from "@/services/cms/hero.service";
import { getFeaturedReviews } from "@/services/reviews/reviews.service";
import FeaturedGrid from "@/components/sections/products/FeaturedGrid";
import type { Metadata } from "next";
import { Suspense } from "react";
import { fetchSiteConfig } from "@/services/site-config.service";

export const revalidate = 60;

export async function generateMetadata(): Promise<Metadata> {
  let brand = "Electronics Store";
  let title = "Home";
  let description = "Genuine electronics, home appliances and gadgets from trusted brands — with warranty, EMI options and fast nationwide delivery.";
  let ogImage = "/images/og-image.webp";

  try {
    const siteConfig = (await fetchSiteConfig()) as any;
    if (siteConfig.company_name) {
      brand = siteConfig.company_name;
    }
    if (siteConfig.company_short_description) {
      description = siteConfig.company_short_description;
    }
    ogImage = siteConfig.site_og_image || siteConfig.company_logo || "/images/og-image.webp";
  } catch {}

  try {
    const heroSections = await getHero();
    const activeHero = heroSections?.find((s) => s.is_active) || heroSections?.[0];
    if (activeHero?.title) {
      title = activeHero.title;
    }
    if (activeHero?.subtitle) {
      description = activeHero.subtitle;
    }
  } catch (error) {
    console.error("SEO Metadata: Failed to fetch hero section:", error);
  }

  const base = process.env.NEXT_PUBLIC_SITE_URL || "http://localhost:3000";
  const absoluteOg = ogImage.startsWith("http") ? ogImage : `${base}${ogImage.startsWith("/") ? "" : "/"}${ogImage}`;

  return {
    title,
    description,
    metadataBase: new URL(base),
    alternates: {
      canonical: "/",
    },
    openGraph: {
      title,
      description,
      type: "website",
      url: "/",
      siteName: brand,
      locale: "en_US",
      images: [
        {
          url: absoluteOg,
          width: 1200,
          height: 630,
          alt: "Electronics Store",
        },
      ],
    },
    twitter: {
      card: "summary_large_image",
      title,
      description,
      images: [absoluteOg],
    },
  };
}

interface PageProps {
  searchParams: Promise<{
    page?: string;
    search?: string;
    category?: string;
    brand?: string;
    min_price?: string;
    max_price?: string;
    sort?: string;
    blogPage?: string;
    featuredPage?: string;
  }>;
}

export default async function Page({ searchParams }: PageProps) {
  const params = await searchParams;
  const { page, search, category, brand: brandSlug, min_price, max_price, sort, blogPage, featuredPage } = params;

  let activeHero = null;
  let categoriesData: any[] = [];
  let reviews: any[] = [];
  let brand = "Electronics Store";
  let description = "Genuine electronics & appliances.";
  let configData: any = {};

  try {
    const [heroSections, categories, reviewsRes, siteConfig] = await Promise.all([
      getHero().catch((e) => {
        console.error("Failed to fetch hero:", e);
        return null;
      }),
      getCategories().catch((e) => {
        console.error("Failed to fetch categories:", e);
        return [];
      }),
      getFeaturedReviews().catch((e) => {
        console.error("Failed to fetch reviews:", e);
        return [];
      }),
      fetchSiteConfig().catch(() => ({} as any)),
    ]);
    activeHero = heroSections?.find((s) => s.is_active) || heroSections?.[0] || null;
    categoriesData = categories || [];
    reviews = reviewsRes || [];
    configData = siteConfig as any;
    if (configData.company_name) brand = configData.company_name;
    if (configData.company_short_description) description = configData.company_short_description;
  } catch (error) {
    console.error("Error in parallel fetches:", error);
  }

  const reviewsCount = reviews.length;
  const ratingSum = reviews.reduce((acc: number, r: any) => acc + (Number(r.rating) || 5), 0);
  const averageRating = reviewsCount > 0 ? (ratingSum / reviewsCount).toFixed(1) : "5.0";

  const jsonLd = {
    "@context": "https://schema.org",
    "@type": "Store",
    "name": brand,
    "description": description,
    "url": process.env.NEXT_PUBLIC_SITE_URL || "http://localhost:3000",
    "logo": configData.company_logo || "/favicon.ico",
    ...(reviewsCount > 0 ? {
      "aggregateRating": {
        "@type": "AggregateRating",
        "ratingValue": averageRating,
        "reviewCount": reviewsCount,
        "bestRating": "5",
        "worstRating": "1",
      },
    } : {}),
  };

  return (
    <>
      <script
        type="application/ld+json"
        dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
      />
      <Navbar />
      <main id="main-content">
        <Hero activeHero={activeHero} />

        <Suspense fallback={<ProductsSkeleton gridOnly />}>
          <FeaturedSectionWrapper
            featuredPage={featuredPage}
            page={page}
            search={search}
            category={category}
            sort={sort}
            blogPage={blogPage}
          />
        </Suspense>

        <Suspense fallback={<ProductsSkeleton />}>
          <ProductsSectionWrapper />
        </Suspense>

        <Suspense
          fallback={
            <div className="pt-10 pb-20 bg-slate-50/30 border-t border-slate-100">
              <div className="container mx-auto px-6">
                <BlogsSkeleton />
              </div>
            </div>
          }
        >
          <BlogsSectionWrapper
            blogPage={blogPage}
            page={page}
            search={search}
            category={category}
            sort={sort}
          />
        </Suspense>

        <TrackOrder />
        <ReviewsSection />
      </main>
      <Footer />
    </>
  );
}

// Wrapper to fetch featured products on the server side async
async function FeaturedSectionWrapper({
  featuredPage,
  page,
  search,
  category,
  sort,
  blogPage,
}: {
  featuredPage?: string;
  page?: string;
  search?: string;
  category?: string;
  sort?: string;
  blogPage?: string;
}) {
  const currentFeaturedPage = Number(featuredPage) || 1;

  let featuredData = null;
  try {
    featuredData = await getFeaturedProducts(currentFeaturedPage, 9);
  } catch (error) {
    console.error("Failed to fetch featured products:", error);
  }

  const totalPages = featuredData ? Math.ceil(featuredData.total / featuredData.limit) : 0;
  const productsList = featuredData?.data ?? [];

  if (!productsList || productsList.length === 0) return null;

  return (
    <FeaturedGrid
      featuredData={featuredData}
      currentPage={currentFeaturedPage}
      totalPages={totalPages}
      filterParams={{ page, search, category, sort, blogPage }}
    />
  );
}

// Wrapper to fetch products on the server side async
async function ProductsSectionWrapper() {
  let productsData = null;
  try {
    productsData = await getProducts({
      page: 1,
      limit: 11,
    }).catch((error) => {
      console.error("Failed to fetch products:", error);
      return null;
    });
  } catch (error) {
    console.error("Error fetching products:", error);
  }

  const productsList = productsData?.data ?? [];

  return (
    <ProductGrid
      products={productsList}
    />
  );
}

// Wrapper to fetch blogs on the server side async
async function BlogsSectionWrapper({
  blogPage,
  page,
  search,
  category,
  sort,
}: {
  blogPage?: string;
  page?: string;
  search?: string;
  category?: string;
  sort?: string;
}) {
  const currentBlogPage = Number(blogPage) || 1;

  let blogsData = null;
  try {
    blogsData = await getBlogs({
      page: currentBlogPage,
      limit: 3,
    });
  } catch (error) {
    console.error("Failed to fetch blogs:", error);
  }

  const totalPages = blogsData ? Math.ceil(blogsData.total / blogsData.limit) : 0;

  return (
    <BlogsSection
      blogData={blogsData}
      currentPage={currentBlogPage}
      totalPages={totalPages}
      filterParams={{ page, search, category, sort }}
    />
  );
}
