// src/components/KeyBusinessSegments/index.tsx
import React, { useEffect, useMemo, useRef, useState, useLayoutEffect } from "react";
import styled, { css } from "styled-components";
import {
  s_Text40_700 as Text40_700,
  s_Text24_700 as Text24_700,
  Text18_400 as Text18_400_dom,
  Text24_700 as Text24_700_dom,
} from "../Typography";
import { useSingleton } from "cms/factory";
import fallbackLogo from "imgs/logo.svg";

/* ===== Types that reflect CMS ===== */
type CmsItem = {
  id: string;
  text: string;
  order: number;
  infoLogo?: { url?: string | null } | null;
  colSpan?: "ONE" | "TWO" | "1" | "2" | 1 | 2 | null;
};

type CmsInfo = {
  id: string;
  title: string;
  order: number;
  colSpan?: "ONE" | "TWO" | "1" | "2" | 1 | 2 | null;
  brandLink?: string | null;
  brandLogo?: { url?: string | null } | null;
  items: CmsItem[];
};

type CmsSegment = {
  id: string;
  key?: string | null;
  name: string;
  order: number;
  logo?: { url?: string | null } | null;
  info: CmsInfo[];
};

type CmsSection = {
  id: string;
  title?: string | null;
  segments: CmsSegment[];
};

/* ===== GQL selection for useSingleton ===== */
const SELECTION = `
  id
  title
  segments(orderBy: { order: asc }) {
    id key name order
    logo { url }
    info(orderBy: { order: asc }) {
      id title order
      brandLink
      brandLogo { url }
      items(orderBy: { order: asc }) {
        id text order colSpan infoLogo { url }
      }
    }
  }
`;

const toSpan = (v: CmsItem["colSpan"]) =>
  v === "TWO" || v === "2" || v === 2 ? 2 : 1;

/* ===== View-model mapping ===== */
function mapSegments(s?: CmsSection | null) {
  const segs = s?.segments ?? [];
  return segs.map((seg) => ({
    id: seg.key || seg.id,
    name: seg.name,
    logoSrc: seg.logo?.url || fallbackLogo,
    info: (seg.info ?? []).map((block) => ({
      id: block.id,
      title: block.title,
      brandLink: block.brandLink ?? undefined,
      brandLogo: block.brandLogo?.url ?? undefined,
      items: (block.items ?? []).map((it) => ({
        id: it.id,
        text: it.text,
        infoLogo: it.infoLogo?.url ?? undefined,
        span: toSpan(it.colSpan),            // ← ТУТ ВАЖНО
      })),
    })),
  }));
}

/* ===== Sizes/FX (как было у тебя) ===== */
const INACTIVE_LOGO_W = 189;
const INACTIVE_LOGO_H = 54;
const ACTIVE_LOGO_W = 248;
const ACTIVE_LOGO_H = 77;

const INACTIVE_LOGO_W_M = 123;
const INACTIVE_LOGO_H_M = 35;
const ACTIVE_LOGO_W_M = 161;
const ACTIVE_LOGO_H_M = 50;

const ACTIVE_BLOCK_W = 317.3333;
const ACTIVE_BLOCK_H = 112;
const ACTIVE_BLOCK_RADIUS = 24.89;

const ACTIVE_BLOCK_W_M = 206;
const ACTIVE_BLOCK_H_M = 73;
const INACTIVE_BLOCK_W_M = 123;
const INACTIVE_BLOCK_H_M = 35;

const CARD_SHADOW = "0px 4px 27.3px 0px #00000014";

/* ===================== styles ===================== */

const Section = styled.section`
  width: 100%;
  max-width: 1220px;
  padding: 64px 0px;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  gap: 0;
  @media (max-width: 768px) {
    padding: 48px 0px;
  }
`;

const HeaderRow = styled.div`
  display: flex;
  justify-content: flex-start;
  align-items: center;
  padding: 0 10px 16px;
`;

const LogosScroller = styled.div<{ $gap: number }>`
  display: flex;
  align-items: center;
  gap: ${({ $gap }) => $gap}px;
  overflow-x: auto;
  padding: 0 15px;
  margin: 0 10px;

  @media (max-width: 1200px) {
    margin: 0;
  }

  height: ${ACTIVE_BLOCK_H + 64}px;
  @media (max-width: 768px) {
    height: ${ACTIVE_LOGO_H_M + 64}px;
  }

  scrollbar-width: none;
  -ms-overflow-style: none;
  &::-webkit-scrollbar {
    display: none;
  }
`;

const HiddenBlock =  styled.div`
  @media (max-width: 768px) {
    display:none;
  }
`

const LogoCard = styled.div<{ $active: boolean }>`
  flex: 0 0 ${({ $active }) => ($active ? ACTIVE_BLOCK_W : INACTIVE_LOGO_W)}px;
  height: ${({ $active }) => ($active ? ACTIVE_BLOCK_H : INACTIVE_LOGO_H)}px;
  border-radius: ${ACTIVE_BLOCK_RADIUS}px;
  background: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: flex-basis 220ms ease, height 220ms ease, box-shadow 220ms ease,
    transform 220ms ease;
  ${({ $active }) => ($active ? css`box-shadow: ${CARD_SHADOW};` : css`box-shadow: none;`)}
  margin: 0 auto;

  @media (max-width: 768px) {
    flex: 0 0
      ${({ $active }) => ($active ? ACTIVE_BLOCK_W_M : INACTIVE_BLOCK_W_M)}px;
    height: ${({ $active }) => ($active ? ACTIVE_BLOCK_H_M : INACTIVE_BLOCK_H_M)}px;
  }
`;

const LogoImg = styled.div<{ $active: boolean }>`
  transition: width 220ms ease, height 220ms ease, opacity 220ms ease;
  width: ${({ $active }) => ($active ? ACTIVE_LOGO_W : INACTIVE_LOGO_W)}px;
  height: ${({ $active }) => ($active ? ACTIVE_LOGO_H : INACTIVE_LOGO_H)}px;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
  box-sizing: border-box;

  @media (max-width: 768px) {
    width: ${({ $active }) => ($active ? ACTIVE_LOGO_W_M : INACTIVE_LOGO_W_M)}px;
    height: ${({ $active }) => ($active ? ACTIVE_LOGO_H_M : INACTIVE_LOGO_H_M)}px;
  }
`;

const InfoGrid = styled.div`
  padding: 0 10px;
  column-count: 2;       /* ← две колонки */
  column-gap: 32px;      /* ← горизонтальный зазор между колонками */
  @media (max-width: 900px) {
    column-count: 1;
  }
`;

/* обёртка для резерва высоты */
const InfoGridSizer = styled.div<{ $minh: number }>`
  position: relative;
  min-height: ${({ $minh }) => ($minh ? `${$minh}px` : "0px")};
`;

// карточка должна быть «неделимой» и вести себя как блочный элемент в колонке
const InfoCard = styled.div`
  display: inline-block;                 /* ← важно для columns */
  width: 100%;
  margin: 0 0 32px;                      /* ← вертикальный зазор между карточками */
  break-inside: avoid;                   /* стандарт */
  -webkit-column-break-inside: avoid;    /* сафари/старые вебкиты */
  -moz-column-break-inside: avoid;

  background: #fff;
  border-radius: 16px;
  box-shadow: ${CARD_SHADOW};
  padding: 24px;
`;

const InfoTitleRow = styled.div`
  display: flex;
  align-items: start;
  justify-content: space-between;
  gap: 12px;
`;

const Bullets = styled.ul`
  margin: 0;
  padding-left: 0;
  list-style: none;
  margin-top: 24px;

  display: grid;
  grid-template-columns: 1fr 1fr;  /* 2 колонки */
  gap: 16px 24px;

  @media (max-width: 900px) {
    grid-template-columns: 1fr;   /* на мобилке одна колонка */
  }
`;

// li с поддержкой span
const BulletItem = styled.li<{ $span: number }>`
  grid-column: span ${({ $span }) => Math.min(2, Math.max(1, $span))};
`;

const CheckDot = styled.div`
  width: 32px;
  height: 32px;
  border-radius: 4px;
  background: #16a34a;
  display: inline-block;
  flex-shrink: 0;
  margin-right: 0px;
  border: 0px;
  background-size: 24px;
  background-repeat: no-repeat;
  background-position: 50%;
`;

const ItemRow = styled.div`
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  a {
    color: inherit;
    text-decoration: none;
  }
`;

const RightBrand = styled.div`
  display: inline-flex;
  align-items: center;
  flex-shrink: 0;
  img {
    width: 32px;
    height: 32px;
    object-fit: contain;
    border-radius: 8px;
    background: #00a76b;
    padding: 4px;
  }
`;

function usePreloadImages(urls: string[]) {
  useEffect(() => {
    if (!urls?.length) return;
    const unique = Array.from(new Set(urls.filter(Boolean)));

    unique.forEach((url) => {
      if (!url) return;

      // Проверяем, есть ли уже preload в <head>
      const exists = document.querySelector<HTMLLinkElement>(
        `link[rel="preload"][as="image"][href="${url}"]`
      );
      if (!exists) {
        const link = document.createElement("link");
        link.rel = "preload";
        link.as = "image";
        link.href = url;
        document.head.appendChild(link);
      }

      // Дополнительно сразу грузим в memory cache
      const img = new Image();
      img.src = url;
    });
  }, [urls]);
}



/* ===================== Component ===================== */

export default function KeyBusinessSegments() {
  const { data, loading, error } = useSingleton<CmsSection>(
    "KeyBusinessSegmentsSection",
    SELECTION
  );

  const segments = useMemo(() => mapSegments(data), [data]);

    // --- предзагрузка иконок ---
  // собираем все картинки для предзагрузки
  const preloadUrls = useMemo(() => {
    if (!segments?.length) return [];
    return segments.flatMap((seg) =>
      seg.info.flatMap((block) => [
        block.brandLogo, // ← бренд
        ...block.items.map((item) => item.infoLogo), // ← иконки
      ])
    ).filter((u): u is string => Boolean(u));
  }, [segments]);

  // предзагрузка всех логотипов
  usePreloadImages(preloadUrls);
  // ---------------------------


  const scrollerRef = useRef<HTMLDivElement>(null);
  const maxScrollRef = useRef(0);

  const N = segments.length;
  const denom = Math.max(1, N - 1);
  const defaultCenterIndex = useMemo(() => Math.floor(N / 2), [N]);

  const [activeIndex, _setActiveIndex] = useState<number>(defaultCenterIndex);
  const [hoverIndex, setHoverIndex] = useState<number | null>(null);
  const [isOverflow, setIsOverflow] = useState(false);
  const [isMobile, setIsMobile] = useState(false);

  const [isLocked, setIsLocked] = useState(false);
  const lockTimer = useRef<number | null>(null);

  // обёртка для смены индекса
  const setActiveIndex = (idx: number) => {
    if (idx === activeIndex) return;
    _setActiveIndex(idx);
    setIsLocked(true);
    if (lockTimer.current) clearTimeout(lockTimer.current);
    lockTimer.current = window.setTimeout(() => {
      setIsLocked(false);
    }, 250); // чуть больше transition
  };


  useEffect(() => {
    const el = scrollerRef.current;
    if (!el) return;
    let raf = 0;
    const onScroll = () => {
      cancelAnimationFrame(raf);
      raf = requestAnimationFrame(() => {
        if (isLocked) return; // 🔒 во время анимации не пересчитываем
        setActiveIndex(indexFromScroll(el.scrollLeft));
      });
    };
    el.addEventListener("scroll", onScroll, { passive: true });
    return () => el.removeEventListener("scroll", onScroll);
  }, [denom, isLocked]);


  /* ===== reserve-height measuring ===== */
  const gridWrapRef = useRef<HTMLDivElement>(null);
  const [gridMinHeight, setGridMinHeight] = useState(0);
  const [sizerWidth, setSizerWidth] = useState(0);

  useLayoutEffect(() => {
    const el = gridWrapRef.current;
    if (!el) return;
    setSizerWidth(el.clientWidth);
    const ro = new ResizeObserver(() => setSizerWidth(el.clientWidth));
    ro.observe(el);
    return () => ro.disconnect();
  }, [gridWrapRef.current]);

  /* recompute scroll size */
  const recomputeMaxScroll = () => {
    const el = scrollerRef.current;
    if (!el) return 0;
    const maxScroll = Math.max(0, el.scrollWidth - el.clientWidth);
    maxScrollRef.current = maxScroll;
    setIsOverflow(maxScroll > 2);
    setIsMobile(window.innerWidth <= 768);
    return maxScroll;
  };

  const indexFromScroll = (left: number) => {
    const maxScroll = maxScrollRef.current;
    if (maxScroll <= 0) return 0;
    const ratio = left / maxScroll;
    const idx = Math.round(ratio * denom);
    return Math.min(denom, Math.max(0, idx));
  };
  const leftFromIndex = (idx: number) => {
    const maxScroll = maxScrollRef.current;
    return maxScroll * (Math.min(denom, Math.max(0, idx)) / denom);
  };

  useEffect(() => {
    const el = scrollerRef.current;
    if (!el) return;

    const init = () => {
      recomputeMaxScroll();
      const startLeft = leftFromIndex(defaultCenterIndex);
      el.scrollLeft = isFinite(startLeft) ? startLeft : 0;
      setActiveIndex(defaultCenterIndex);
      setHoverIndex(null);
    };
    requestAnimationFrame(init);

    const onResize = () => {
      const el2 = scrollerRef.current;
      if (!el2) return;
      recomputeMaxScroll();
      setActiveIndex(indexFromScroll(el2.scrollLeft));
    };
    window.addEventListener("resize", onResize);
    return () => window.removeEventListener("resize", onResize);
  }, [defaultCenterIndex, N]);

  const realActiveIndex = hoverIndex ?? activeIndex;
  const activeSegment = segments[Math.min(Math.max(realActiveIndex, 0), N - 1)];

  return (
    <Section>
      <HeaderRow>
        <Text40_700>{data?.title || "Key business segments"}</Text40_700>
      </HeaderRow>

      {/* LOGO STRIP */}
      <LogosScroller ref={scrollerRef} $gap={12}>
        {segments.map((seg, idx) => {
          const isActive = idx === realActiveIndex;
          return (
            <LogoCard
              key={seg.id}
              $active={isActive}
              onMouseEnter={() => {
                if (!isOverflow && !isMobile) setHoverIndex(idx);
              }}
              onMouseLeave={() => {
                if (!isOverflow && !isMobile) setHoverIndex(null);
              }}
              onClick={() => {
                const el = scrollerRef.current;
                if (el) el.scrollTo({ left: leftFromIndex(idx), behavior: "smooth" });
                setActiveIndex(idx);
                setHoverIndex(null);
              }}
              title={seg.name}
            >
              <LogoImg $active={isActive}>
                <img height="100%" style={{maxHeight: '100%'}} src={seg.logoSrc} alt={seg.name} />
              </LogoImg>
            </LogoCard>
          );
        })}
      </LogosScroller>

      {/* reserve height wrapper */}
      <InfoGridSizer ref={gridWrapRef} $minh={gridMinHeight}>
        {/* INFO GRID (2 cols; cards can span 2 columns) */}
        {activeSegment ? (
          <InfoGrid>
            {activeSegment.info.map((block) => (
              <InfoCard key={block.id}>
                <InfoTitleRow>
                  <Text24_700_dom>{block.title}</Text24_700_dom>
                  {block.brandLogo ? (
                    <a
                      href={block.brandLink || "#"}
                      target="_blank"
                      rel="noreferrer"
                      style={{ display: "inline-flex", alignItems: "center" }}
                    >
                      <img src={block.brandLogo} alt="brand" style={{ height: 32 }} />
                    </a>
                  ) : null}
                </InfoTitleRow>
                {block.items?.length > 0  && (
                  <Bullets>
                    {block.items.map((item) => (
                      <BulletItem key={item.id} $span={item.span}>
                        <ItemRow>
                          <img
                            src={item.infoLogo}
                            alt=""
                            style={{
                              width: 32,
                              height: 32,
                              borderRadius: 4,
                              objectFit: "contain",
                              background: "#16a34a",
                              padding: 4,
                            }}
                          />
                          <Text18_400_dom
                            style={{ textAlign: "left", marginRight: item.infoLogo ? 10 : 0 }}
                          >
                            {item.text}
                          </Text18_400_dom>
                        </ItemRow>
                      </BulletItem>
                    ))}
                  </Bullets>
                )}
              </InfoCard>
            ))}
          </InfoGrid>
        ) : null}
      </InfoGridSizer>

      {/* hidden measurer: offscreen render of ALL segments to get max height */}
      <HiddenSizer
        width={sizerWidth}
        segments={segments}
        onResult={setGridMinHeight}
      />

      {/* ошибки / загрузка */}
      {error ? (
        <div style={{ color: "#ffb4b4", fontSize: 12 }}>Failed to load</div>
      ) : null}
    </Section>
  );
}

/* ===== HiddenSizer ===== */
function HiddenSizer({
  width,
  segments,
  onResult,
}: {
  width: number;
  segments: ReturnType<typeof mapSegments>;
  onResult: (h: number) => void;
}) {
  const refs = useRef<Array<HTMLDivElement | null>>([]);

  useLayoutEffect(() => {
    const heights = refs.current.map((r) => (r ? r.offsetHeight : 0));
    const max = heights.length ? Math.max(...heights) : 0;
    onResult(max);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [width, segments]);

  if (!width || !segments.length) return null;

  return (
    <HiddenBlock
      aria-hidden
      style={{
        position: "absolute",
        left: -99999,
        top: 0,
        width,
        visibility: "hidden",
        pointerEvents: "none",
        overflow: "hidden",
      }}
    >
      {segments.map((seg, i) => (
        <InfoGrid key={`sizer-${seg.id}`} ref={(el) => { refs.current[i] = el; }}>
          {seg.info.map((block) => (
            <InfoCard key={block.id}>
              <InfoTitleRow>
                <Text24_700_dom>{block.title}</Text24_700_dom>
                {block.brandLogo ? (
                  <img src={block.brandLogo} alt="" style={{ height: 32 }} />
                ) : null}
              </InfoTitleRow>
              {block.items?.length > 0  && (
                <Bullets>
                  {block.items.map((item) => (
                    <BulletItem key={item.id} $span={item.span}>
                      <ItemRow>
                        <CheckDot
                          style={{
                            backgroundImage: item.infoLogo ? `url(${item.infoLogo})` : undefined,
                          }}
                        />
                        <Text18_400_dom
                          style={{ textAlign: "left", marginRight: item.infoLogo ? 10 : 0 }}
                        >
                          {item.text}
                        </Text18_400_dom>
                      </ItemRow>
                    </BulletItem>
                  ))}
                </Bullets>
              )}
            </InfoCard>
          ))}
        </InfoGrid>
      ))}
    </HiddenBlock>
  );
}
