"use client";

import Image from "next/image";
import Link from "next/link";
import { usePathname, useRouter, useSearchParams } from "next/navigation";
import { type MouseEvent, useEffect, useMemo, useRef, useState } from "react";
import { ArrowUpRight, Car, Loader2, MapPin, Search, Star, X } from "lucide-react";
import { EvOnlyFloatingToggle } from "@/components/EvOnlyFloatingToggle";
import { getWhatsAppUrl } from "@/lib/contact";
import {
  getEvModeUrl,
  getEvModeStorageKey,
  hasEvModePath,
  hasEvModeQuery,
  readStoredEvMode,
  writeStoredEvMode,
} from "@/lib/ev-mode-state";
import { useUserLocation } from "@/lib/location-context";
import { apiHeaders, apiPath } from "@/lib/api-url";
import { cn } from "@/lib/utils";
import { getVehicleCompanyModelHref } from "@/lib/vehicle-model-navigation";
import { ServiceFlowHero } from "../ServiceFlowHero";

export type CarCompany = {
  id: number;
  name: string;
  slug: string;
  logo: string;
  isPopular: boolean;
  popularOrder: number | null;
};

export function CarAcCompaniesClient({
  initialCompanies,
  initialErrorMessage = "",
}: {
  initialCompanies?: CarCompany[];
  initialErrorMessage?: string;
}) {
  const router = useRouter();
  const pathname = usePathname();
  const searchParams = useSearchParams();
  const [companies, setCompanies] = useState<CarCompany[]>(initialCompanies ?? []);
  const [search, setSearch] = useState("");
  const evModeStorageKey = getEvModeStorageKey("car-ac-service", "car");
  const [evOnly, setEvOnly] = useState(
    () => hasEvModePath(pathname) || hasEvModeQuery(searchParams),
  );
  const [isLoading, setIsLoading] = useState(!initialCompanies && !initialErrorMessage);
  const [errorMessage, setErrorMessage] = useState(initialErrorMessage);
  const [reloadKey, setReloadKey] = useState(0);
  const usedInitialDataRef = useRef(false);
  const { location } = useUserLocation();

  useEffect(() => {
    const queryEvOnly = hasEvModeQuery(searchParams);
    const urlEvOnly = hasEvModePath(pathname) || queryEvOnly;
    const storedEvOnly = readStoredEvMode(evModeStorageKey);
    const nextEvOnly = urlEvOnly || storedEvOnly === true;

    setEvOnly(nextEvOnly);

    if (queryEvOnly || (!urlEvOnly && storedEvOnly === true)) {
      router.replace(getEvModeUrl(pathname, searchParams, true), { scroll: false });
    }
  }, [evModeStorageKey, pathname, router, searchParams]);

  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 loadCompanies() {
      if (
        !usedInitialDataRef.current &&
        (initialCompanies || initialErrorMessage) &&
        reloadKey === 0 &&
        !evOnly
      ) {
        usedInitialDataRef.current = true;
        return;
      }

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

      try {
        const response = await fetch(
          apiPath(`/api/vehicle-logos?vehicleType=car${evOnly ? "&evOnly=true" : ""}`),
          {
            headers: apiHeaders(),
          },
        );

        if (!response.ok) {
          throw new Error("Could not load car companies");
        }

        const data = (await response.json()) as { logos: CarCompany[] };

        if (isMounted) {
          setCompanies(data.logos);
        }
      } catch (error) {
        if (isMounted) {
          setErrorMessage(error instanceof Error ? error.message : "Could not load car companies");
        }
      } finally {
        if (isMounted) {
          setIsLoading(false);
        }
      }
    }

    loadCompanies();

    return () => {
      isMounted = false;
    };
  }, [evOnly, initialCompanies, initialErrorMessage, reloadKey]);

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

    if (!query) {
      return companies;
    }

    return companies.filter((company) => company.name.toLowerCase().includes(query));
  }, [companies, search]);

  const popularCompanies = sortPopularCompanies(
    filteredCompanies.filter((company) => company.isPopular),
  );
  const remainingCompanies = filteredCompanies.filter((company) => !company.isPopular);
  const hasSearch = search.trim().length > 0;
  const resultStateKey = `${evOnly ? "ev" : "all"}-${
    hasSearch ? `search-${search.trim().toLowerCase()}` : "default"
  }`;

  function resetSearch() {
    setSearch("");
  }

  function setEvMode(pressed: boolean) {
    setEvOnly(pressed);
    writeStoredEvMode(evModeStorageKey, pressed);
    router.replace(getEvModeUrl(pathname, searchParams, pressed), { scroll: false });
  }

  return (
    <>
      <ServiceFlowHero
        currentPage="Car AC Service"
        eyebrow="Doorstep cooling care"
        title="Choose your car company."
        lead={`Search supported brands and send a faster AC service request with the company${
          location ? ` and ${location.name} location` : ""
        } already included.`}
      />

      <section className="bg-gradient-to-b from-white via-slate-50 to-white py-14 font-['Space_Grotesk'] 2xl:py-20">
        <div className="mx-auto max-w-7xl px-4">
          <StickyCompanySearch
            search={search}
            onSearchChange={setSearch}
            onClear={resetSearch}
            hasSearch={hasSearch}
            isLoading={isLoading}
            shownCount={filteredCompanies.length}
            totalCount={companies.length}
            locationName={location?.name ?? null}
            placeholder="Search car company"
          />

          {errorMessage ? (
            <p className="mt-6 rounded-xl border border-destructive/25 bg-destructive/10 px-4 py-3 text-sm font-bold text-destructive">
              {errorMessage}
            </p>
          ) : null}

          {isLoading ? (
            <CompanySkeletonGrid />
          ) : filteredCompanies.length === 0 ? (
            <div className="mt-8 rounded-2xl border border-dashed border-border bg-white px-4 py-14 text-center">
              <Car className="mx-auto h-10 w-10 text-primary" />
              <p className="mt-4 text-lg font-black text-foreground">No car company found</p>
              <p className="mt-2 text-sm font-semibold text-muted-foreground">
                Try another brand name or clear the search.
              </p>
              {hasSearch ? (
                <button
                  type="button"
                  onClick={resetSearch}
                  className="mt-5 rounded-full bg-primary px-5 py-2.5 text-sm font-black text-primary-foreground transition hover:opacity-90"
                >
                  Clear search
                </button>
              ) : null}
            </div>
          ) : (
            <div key={resultStateKey} className="space-y-12">
              {popularCompanies.length > 0 ? (
                <CompanySection
                  eyebrow={`${popularCompanies.length} popular`}
                  title="Popular companies"
                  companies={popularCompanies}
                  evOnly={evOnly}
                  featured
                />
              ) : null}

              <CompanySection
                eyebrow={`${remainingCompanies.length} companies`}
                title={popularCompanies.length > 0 ? "All other companies" : "Car companies"}
                companies={remainingCompanies}
                evOnly={evOnly}
              />
            </div>
          )}
        </div>
      </section>
      <EvOnlyFloatingToggle pressed={evOnly} onPressedChange={setEvMode} label="EV cars" />
    </>
  );
}

function sortPopularCompanies(companies: CarCompany[]) {
  return [...companies].sort(
    (a, b) =>
      (a.popularOrder ?? Number.MAX_SAFE_INTEGER) - (b.popularOrder ?? Number.MAX_SAFE_INTEGER) ||
      a.name.localeCompare(b.name),
  );
}

function StickyCompanySearch({
  search,
  onSearchChange,
  onClear,
  hasSearch,
  isLoading,
  shownCount,
  totalCount,
  locationName,
  placeholder,
}: {
  search: string;
  onSearchChange: (value: string) => void;
  onClear: () => void;
  hasSearch: boolean;
  isLoading: boolean;
  shownCount: number;
  totalCount: number;
  locationName: string | null;
  placeholder: string;
}) {
  return (
    <div className="sticky top-24 z-30 rounded-2xl border border-border/70 bg-white/90 p-2 shadow-[0_16px_46px_rgba(0,0,0,0.12)] backdrop-blur-xl">
      <div className="flex flex-col gap-2 md:flex-row md:items-center">
        <label className="relative block min-w-0 flex-1">
          <Search className="pointer-events-none absolute left-4 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" />
          <input
            value={search}
            onChange={(event) => onSearchChange(event.target.value)}
            placeholder={placeholder}
            className="h-12 w-full rounded-xl border border-transparent bg-slate-50 pl-11 pr-11 text-sm font-black outline-none transition placeholder:text-muted-foreground/80 focus:border-primary focus:bg-white focus:ring-4 focus:ring-primary/10"
          />
          {hasSearch ? (
            <button
              type="button"
              onClick={onClear}
              className="absolute right-3 top-1/2 grid h-7 w-7 -translate-y-1/2 place-items-center rounded-full text-muted-foreground transition hover:bg-slate-200 hover:text-foreground"
              aria-label="Clear company search"
            >
              <X className="h-4 w-4" />
            </button>
          ) : null}
        </label>
        <div className="flex shrink-0 flex-wrap items-center gap-2 px-1 text-xs font-black uppercase tracking-[0.12em] text-muted-foreground md:px-2">
          <span className="rounded-full border border-border bg-white px-3 py-1.5">
            {isLoading ? "Loading" : `${shownCount} of ${totalCount}`}
          </span>
          {locationName ? (
            <span className="inline-flex items-center gap-1 rounded-full border border-primary/20 bg-primary/5 px-3 py-1.5 text-primary">
              <MapPin className="h-3 w-3" />
              {locationName}
            </span>
          ) : null}
        </div>
      </div>
    </div>
  );
}

function CompanySection({
  eyebrow,
  title,
  companies,
  evOnly,
  featured = false,
}: {
  eyebrow: string;
  title: string;
  companies: CarCompany[];
  evOnly: boolean;
  featured?: boolean;
}) {
  const initialVisibleCount = 20;
  const [visibleCount, setVisibleCount] = useState(initialVisibleCount);
  const loadMoreRef = useRef<HTMLDivElement | null>(null);

  useEffect(() => {
    setVisibleCount(initialVisibleCount);
  }, [companies.length, initialVisibleCount]);

  const visibleCompanies = companies.slice(0, visibleCount);
  const remainingCount = companies.length - visibleCompanies.length;

  useEffect(() => {
    if (remainingCount <= 0 || !loadMoreRef.current) {
      return;
    }

    const observer = new IntersectionObserver(
      ([entry]) => {
        if (entry.isIntersecting) {
          setVisibleCount((current) => Math.min(current + 20, companies.length));
        }
      },
      { rootMargin: "360px 0px" },
    );

    observer.observe(loadMoreRef.current);

    return () => observer.disconnect();
  }, [companies.length, remainingCount]);

  if (companies.length === 0) {
    return null;
  }

  return (
    <div className="mt-8">
      <div className="mb-5 flex items-end justify-between gap-4">
        <div>
          <p className="text-xs font-black uppercase tracking-[0.18em] text-primary">{eyebrow}</p>
          <h3 className="mt-2 font-display text-2xl font-bold tracking-tight text-foreground sm:text-3xl">
            {title}
          </h3>
        </div>
      </div>
      <div className={cn("grid grid-cols-2 gap-3 sm:gap-4 lg:grid-cols-3", "xl:grid-cols-5")}>
        {visibleCompanies.map((company) => (
          <CompanyCard key={company.id} company={company} evOnly={evOnly} featured={featured} />
        ))}
      </div>
      {remainingCount > 0 ? (
        <div
          ref={loadMoreRef}
          className="mt-6 grid grid-cols-2 gap-3 sm:gap-4 lg:grid-cols-3 xl:grid-cols-5"
        >
          {Array.from({ length: Math.min(4, remainingCount) }).map((_, index) => (
            <CompanySkeleton key={index} />
          ))}
        </div>
      ) : null}
    </div>
  );
}

function CompanyCard({
  company,
  evOnly,
  featured,
}: {
  company: CarCompany;
  evOnly: boolean;
  featured: boolean;
}) {
  const { location, resolvedName, state } = useUserLocation();
  const router = useRouter();
  const [isCheckingModels, setIsCheckingModels] = useState(false);
  const whatsappMessage = `Hi Ride N Revive, I want to book Car AC Service for ${company.name}${
    location ? ` in ${location.name}` : ""
  }. Please help me.`;

  async function openCompany(event: MouseEvent<HTMLAnchorElement>) {
    event.preventDefault();

    if (state === "unavailable") {
      window.alert(
        `Service is not available in your area${resolvedName ? ` (${resolvedName})` : ""}.`,
      );
      return;
    }

    setIsCheckingModels(true);

    try {
      const target = await getVehicleCompanyModelHref({
        vehicleType: "car",
        servicePath: "car-ac-service",
        companyName: company.name,
        companySlug: company.slug,
        locationName: location?.name,
        packageType: "car_ac",
        evOnly,
      });

      if (target.external) {
        window.open(target.href, "_blank", "noopener,noreferrer");
      } else {
        router.push(target.href);
      }
    } finally {
      setIsCheckingModels(false);
    }
  }

  return (
    <>
      <a
        href={getWhatsAppUrl(whatsappMessage)}
        target="_blank"
        rel="noreferrer"
        onClick={openCompany}
        className={cn(
          "group block h-full overflow-hidden rounded-xl border bg-white text-left shadow-[0_10px_28px_rgba(0,0,0,0.07)] transition-colors duration-200 hover:border-primary/40 hover:shadow-[0_14px_34px_rgba(0,0,0,0.1)]",
          featured ? "border-primary/30 ring-2 ring-primary/10" : "border-border",
          evOnly && "border-emerald-400 ring-2 ring-emerald-200 hover:border-emerald-500",
        )}
      >
        <div className="relative aspect-[4/3] border-b border-border bg-white">
          <Image
            src={company.logo}
            alt={`${company.name} logo`}
            fill
            loading="lazy"
            sizes="(min-width: 1280px) 220px, (min-width: 640px) 50vw, 100vw"
            className="object-contain p-4 sm:p-8"
          />
          {company.isPopular ? (
            <span className="absolute left-2 top-2 inline-flex h-7 w-7 items-center justify-center rounded-full bg-white text-primary shadow-sm sm:left-3 sm:top-3 sm:h-auto sm:w-auto sm:gap-1.5 sm:px-3 sm:py-1.5 sm:text-[10px] sm:font-black sm:uppercase sm:tracking-[0.14em]">
              <Star className="h-3 w-3 fill-primary" />
              <span className="hidden sm:inline">Popular</span>
            </span>
          ) : null}
          {evOnly ? (
            <span className="absolute right-2 top-2 inline-flex items-center gap-1 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 sm:right-3 sm:top-3">
              EV
            </span>
          ) : null}
        </div>
        <div className="flex items-center justify-between gap-2 p-3 sm:gap-3 sm:p-4">
          <div className="min-w-0">
            <h4 className="truncate text-sm font-black tracking-tight text-foreground sm:text-lg">
              {company.name}
            </h4>
            <p className="mt-1 hidden text-xs font-bold uppercase tracking-[0.14em] text-muted-foreground sm:block">
              Tap to request AC service
            </p>
          </div>
          <span
            className={cn(
              "grid h-8 w-8 shrink-0 place-items-center rounded-full bg-foreground text-background transition-colors group-hover:bg-primary group-hover:text-primary-foreground sm:h-10 sm:w-10",
              evOnly && "bg-emerald-500 text-white group-hover:bg-emerald-600",
            )}
          >
            {isCheckingModels ? (
              <Loader2 className="h-4 w-4 animate-spin" />
            ) : (
              <ArrowUpRight className="h-4 w-4" />
            )}
          </span>
        </div>
      </a>
    </>
  );
}

function CompanySkeletonGrid() {
  return (
    <div className="mt-8 space-y-10">
      <div>
        <div className="shimmer-surface h-5 w-40 rounded-full" />
        <div className="mt-5 grid grid-cols-2 gap-3 sm:gap-4 lg:grid-cols-3 xl:grid-cols-5">
          {Array.from({ length: 4 }).map((_, index) => (
            <CompanySkeleton key={index} />
          ))}
        </div>
      </div>
      <div>
        <div className="shimmer-surface h-5 w-48 rounded-full" />
        <div className="mt-5 grid grid-cols-2 gap-3 sm:gap-4 lg:grid-cols-3 xl:grid-cols-5">
          {Array.from({ length: 10 }).map((_, index) => (
            <CompanySkeleton key={index} />
          ))}
        </div>
      </div>
    </div>
  );
}

function CompanySkeleton() {
  return (
    <div className="overflow-hidden rounded-xl border border-border bg-white shadow-sm">
      <div className="shimmer-surface aspect-[4/3]" />
      <div className="p-4">
        <div className="shimmer-surface h-5 w-2/3 rounded-full" />
        <div className="shimmer-surface mt-2 h-3 w-1/2 rounded-full" />
      </div>
    </div>
  );
}
