"use client";

import Link from "next/link";
import { useRouter } from "next/navigation";
import { useEffect, useMemo, useState } from "react";
import { ArrowRight, Loader2 } from "lucide-react";
import { MotionReveal } from "@/components/Motion";
import { SectionHeader } from "@/components/SectionHeader";
import { apiHeaders, apiPath } from "@/lib/api-url";
import { useUserLocation } from "@/lib/location-context";
import { routePath } from "@/lib/route-url";
import { getVehicleCompanyModelHref } from "@/lib/vehicle-model-navigation";

type VehicleType = "bike" | "car";

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

type LogosResponse = {
  logos?: Company[];
  error?: string;
};

async function fetchPopularCompanies(vehicleType: VehicleType) {
  const response = await fetch(apiPath(`/api/vehicle-logos?vehicleType=${vehicleType}`), {
    headers: apiHeaders(),
  });
  const data = (await response.json()) as LogosResponse;

  if (!response.ok) {
    throw new Error(data.error ?? `Could not load ${vehicleType} companies`);
  }

  return (data.logos ?? [])
    .filter((company) => company.isPopular)
    .sort((first, second) => {
      const firstOrder = first.popularOrder ?? Number.MAX_SAFE_INTEGER;
      const secondOrder = second.popularOrder ?? Number.MAX_SAFE_INTEGER;

      return firstOrder - secondOrder || first.name.localeCompare(second.name);
    });
}

export function BrandsWeServeSection() {
  const { location } = useUserLocation();
  const [bikeCompanies, setBikeCompanies] = useState<Company[]>([]);
  const [carCompanies, setCarCompanies] = useState<Company[]>([]);
  const [isLoading, setIsLoading] = useState(true);
  const [errorMessage, setErrorMessage] = useState("");

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

    async function loadCompanies() {
      setIsLoading(true);
      setErrorMessage("");

      try {
        const [bikes, cars] = await Promise.all([
          fetchPopularCompanies("bike"),
          fetchPopularCompanies("car"),
        ]);

        if (isMounted) {
          setBikeCompanies(bikes);
          setCarCompanies(cars);
        }
      } catch (error) {
        if (isMounted) {
          setErrorMessage(error instanceof Error ? error.message : "Could not load brands");
        }
      } finally {
        if (isMounted) {
          setIsLoading(false);
        }
      }
    }

    loadCompanies();

    return () => {
      isMounted = false;
    };
  }, []);

  const hasBrands = bikeCompanies.length > 0 || carCompanies.length > 0;
  const locationName = location?.name ?? null;

  if (!isLoading && !hasBrands && !errorMessage) {
    return null;
  }

  return (
    <section className="overflow-hidden bg-slate-100 py-16 font-['Space_Grotesk'] md:py-24">
      <div className="mx-auto max-w-7xl px-4 md:px-6">
        <MotionReveal className="flex flex-col gap-6 md:flex-row md:items-end md:justify-between">
          <SectionHeader
            eyebrow="Brands we serve"
            title={`Popular companies covered at your doorstep${locationName ? ` in ${locationName}` : ""}.`}
            lead={`Choose your vehicle brand to see doorstep service support${locationName ? ` available around ${locationName}` : " available near you"}.`}
          />
          <Link
            href={routePath("/services")}
            className="inline-flex w-fit shrink-0 items-center justify-center gap-2 rounded-full bg-zinc-950 px-6 py-3 text-sm font-black text-white shadow-[0_14px_34px_rgba(0,0,0,0.18)] transition hover:-translate-y-0.5 hover:bg-primary active:scale-95"
          >
            Book service
            <ArrowRight className="h-4 w-4" />
          </Link>
        </MotionReveal>
        <MotionReveal delay={0.08} className="mt-8 space-y-5 2xl:mt-12">
          {isLoading ? (
            <>
              <BrandRowSkeleton />
              <BrandRowSkeleton />
            </>
          ) : null}

          {!isLoading && errorMessage ? (
            <div className="rounded-md border border-primary/20 bg-primary/5 px-4 py-3 text-sm font-semibold text-primary">
              {errorMessage}
            </div>
          ) : null}

          {!isLoading && bikeCompanies.length > 0 ? (
            <BrandMarquee companies={bikeCompanies} />
          ) : null}

          {!isLoading && carCompanies.length > 0 ? (
            <BrandMarquee companies={carCompanies} reverse />
          ) : null}
        </MotionReveal>
      </div>
    </section>
  );
}

function BrandMarquee({ companies, reverse = false }: { companies: Company[]; reverse?: boolean }) {
  const visibleCompanies = useMemo(
    () =>
      Array.from({ length: Math.max(4, Math.ceil(12 / companies.length)) }).flatMap(
        () => companies,
      ),
    [companies],
  );

  return (
    <div className="brand-marquee-mask rounded-md">
      <div className={`brand-marquee-track ${reverse ? "brand-marquee-track-reverse" : ""}`}>
        <BrandLogoGroup companies={visibleCompanies} vehicleType={reverse ? "car" : "bike"} />
        <BrandLogoGroup
          companies={visibleCompanies}
          vehicleType={reverse ? "car" : "bike"}
          ariaHidden
        />
      </div>
    </div>
  );
}

function BrandLogoGroup({
  companies,
  vehicleType,
  ariaHidden = false,
}: {
  companies: Company[];
  vehicleType: VehicleType;
  ariaHidden?: boolean;
}) {
  const router = useRouter();
  const { location } = useUserLocation();
  const [loadingCompanyId, setLoadingCompanyId] = useState<number | null>(null);

  async function openCompany(company: Company) {
    if (ariaHidden || loadingCompanyId) {
      return;
    }

    setLoadingCompanyId(company.id);

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

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

  return (
    <div aria-hidden={ariaHidden} className="brand-marquee-group">
      {companies.map((company, index) => (
        <button
          type="button"
          disabled={ariaHidden || loadingCompanyId !== null}
          onClick={() => openCompany(company)}
          className="brand-logo-tile relative disabled:cursor-default"
          key={`${company.id}-${index}`}
          aria-label={`Open ${company.name} models`}
          tabIndex={ariaHidden ? -1 : undefined}
        >
          {company.logo ? (
            <img
              src={company.logo}
              alt={ariaHidden ? "" : `${company.name} logo`}
              className="h-12 max-w-28 object-contain sm:h-14 sm:max-w-32"
              loading="lazy"
            />
          ) : (
            <span className="text-sm font-black text-zinc-700">{company.name}</span>
          )}
          {loadingCompanyId === company.id ? (
            <span className="absolute inset-0 grid place-items-center rounded-md bg-white/80">
              <Loader2 className="h-5 w-5 animate-spin text-primary" />
            </span>
          ) : null}
        </button>
      ))}
    </div>
  );
}

function BrandRowSkeleton() {
  return (
    <div className="flex gap-4 overflow-hidden">
      {Array.from({ length: 8 }).map((_, index) => (
        <div
          className="h-20 min-w-36 rounded-md border border-zinc-200 bg-zinc-100 sm:min-w-44"
          key={index}
        />
      ))}
    </div>
  );
}
