"use client";

import Breadcrumb from "@/components/Breadcrumbs/Breadcrumb";
import { ShowcaseSection } from "@/components/Layouts/showcase-section";
import Loading from "@/components/loading";
import {
  useGetTenderDocumentsQuery,
  useTenderDetailQuery,
  useTranslateTenderMutation,
} from "@/hooks/queries";
import type {
  TTenderDetails,
  TTenderDocumentsResponse,
} from "@/lib/api/types/Tenders";
import { usePathname, useRouter, useSearchParams } from "next/navigation";
import { use, useCallback, useEffect, useMemo, useRef } from "react";
import { TenderDetailsContent } from "./components/tender-details-content";
import { TenderDetailsError } from "./components/tender-details-error";
import { TenderDetailsHeader } from "./components/tender-details-header";
import { useTenderSectionScrollSpy } from "./hooks/use-tender-section-scroll-spy";
import { getTenderNavItems } from "./tender-nav-utils";

interface IProps {
  params: Promise<{
    details: string;
  }>;
}

// Backend has shipped the documents payload as a bare array, an `ApiResponse`
// wrapper, and a `{ data: { documents: [...] } }` wrapper at different times.
// Normalize so a real list is never dropped because of a wrapper mismatch.
function extractTenderDocuments(
  payload: unknown,
): TTenderDocumentsResponse[] {
  if (!payload) return [];
  if (Array.isArray(payload)) return payload as TTenderDocumentsResponse[];

  const wrapper = payload as {
    data?: unknown;
    documents?: unknown;
  };

  if (Array.isArray(wrapper.documents)) {
    return wrapper.documents as TTenderDocumentsResponse[];
  }
  if (Array.isArray(wrapper.data)) {
    return wrapper.data as TTenderDocumentsResponse[];
  }
  if (wrapper.data && typeof wrapper.data === "object") {
    const inner = (wrapper.data as { documents?: unknown }).documents;
    if (Array.isArray(inner)) return inner as TTenderDocumentsResponse[];
  }
  return [];
}

const TenderDetails = ({ params }: IProps) => {
  const { details } = use(params);
  const router = useRouter();
  const pathname = usePathname();
  const searchParams = useSearchParams();
  const selectedLanguage = searchParams.get("lang") || "en";
  const { mutate: translateTender, isPending: isTranslating } =
    useTranslateTenderMutation();
  const { data, isLoading, isError, isFetching } = useTenderDetailQuery(
    details,
    { language: selectedLanguage },
  );

  const breadcrumbItems = [
    { name: "Dashboard", href: "/" },
    { name: "Tenders", href: "/tenders" },
    { name: "Tender details", href: `/tenders/${details}` },
  ];

  const tenderForNav = data?.data;
  const { data: documentsResponse, isPending: isDocumentsLoading } =
    useGetTenderDocumentsQuery(details, { enabled: Boolean(tenderForNav) });
  const documents = extractTenderDocuments(documentsResponse);

  const showDocumentsSection =
    Boolean(tenderForNav) && !isDocumentsLoading && documents.length > 0;

  const tenderNavItems = useMemo(
    () =>
      tenderForNav
        ? getTenderNavItems(tenderForNav, {
            showDocuments: showDocumentsSection,
          })
        : [],
    [tenderForNav, showDocumentsSection],
  );

  const sectionIds = useMemo(
    () => tenderNavItems.map((item) => item.id),
    [tenderNavItems],
  );
  const activeSectionId = useTenderSectionScrollSpy(sectionIds);

  // Only translate when the user explicitly picks a language from the dropdown.
  // The ref is set inside handleLanguageChange and consumed by the effect once
  // the GET refetch resolves; initial page loads never trigger a translate.
  const userPendingLangRef = useRef<string | null>(null);
  const attemptedRef = useRef<Set<string>>(new Set());

  const handleLanguageChange = useCallback(
    (event: React.ChangeEvent<HTMLSelectElement>) => {
      const nextLanguage = event.target.value;
      if (!nextLanguage) return;

      const prevLanguage = searchParams.get("lang") || "en";
      if (nextLanguage === prevLanguage) return;

      userPendingLangRef.current = nextLanguage;

      const nextParams = new URLSearchParams(searchParams.toString());
      nextParams.set("lang", nextLanguage);
      const queryString = nextParams.toString();
      router.replace(queryString ? `${pathname}?${queryString}` : pathname);
    },
    [pathname, router, searchParams],
  );

  // ensureTranslation flow (per backend integration doc):
  // 1) User picks a language → handleLanguageChange marks it as pending.
  // 2) GET detail with ?language={selected} refetches.
  // 3) If the refetched data.language doesn't match, POST ai-translate.
  //    The mutation's onSuccess invalidates the detail query → refetch binds title/description.
  // attemptedRef prevents a retry loop if translation fails.
  useEffect(() => {
    const fetched = data?.data;
    if (!fetched) return;
    if (isFetching || isTranslating) return;

    const pending = userPendingLangRef.current;
    if (!pending || pending !== selectedLanguage) return;

    if (fetched.language === selectedLanguage) {
      userPendingLangRef.current = null;
      return;
    }

    const key = `${details}::${selectedLanguage}`;
    if (attemptedRef.current.has(key)) {
      userPendingLangRef.current = null;
      return;
    }
    attemptedRef.current.add(key);
    userPendingLangRef.current = null;

    translateTender({ id: details, language: selectedLanguage });
  }, [
    data,
    details,
    isFetching,
    isTranslating,
    selectedLanguage,
    translateTender,
  ]);

  if (isLoading) return <Loading />;
  if (isError) {
    return <TenderDetailsError breadcrumbItems={breadcrumbItems} />;
  }

  const tender: TTenderDetails = data!.data;

  return (
    <>
      <Breadcrumb items={breadcrumbItems} />
      <ShowcaseSection
        rootClassName="overflow-clip"
        title={
          <TenderDetailsHeader
            title={tender.title}
            selectedLanguage={selectedLanguage}
            onLanguageChange={handleLanguageChange}
            isTranslating={isTranslating}
            status={tender.status}
          />
        }
        className="!p-0"
      >
        <TenderDetailsContent
          tender={tender}
          tenderNavItems={tenderNavItems}
          activeSectionId={activeSectionId}
          tenderId={details}
          documents={documents}
          documentsLoading={isDocumentsLoading}
          showDocumentsSection={showDocumentsSection}
        />
      </ShowcaseSection>
    </>
  );
};

export default TenderDetails;
