"use client";

import Link from "next/link";
import { usePathname, useRouter, useSearchParams } from "next/navigation";
import { useEffect, useMemo, useRef, useState } from "react";
import { ArrowRight, Loader2, MessageCircle, Search, X } from "lucide-react";

import { EvOnlyFloatingToggle } from "@/components/EvOnlyFloatingToggle";
import { ServiceFlowHero } from "@/app/services/ServiceFlowHero";
import { apiHeaders, apiPath } from "@/lib/api-url";
import { getWhatsAppUrl } from "@/lib/contact";
import {
  getEvModeStorageKey,
  getEvModeUrl,
  hasEvModePath,
  hasEvModeQuery,
  writeStoredEvMode,
} from "@/lib/ev-mode-state";
import { useUserLocation } from "@/lib/location-context";
import { routePath } from "@/lib/route-url";
import { cn } from "@/lib/utils";
import { formatCompanyName } from "@/lib/vehicle-display";
import type { VehiclePackageType } from "@/lib/vehicle-model-navigation";

type VehicleType = "car" | "bike";

export type VehicleModel = {
  id: number;
  name: string;
  slug: string;
  fuelType: string | null;
  engineCc: number | null;
  isEv?: boolean;
  image: string | null;
  manufacturerName: string;
  manufacturerLogo: string | null;
};

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

function getPackageTypeFromServiceSlug(serviceSlug?: string): VehiclePackageType {
  if (serviceSlug === "car-ac-service") {
    return "car_ac";
  }

  if (serviceSlug === "engine-repair") {
    return "engine_repair";
  }

  if (serviceSlug === "battery-service") {
    return "battery_service";
  }

  if (serviceSlug === "tyre-wheel") {
    return "tyre_wheel_service";
  }

  return "service_package";
}

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

export function VehicleModelsClient({
  vehicleType,
  manufacturerSlug,
  packageType,
  serviceSlug,
  initialModels,
  initialErrorMessage = "",
  initialEvOnly = false,
}: {
  vehicleType?: VehicleType;
  manufacturerSlug: string;
  packageType: string;
  serviceSlug?: string;
  initialModels?: VehicleModel[];
  initialErrorMessage?: string;
  initialEvOnly?: boolean;
}) {
  const { location } = useUserLocation();
  const router = useRouter();
  const pathname = usePathname();
  const searchParams = useSearchParams();
  const [models, setModels] = useState<VehicleModel[]>(initialModels ?? []);
  const [search, setSearch] = useState("");
  const [selectedFuel, setSelectedFuel] = useState("all");
  const [evOnly, setEvOnly] = useState(initialEvOnly);
  const [isLoading, setIsLoading] = useState(!initialModels && !initialErrorMessage);
  const [errorMessage, setErrorMessage] = useState(initialErrorMessage);
  const [reloadKey, setReloadKey] = useState(0);
  const usedInitialDataRef = useRef(false);
  const resolvedVehicleType = vehicleType ?? (serviceSlug === "bike-service" ? "bike" : "car");
  const supportsEvFilter = serviceSlug !== "battery-service" && serviceSlug !== "engine-repair";
  const activeEvOnly = supportsEvFilter && evOnly;
  const evModeStorageKey = getEvModeStorageKey(
    serviceSlug ?? `${resolvedVehicleType}-service`,
    resolvedVehicleType,
  );

  useEffect(() => {
    const queryEvOnly = hasEvModeQuery(searchParams);
    const urlEvOnly = supportsEvFilter && (hasEvModePath(pathname) || queryEvOnly);
    setEvOnly(urlEvOnly);

    if (supportsEvFilter && queryEvOnly) {
      router.replace(getEvModeUrl(pathname, searchParams, true), { scroll: false });
    }
  }, [pathname, router, searchParams, supportsEvFilter]);

  useEffect(() => {
    const reloadOnRestore = () => setReloadKey((currentKey) => currentKey + 1);

    window.addEventListener("pageshow", reloadOnRestore);
    window.addEventListener("popstate", reloadOnRestore);

    return () => {
      window.removeEventListener("pageshow", reloadOnRestore);
      window.removeEventListener("popstate", reloadOnRestore);
    };
  }, []);

  useEffect(() => {
    let isMounted = true;

    async function loadModels() {
      if (
        !usedInitialDataRef.current &&
        (initialModels || initialErrorMessage) &&
        reloadKey === 0 &&
        evOnly === initialEvOnly
      ) {
        usedInitialDataRef.current = true;
        return;
      }

      usedInitialDataRef.current = true;
      setIsLoading(true);
      setErrorMessage("");

      try {
        const response = await fetch(
          apiPath(
            `/api/vehicle-models?manufacturerSlug=${encodeURIComponent(manufacturerSlug)}${
              serviceSlug
                ? `&serviceSlug=${serviceSlug}${vehicleType ? `&vehicleType=${vehicleType}` : ""}`
                : vehicleType
                  ? `&vehicleType=${vehicleType}`
                  : ""
            }${activeEvOnly ? "&evOnly=true" : ""}`,
          ),
          {
            headers: apiHeaders(),
          },
        );
        const data = (await response.json()) as VehicleModelsResponse;

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

        if (isMounted) {
          setModels(data.models ?? []);
        }
      } catch (error) {
        if (isMounted) {
          setErrorMessage(error instanceof Error ? error.message : "Could not load vehicle models");
        }
      } finally {
        if (isMounted) {
          setIsLoading(false);
        }
      }
    }

    loadModels();

    return () => {
      isMounted = false;
    };
  }, [
    evOnly,
    activeEvOnly,
    initialErrorMessage,
    initialEvOnly,
    initialModels,
    manufacturerSlug,
    reloadKey,
    serviceSlug,
    vehicleType,
  ]);

  const companyName = formatCompanyName(models[0]?.manufacturerName ?? manufacturerSlug);
  const vehicleLabel = resolvedVehicleType === "car" ? "Car" : "Bike";
  const modelBackQuery = new URLSearchParams();

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

  const modelBackQueryString = modelBackQuery.toString();
  const backPath =
    serviceSlug && usesVehicleTypePath(serviceSlug)
      ? `/services/${serviceSlug}/${resolvedVehicleType}${activeEvOnly ? "/ev" : ""}`
      : `${serviceSlug ? `/services/${serviceSlug}${activeEvOnly ? "/ev" : ""}` : "/services"}${
          modelBackQueryString ? `?${modelBackQueryString}` : ""
        }`;
  const backHref = routePath(backPath);
  const fuelOptions = useMemo(() => {
    return Array.from(
      new Set(models.map((model) => model.fuelType).filter(Boolean) as string[]),
    ).sort((first, second) => first.localeCompare(second));
  }, [models]);

  const filteredModels = useMemo(() => {
    const query = search.trim().toLowerCase();

    return models.filter((model) => {
      const matchesSearch = !query || model.name.toLowerCase().includes(query);
      const matchesFuel = selectedFuel === "all" || model.fuelType === selectedFuel;

      return matchesSearch && matchesFuel;
    });
  }, [models, search, selectedFuel]);

  const whatsappMessage = `Hi Ride N Revive, I want to book service for my ${companyName} ${vehicleLabel.toLowerCase()}${
    location ? ` in ${location.name}` : ""
  }. Please help me.`;
  const selectedPackageType = (
    packageType && packageType !== "service_package"
      ? packageType
      : getPackageTypeFromServiceSlug(serviceSlug)
  ) as VehiclePackageType;
  const shouldKeepVehicleTypeInModelLinks =
    serviceSlug === "engine-repair" ||
    serviceSlug === "battery-service" ||
    serviceSlug === "tyre-wheel";

  function setEvMode(pressed: boolean) {
    if (!supportsEvFilter) {
      return;
    }

    setEvOnly(pressed);
    setSelectedFuel("all");
    setSearch("");
    writeStoredEvMode(evModeStorageKey, pressed);
    router.replace(getEvModeUrl(pathname, searchParams, pressed), { scroll: false });
  }

  return (
    <>
      <ServiceFlowHero
        currentPage={`${companyName} models`}
        eyebrow="Select model"
        title={`${companyName} ${vehicleLabel} Models`}
        lead="Search your model and filter by fuel type before booking doorstep service support."
        backHref={backHref}
        backLabel="Back to companies"
      />

      <section className="bg-slate-50 py-12 font-['Space_Grotesk'] md:py-16">
        <div className="mx-auto max-w-7xl px-4">
          <div className="rounded-lg border border-border bg-white p-4 shadow-sm">
            <div
              className={cn(
                "grid gap-3",
                activeEvOnly
                  ? "md:grid-cols-[minmax(0,1fr)_auto]"
                  : "md:grid-cols-[minmax(0,1fr)_220px_auto]",
              )}
            >
              <label className="relative">
                <Search className="absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" />
                <input
                  value={search}
                  onChange={(event) => setSearch(event.target.value)}
                  className="h-11 w-full rounded-md border border-input bg-white pl-9 pr-3 text-sm font-bold text-foreground outline-none transition focus:border-primary focus:ring-4 focus:ring-primary/10"
                  placeholder={`Search ${companyName} model`}
                />
              </label>
              {activeEvOnly ? null : (
                <select
                  value={selectedFuel}
                  onChange={(event) => setSelectedFuel(event.target.value)}
                  className="h-11 rounded-md border border-input bg-white px-3 text-sm font-bold text-foreground outline-none transition focus:border-primary focus:ring-4 focus:ring-primary/10"
                >
                  <option value="all">All fuel types</option>
                  {fuelOptions.map((fuel) => (
                    <option key={fuel} value={fuel}>
                      {fuel}
                    </option>
                  ))}
                </select>
              )}
              <button
                type="button"
                onClick={() => {
                  setSearch("");
                  setSelectedFuel("all");
                  setEvMode(false);
                }}
                className="inline-flex h-11 items-center justify-center gap-2 rounded-md border border-border bg-slate-50 px-4 text-sm font-black text-foreground transition hover:border-primary/30 hover:bg-primary/5 hover:text-primary"
              >
                <X className="h-4 w-4" />
                Reset
              </button>
            </div>
          </div>

          {errorMessage ? (
            <div className="mt-5 rounded-lg border border-primary/20 bg-primary/5 p-4 text-sm font-bold text-primary">
              {errorMessage}
            </div>
          ) : null}

          {isLoading ? (
            <div className="mt-5 grid min-h-56 place-items-center rounded-lg border border-border bg-white">
              <Loader2 className="h-6 w-6 animate-spin text-primary" />
            </div>
          ) : models.length === 0 ? (
            <div className="mt-5 rounded-lg border border-dashed border-border bg-white p-8 text-center">
              <h2 className="text-xl font-black text-foreground">Models are not listed yet</h2>
              <p className="mx-auto mt-2 max-w-xl text-sm font-semibold leading-6 text-muted-foreground">
                Send the company name on WhatsApp and the team will help you with the right service.
              </p>
              <Link
                href={getWhatsAppUrl(whatsappMessage)}
                target="_blank"
                rel="noreferrer"
                className="mt-5 inline-flex h-11 items-center justify-center gap-2 rounded-md bg-primary px-5 text-sm font-black text-primary-foreground transition hover:bg-primary/90"
              >
                <MessageCircle className="h-4 w-4" />
                Ask on WhatsApp
              </Link>
            </div>
          ) : filteredModels.length === 0 ? (
            <div className="mt-5 rounded-lg border border-dashed border-border bg-white p-8 text-center">
              <h2 className="text-xl font-black text-foreground">No models match this filter</h2>
              <p className="mt-2 text-sm font-semibold text-muted-foreground">
                Try another search or choose all fuel types.
              </p>
            </div>
          ) : (
            <div className="mt-5 grid gap-3 sm:grid-cols-2 lg:grid-cols-4 xl:grid-cols-5">
              {filteredModels.map((model) => {
                const modelPageQuery = new URLSearchParams();

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

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

                return (
                  <Link
                    key={model.id}
                    href={routePath(modelHref)}
                    className={cn(
                      "group overflow-hidden rounded-lg border border-border bg-white shadow-sm transition hover:border-primary/35 hover:shadow-md",
                      activeEvOnly &&
                        "border-emerald-400 ring-2 ring-emerald-200 hover:border-emerald-500",
                    )}
                  >
                    <div className="relative grid aspect-[5/3] place-items-center border-b border-border bg-slate-100">
                      {model.image || model.manufacturerLogo ? (
                        <img
                          src={model.image ?? model.manufacturerLogo ?? ""}
                          alt={`${model.name} image`}
                          className="h-full w-full object-contain p-3"
                          loading="lazy"
                        />
                      ) : (
                        <span className="text-sm font-black text-muted-foreground">
                          {companyName}
                        </span>
                      )}
                      {activeEvOnly ? (
                        <span className="absolute right-3 top-3 rounded-full border border-emerald-200 bg-emerald-500 px-2.5 py-1 text-[10px] font-black uppercase tracking-[0.14em] text-white shadow-sm">
                          EV
                        </span>
                      ) : null}
                    </div>
                    <div className="p-3">
                      <h2 className="line-clamp-2 min-h-[3rem] text-base font-black leading-6 text-foreground">
                        {model.name}
                      </h2>
                      <div className="mt-3 flex flex-wrap items-center gap-2">
                        {model.isEv ? (
                          <span className="rounded-md bg-emerald-100 px-2.5 py-1.5 text-xs font-black text-emerald-700">
                            Electric
                          </span>
                        ) : (
                          <>
                            <span className="rounded-md bg-primary/10 px-2.5 py-1.5 text-xs font-black text-primary">
                              {model.fuelType ?? "Fuel not set"}
                            </span>
                            <span className="rounded-md bg-slate-100 px-2.5 py-1.5 text-xs font-black text-slate-700">
                              {model.engineCc === null ? "CC not set" : `${model.engineCc} cc`}
                            </span>
                          </>
                        )}
                        <span
                          className={cn(
                            "ml-auto grid h-8 w-8 place-items-center rounded-full bg-foreground text-background transition group-hover:bg-primary group-hover:text-primary-foreground",
                            activeEvOnly && "bg-emerald-500 text-white group-hover:bg-emerald-600",
                          )}
                        >
                          <ArrowRight className="h-4 w-4" />
                        </span>
                      </div>
                    </div>
                  </Link>
                );
              })}
            </div>
          )}
        </div>
      </section>
      {supportsEvFilter ? (
        <EvOnlyFloatingToggle
          pressed={activeEvOnly}
          onPressedChange={setEvMode}
          label={resolvedVehicleType === "bike" ? "EV bikes" : "EV cars"}
        />
      ) : null}
    </>
  );
}
