import type { Metadata } from "next";
import { redirect } from "next/navigation";
import { Suspense } from "react";
import {
  VehicleModelsClient,
  type VehicleModel,
} from "@/app/vehicle-models/[vehicleType]/[manufacturerSlug]/VehicleModelsClient";
import { serverApiBaseUrl } from "@/lib/api-url";
import { formatCompanyName, formatModelName } from "@/lib/vehicle-display";
import { JsonLd, breadcrumbJsonLd, serviceJsonLd } from "@/lib/seo";

type ServiceModelsPageProps = {
  params: Promise<{
    serviceSlug: string;
    manufacturerSlug: string;
  }>;
  searchParams?: Promise<{
    packageType?: string;
    vehicleType?: string;
    ev?: string;
    evOnly?: string;
  }>;
};

type VehicleModelsResponse = {
  models?: VehicleModel[];
  error?: string;
};

const serviceTitles: Record<string, string> = {
  "car-service": "Car Service",
  "bike-service": "Bike Service",
  "car-ac-service": "Car AC Service",
  "engine-repair": "Engine Repair",
  "battery-service": "Battery Service",
  "tyre-wheel": "Tyre & Wheel",
};

function getRouteVehicleType(serviceSlug: string) {
  if (serviceSlug === "bike-service") {
    return "bike" as const;
  }

  if (serviceSlug === "car-service" || serviceSlug === "car-ac-service") {
    return "car" as const;
  }

  return undefined;
}

function getSearchVehicleType(vehicleType?: string) {
  return vehicleType === "bike" ? "bike" : vehicleType === "car" ? "car" : undefined;
}

function getServiceName(serviceSlug: string) {
  return serviceTitles[serviceSlug] ?? "Vehicle Service";
}

function usesVehicleTypePath(serviceSlug: string) {
  return (
    serviceSlug === "engine-repair" ||
    serviceSlug === "battery-service" ||
    serviceSlug === "tyre-wheel"
  );
}

function supportsEvFilter(serviceSlug: string) {
  return (
    serviceSlug === "car-service" ||
    serviceSlug === "bike-service" ||
    serviceSlug === "car-ac-service" ||
    serviceSlug === "tyre-wheel"
  );
}

export async function generateMetadata({ params }: ServiceModelsPageProps): Promise<Metadata> {
  const { serviceSlug, manufacturerSlug } = await params;
  const companyName = formatCompanyName(decodeURIComponent(manufacturerSlug));
  const serviceName = getServiceName(serviceSlug);

  return {
    title: `${companyName} Models for ${serviceName}`,
    description: `Select your ${companyName} model for ${serviceName} with Ride N Revive.`,
    alternates: {
      canonical: `/services/${serviceSlug}/${manufacturerSlug}`,
    },
  };
}

export async function renderServiceModelsPage(
  { params, searchParams }: ServiceModelsPageProps,
  initialEvOnlyFromPath = false,
  shouldRedirectLegacyVehicleTypeUrl = true,
) {
  const { serviceSlug, manufacturerSlug } = await params;
  const companyName = formatCompanyName(decodeURIComponent(manufacturerSlug));
  const serviceName = getServiceName(serviceSlug);
  const resolvedSearchParams = await searchParams;
  const resolvedVehicleType =
    getRouteVehicleType(serviceSlug) ?? getSearchVehicleType(resolvedSearchParams?.vehicleType);
  const canUseEvFilter = supportsEvFilter(serviceSlug);
  const initialEvOnly =
    canUseEvFilter &&
    (initialEvOnlyFromPath ||
      resolvedSearchParams?.ev === "1" ||
      resolvedSearchParams?.evOnly === "true");

  if (
    shouldRedirectLegacyVehicleTypeUrl &&
    resolvedVehicleType &&
    usesVehicleTypePath(serviceSlug)
  ) {
    const nextParams = new URLSearchParams();

    if (resolvedSearchParams?.packageType) {
      nextParams.set("packageType", resolvedSearchParams.packageType);
    }

    const queryString = nextParams.toString();
    redirect(
      `/services/${serviceSlug}/${resolvedVehicleType}/${manufacturerSlug}${
        initialEvOnly ? "/ev" : ""
      }${queryString ? `?${queryString}` : ""}`,
    );
  }

  if (
    canUseEvFilter &&
    !initialEvOnlyFromPath &&
    (resolvedSearchParams?.ev === "1" || resolvedSearchParams?.evOnly === "true")
  ) {
    const nextParams = new URLSearchParams();

    if (resolvedSearchParams?.packageType) {
      nextParams.set("packageType", resolvedSearchParams.packageType);
    }

    if (resolvedSearchParams?.vehicleType) {
      nextParams.set("vehicleType", resolvedSearchParams.vehicleType);
    }

    const queryString = nextParams.toString();
    redirect(
      `/services/${serviceSlug}/${manufacturerSlug}/ev/${queryString ? `?${queryString}` : ""}`,
    );
  }
  let initialModels: VehicleModel[] | undefined;
  let initialErrorMessage = "";

  try {
    const response = await fetch(
      `${serverApiBaseUrl}/api/vehicle-models?manufacturerSlug=${encodeURIComponent(
        decodeURIComponent(manufacturerSlug),
      )}&serviceSlug=${encodeURIComponent(serviceSlug)}${
        resolvedVehicleType ? `&vehicleType=${resolvedVehicleType}` : ""
      }${initialEvOnly ? "&evOnly=true" : ""}`,
      { cache: "no-store" },
    );
    const data = (await response.json().catch(() => ({}))) as VehicleModelsResponse;

    if (!response.ok) {
      throw new Error(data.error ?? "Could not load vehicle models");
    }

    initialModels = data.models ?? [];
  } catch (error) {
    initialErrorMessage = error instanceof Error ? error.message : "Could not load vehicle models";
  }

  return (
    <>
      <JsonLd
        data={[
          serviceJsonLd({
            name: `${companyName} ${serviceName}`,
            description: `Select a ${companyName} model for ${serviceName} with Ride N Revive doorstep vehicle support.`,
            path: `/services/${serviceSlug}/${manufacturerSlug}/`,
            serviceType: serviceName,
          }),
          breadcrumbJsonLd([
            { name: "Home", path: "/" },
            { name: "Services", path: "/services/" },
            { name: serviceName, path: `/services/${serviceSlug}/` },
            { name: companyName, path: `/services/${serviceSlug}/${manufacturerSlug}/` },
          ]),
        ]}
      />
      <Suspense fallback={null}>
        <VehicleModelsClient
          vehicleType={resolvedVehicleType}
          manufacturerSlug={decodeURIComponent(manufacturerSlug)}
          packageType={resolvedSearchParams?.packageType ?? "service_package"}
          serviceSlug={serviceSlug}
          initialModels={initialModels}
          initialErrorMessage={initialErrorMessage}
          initialEvOnly={initialEvOnly}
        />
      </Suspense>
      {initialModels && initialModels.length > 0 ? (
        <section className="bg-white font-['Space_Grotesk']">
          <div className="mx-auto max-w-7xl px-4 pb-14 md:px-6 2xl:pb-20">
            <div className="border-t border-border pt-8">
              <h2 className="text-xl font-black tracking-tight text-foreground">
                {companyName} {serviceName} by model
              </h2>
              <div className="mt-5 flex flex-wrap gap-2">
                {initialModels.slice(0, 36).map((model) => {
                  const modelPageQuery = new URLSearchParams();

                  if (resolvedVehicleType && usesVehicleTypePath(serviceSlug)) {
                    modelPageQuery.set("vehicleType", resolvedVehicleType);
                  }

                  const modelPageQueryString = modelPageQuery.toString();
                  const modelHref =
                    resolvedVehicleType && usesVehicleTypePath(serviceSlug)
                      ? `/services/${serviceSlug}/${resolvedVehicleType}/${encodeURIComponent(
                          manufacturerSlug,
                        )}/${encodeURIComponent(model.slug)}`
                      : `/services/${serviceSlug}/${encodeURIComponent(
                          manufacturerSlug,
                        )}/${encodeURIComponent(model.slug)}/${
                          modelPageQueryString ? `?${modelPageQueryString}` : ""
                        }`;

                  return (
                    <a
                      key={model.id}
                      href={modelHref}
                      className="rounded-md border border-border bg-slate-50 px-3 py-2 text-sm font-bold text-muted-foreground transition hover:border-primary/40 hover:bg-primary/5 hover:text-primary"
                    >
                      {formatModelName(model.slug, companyName)}
                    </a>
                  );
                })}
              </div>
            </div>
          </div>
        </section>
      ) : null}
    </>
  );
}

export default async function ServiceModelsPage(props: ServiceModelsPageProps) {
  return renderServiceModelsPage(props);
}
