﻿'use client';

import { useCallback, useEffect, useId, useMemo, useRef, useState, useTransition } from 'react';

import { useTranslations } from 'next-intl';

import { ChevronDown, Loader2 } from 'lucide-react';
import { createPortal } from 'react-dom';
import { Virtuoso, VirtuosoHandle } from 'react-virtuoso';

import type { HomepageCollectionTextFields } from '@/services/homeCollections';

import CreatorAvatar from '@/components/creators/CreatorAvatar';

import { useRouter } from '@/i18n/navigation';

import SectionHeader from '@/components/home/components/SectionHeader';

export interface HomepageParallelPathsTeaserCreatorOption {
  id: string;
  name: string;
  profession: string | null;
  avatarKey: string | null;
}

interface HomepageParallelPathsTeaserClientProps {
  creatorOptions: HomepageParallelPathsTeaserCreatorOption[];
  textFields?: HomepageCollectionTextFields | null;
}

const CREATION_CATEGORY_KEY = 'alkotas';

const normalize = (value: string) =>
  value
    .normalize('NFD')
    .replace(/[\u0300-\u036f]/g, '')
    .toLowerCase()
    .trim();

function CreatorVirtualizedSelect({
  value,
  options,
  disabledCreatorId,
  placeholder,
  searchPlaceholder,
  ariaLabel,
  onChange,
}: {
  value: string | null;
  options: HomepageParallelPathsTeaserCreatorOption[];
  disabledCreatorId: string | null;
  placeholder: string;
  searchPlaceholder: string;
  ariaLabel: string;
  onChange: (id: string) => void;
}) {
  const selectedCreator = useMemo(
    () => (value ? options.find((item) => item.id === value) || null : null),
    [options, value]
  );

  const [open, setOpen] = useState(false);
  const [query, setQuery] = useState('');
  const normalizedQuery = useMemo(() => normalize(query), [query]);
  const filteredOptions = useMemo(() => {
    if (!normalizedQuery) return options;
    return options.filter((item) => {
      const name = normalize(item.name);
      const profession = normalize(item.profession || '');
      return name.includes(normalizedQuery) || profession.includes(normalizedQuery);
    });
  }, [normalizedQuery, options]);
  const selectedIndex = useMemo(
    () => filteredOptions.findIndex((item) => item.id === value),
    [filteredOptions, value]
  );

  const wrapperRef = useRef<HTMLDivElement | null>(null);
  const dropdownRef = useRef<HTMLDivElement | null>(null);
  const virtuosoRef = useRef<VirtuosoHandle | null>(null);
  const selectId = useId();
  const [dropdownLayout, setDropdownLayout] = useState<{
    top: number;
    left: number;
    width: number;
    height: number;
  } | null>(null);

  const updateDropdownLayout = useCallback(() => {
    const wrapper = wrapperRef.current;
    if (!wrapper) return;

    const rect = wrapper.getBoundingClientRect();
    const margin = 8;
    const viewportBottomSpace = window.innerHeight - rect.bottom - margin;

    setDropdownLayout({
      top: rect.bottom + margin,
      left: rect.left,
      width: rect.width,
      height: Math.max(230, Math.min(460, viewportBottomSpace)),
    });
  }, []);

  useEffect(() => {
    if (!open) return;

    updateDropdownLayout();
    window.addEventListener('resize', updateDropdownLayout);
    window.addEventListener('scroll', updateDropdownLayout, true);

    return () => {
      window.removeEventListener('resize', updateDropdownLayout);
      window.removeEventListener('scroll', updateDropdownLayout, true);
    };
  }, [open, updateDropdownLayout]);

  useEffect(() => {
    if (!open || selectedIndex < 0 || !virtuosoRef.current) return;

    virtuosoRef.current.scrollToIndex({
      index: selectedIndex,
      align: 'center',
      behavior: 'auto',
    });
  }, [open, selectedIndex]);

  useEffect(() => {
    const handlePointerDown = (event: PointerEvent) => {
      const target = event.target as Node;
      const insideWrapper = wrapperRef.current?.contains(target);
      const insideDropdown = dropdownRef.current?.contains(target);
      if (!insideWrapper && !insideDropdown) {
        setOpen(false);
      }
    };

    document.addEventListener('pointerdown', handlePointerDown);
    return () => document.removeEventListener('pointerdown', handlePointerDown);
  }, []);

  return (
    <div ref={wrapperRef} className="relative w-full">
      <label htmlFor={`${selectId}-trigger`} className="sr-only">
        {ariaLabel}
      </label>
      <button
        id={`${selectId}-trigger`}
        type="button"
        onClick={() => {
          setOpen((prev) => {
            const next = !prev;
            if (next) setQuery('');
            return next;
          });
        }}
        onKeyDown={(event) => {
          if (event.key === 'Escape') setOpen(false);
        }}
        aria-label={ariaLabel}
        aria-haspopup="listbox"
        aria-expanded={open}
        aria-controls={`${selectId}-listbox`}
        className="grid h-14 w-full min-w-0 grid-cols-[1rem_minmax(0,1fr)_1rem] items-center border border-[#151720]/18 bg-white px-3 text-[#151720] outline-none transition hover:bg-[#fcfcfd] focus:ring-1 focus:ring-[#151720]/25"
      >
        <span aria-hidden="true" className="h-4 w-4" />
        {selectedCreator ? (
          <span className="min-w-0 text-center leading-tight">
            <span className="block truncate text-sm font-semibold">{selectedCreator.name}</span>
            <span className="block truncate text-[11px] font-medium text-[#151720]/62">
              {selectedCreator.profession || '\u00A0'}
            </span>
          </span>
        ) : (
          <span className="min-w-0 text-center leading-tight">
            <span className="block truncate text-sm font-semibold text-[#151720]/55">
              {placeholder}
            </span>
            <span className="block text-[11px] text-transparent">.</span>
          </span>
        )}
        <ChevronDown
          size={16}
          className={
            'h-4 w-4 justify-self-end text-[#151720]/55 transition-transform ' +
            (open ? 'rotate-180' : '')
          }
        />
      </button>

      {open && dropdownLayout
        ? createPortal(
            <div
              ref={dropdownRef}
              id={`${selectId}-listbox`}
              role="listbox"
              style={{
                position: 'fixed',
                top: dropdownLayout.top,
                left: dropdownLayout.left,
                width: dropdownLayout.width,
              }}
              className="z-[4000] overflow-hidden bg-white shadow-[0_14px_30px_-20px_rgba(15,23,42,0.75)]"
            >
              <div className="border-b border-[#151720]/8 p-2">
                <input
                  type="text"
                  value={query}
                  onChange={(event) => setQuery(event.target.value)}
                  placeholder={searchPlaceholder}
                  className="h-9 w-full border border-[#151720]/15 bg-white px-2.5 text-sm text-[#151720] outline-none placeholder:text-[#151720]/45 focus:ring-1 focus:ring-[#151720]/20"
                />
              </div>

              {filteredOptions.length === 0 ? (
                <div className="px-3 py-3 text-sm text-[#151720]/60">{placeholder}</div>
              ) : (
                <Virtuoso
                  ref={virtuosoRef}
                  style={{ height: Math.max(140, dropdownLayout.height - 52) }}
                  totalCount={filteredOptions.length}
                  computeItemKey={(index) => filteredOptions[index]?.id || String(index)}
                  itemContent={(index) => {
                    const item = filteredOptions[index];
                    const disabled = disabledCreatorId === item.id;
                    const selected = value === item.id;

                    return (
                      <button
                        type="button"
                        role="option"
                        aria-selected={selected}
                        aria-disabled={disabled}
                        disabled={disabled}
                        onMouseDown={(event) => event.preventDefault()}
                        onClick={() => {
                          if (disabled) return;
                          onChange(item.id);
                          setOpen(false);
                        }}
                        className={
                          'grid w-full grid-cols-[2.5rem_minmax(0,1fr)] items-center gap-2 overflow-hidden px-3 py-2.5 text-left transition ' +
                          (disabled
                            ? 'cursor-not-allowed opacity-40'
                            : selected
                              ? 'bg-[#f6f6f7]'
                              : 'hover:bg-[#f8f8f9]')
                        }
                      >
                        <CreatorAvatar
                          imageKey={item.avatarKey}
                          name={item.name}
                          width={84}
                          height={84}
                          wrapperClassName="h-10 w-10 shrink-0 rounded-full"
                          imageClassName="rounded-full"
                        />
                        <span className="min-w-0 overflow-hidden leading-tight">
                          <span className="block w-full truncate text-sm font-semibold text-[#151720]">
                            {item.name}
                          </span>
                          {item.profession ? (
                            <span className="block w-full truncate text-[11px] font-medium text-[#151720]/55">
                              {item.profession}
                            </span>
                          ) : null}
                        </span>
                      </button>
                    );
                  }}
                />
              )}
            </div>,
            document.body
          )
        : null}
    </div>
  );
}

function CreatorIdentityPanel({
  creator,
  selectAriaLabel,
  options,
  selectedId,
  disabledCreatorId,
  placeholder,
  searchPlaceholder,
  onSelect,
}: {
  creator: HomepageParallelPathsTeaserCreatorOption | null;
  selectAriaLabel: string;
  options: HomepageParallelPathsTeaserCreatorOption[];
  selectedId: string | null;
  disabledCreatorId: string | null;
  placeholder: string;
  searchPlaceholder: string;
  onSelect: (id: string) => void;
}) {
  return (
    <article className="w-full max-w-[340px]">
      <CreatorAvatar
        imageKey={creator?.avatarKey}
        name={creator?.name || placeholder}
        width={176}
        height={176}
        wrapperClassName="mx-auto h-32 w-32 shrink-0 rounded-full bg-white sm:h-36 sm:w-36 xl:h-44 xl:w-44"
        imageClassName="rounded-full"
      />
      <div className="mt-4 space-y-2 text-center">
        <CreatorVirtualizedSelect
          value={selectedId}
          options={options}
          disabledCreatorId={disabledCreatorId}
          placeholder={placeholder}
          searchPlaceholder={searchPlaceholder}
          ariaLabel={selectAriaLabel}
          onChange={onSelect}
        />
      </div>
    </article>
  );
}

const HomepageParallelPathsTeaserClient = ({
  creatorOptions,
  textFields,
}: HomepageParallelPathsTeaserClientProps) => {
  const t = useTranslations('home.parallelPathsTeaser');
  const tParallelParams = useTranslations('parallelPathsPage.urlParams');
  const tCommon = useTranslations('common');
  const router = useRouter();
  const [isNavigating, startTransition] = useTransition();
  const [leftCreatorId, setLeftCreatorId] = useState<string | null>(null);
  const [rightCreatorId, setRightCreatorId] = useState<string | null>(null);
  const hasAutoRandomizedRef = useRef(false);

  const creatorsById = useMemo(() => {
    const map = new Map<string, HomepageParallelPathsTeaserCreatorOption>();
    creatorOptions.forEach((item) => map.set(item.id, item));
    return map;
  }, [creatorOptions]);

  const leftCreator = leftCreatorId ? creatorsById.get(leftCreatorId) || null : null;
  const rightCreator = rightCreatorId ? creatorsById.get(rightCreatorId) || null : null;

  const hasDuplicateSelection =
    Boolean(leftCreatorId) && Boolean(rightCreatorId) && leftCreatorId === rightCreatorId;
  const canNavigate =
    Boolean(leftCreatorId) && Boolean(rightCreatorId) && !hasDuplicateSelection && !isNavigating;

  const pickRandomPair = useCallback((): [string | null, string | null] => {
    if (creatorOptions.length < 2) {
      return [creatorOptions[0]?.id ?? null, null];
    }

    const firstIndex = Math.floor(Math.random() * creatorOptions.length);
    let secondIndex = Math.floor(Math.random() * creatorOptions.length);

    while (secondIndex === firstIndex) {
      secondIndex = Math.floor(Math.random() * creatorOptions.length);
    }

    return [creatorOptions[firstIndex]?.id ?? null, creatorOptions[secondIndex]?.id ?? null];
  }, [creatorOptions]);

  useEffect(() => {
    if (hasAutoRandomizedRef.current) return;
    hasAutoRandomizedRef.current = true;

    if (!creatorOptions.length) {
      setLeftCreatorId(null);
      setRightCreatorId(null);
      return;
    }

    const [nextLeft, nextRight] = pickRandomPair();
    setLeftCreatorId(nextLeft);
    setRightCreatorId(nextRight);
  }, [creatorOptions, pickRandomPair]);

  const navigateToParallelPaths = () => {
    if (!leftCreatorId || !rightCreatorId || hasDuplicateSelection) return;

    const leftParam = tParallelParams('left');
    const rightParam = tParallelParams('right');
    const categoryParam = tParallelParams('category');

    startTransition(() => {
      router.push({
        pathname: '/parhuzamos-eletutak',
        query: {
          [leftParam]: leftCreatorId,
          [rightParam]: rightCreatorId,
          [categoryParam]: CREATION_CATEGORY_KEY,
        },
      });
    });
  };

  return (
    <section className="relative w-full overflow-hidden bg-white px-site py-14 text-[#151720] sm:py-16 lg:py-20">
      <div className="relative mx-auto max-w-boxed space-y-8">
        <SectionHeader
          eyebrow={textFields?.blockLabel || ''}
          eyebrowUrl="/parhuzamos-eletutak"
          title={textFields?.blockTitle || ''}
          description={textFields?.blockSubtitle || ''}
          maxWidth
        />

        <div className="py-4 sm:py-6">
          <div className="mx-auto grid max-w-5xl gap-8 md:grid-cols-2 md:gap-10">
            <div className="flex justify-center md:justify-end">
              <CreatorIdentityPanel
                creator={leftCreator}
                selectAriaLabel={t('selector.leftLabel')}
                options={creatorOptions}
                selectedId={leftCreatorId}
                disabledCreatorId={rightCreatorId}
                placeholder={t('selector.placeholder')}
                searchPlaceholder={tCommon('searchPlaceholder')}
                onSelect={setLeftCreatorId}
              />
            </div>

            <div className="flex justify-center md:justify-start">
              <CreatorIdentityPanel
                creator={rightCreator}
                selectAriaLabel={t('selector.rightLabel')}
                options={creatorOptions}
                selectedId={rightCreatorId}
                disabledCreatorId={leftCreatorId}
                placeholder={t('selector.placeholder')}
                searchPlaceholder={tCommon('searchPlaceholder')}
                onSelect={setRightCreatorId}
              />
            </div>
          </div>

          <div className="mt-8 flex justify-center">
            <button
              type="button"
              onClick={navigateToParallelPaths}
              disabled={!canNavigate}
              className="inline-flex h-11 items-center justify-center gap-2 bg-[#151720] px-7 text-sm font-semibold uppercase tracking-[0.14em] text-white transition hover:bg-[#0d1020] disabled:cursor-not-allowed disabled:bg-[#151720]/35"
            >
              {isNavigating ? <Loader2 className="h-4 w-4 animate-spin" /> : null}
              <span>{isNavigating ? t('states.loading') : t('cta')}</span>
            </button>
          </div>
        </div>
      </div>
    </section>
  );
};

export default HomepageParallelPathsTeaserClient;
