import { useEffect, useRef } from 'react';
import { DSP, AppPage } from '../../types/types';
import AnimatedLogo from '../../assets/icons/AnimatedLogo';
import { PlusIcon } from '../../assets/icons/PlusIcon';
import { CrownIcon } from '../../assets/icons/CrownIcon';
import Led from '../Led/Led';
import { CloseIcon } from '../../assets/icons/CloseIcon';

import './Topbar.css';

function getStep(count: number) {
  if (count <= 4) return 4;
  if (count <= 6) return 6;
  if (count <= 8) return 8;
  return 10;
}

function Tab({
  dsp,
  active,
  dimmed,
  step,
  onSelect,
  onRemove,
  onConnect,
  onDisconnect,
}: {
  dsp: DSP;
  active: boolean;
  dimmed: boolean;
  step: number;
  onSelect: () => void;
  onRemove: () => void;
  onConnect: (dsp: DSP) => void;
  onDisconnect: (dsp: DSP) => void;
}) {
  const handleLedClick = (e: React.MouseEvent) => {
    e.stopPropagation();

    if (dsp.status === 'connected') {
      onDisconnect(dsp);
    } else {
      onConnect(dsp);
    }
  };

  return (
    <button
      type="button"
      className={
        'tab' +
        (active ? ' tab--active' : '') +
        (dimmed ? ' tab--dimmed' : '')
      }
      data-step={step}
      onClick={onSelect}
    >
      <span
        className="tab-led"
        role="button"
        tabIndex={0}
        onClick={handleLedClick}
        onKeyDown={(e) => {
          if (e.key === 'Enter' || e.key === ' ') {
            e.preventDefault();
            e.stopPropagation();

            if (dsp.status === 'connected') {
              onDisconnect(dsp);
            } else {
              onConnect(dsp);
            }
          }
        }}
      >
        <Led status={dsp.status} />
      </span>

      <span className="tab-name" title={dsp.name}>
        {dsp.name}
      </span>

      <span
        className="tab-close"
        role="button"
        tabIndex={0}
        aria-label={`Remove ${dsp.name}`}
        onClick={(e) => {
          e.stopPropagation();
          onRemove();
        }}
        onKeyDown={(e) => {
          if (e.key === 'Enter' || e.key === ' ') {
            e.preventDefault();
            e.stopPropagation();
            onRemove();
          }
        }}
      >
        <CloseIcon />
      </span>
    </button>
  );
}

function TopBar({
  dsps,
  selected,
  page,
  setPage,
  setSelect,
  onSelect,
  onRemove,
  onAddClick,
  onConnect,
  onDisconnect,
}: {
  dsps: DSP[];
  selected: number | null;
  page: AppPage;
  setPage: (page: AppPage) => void;
  setSelect: (select: number | null) => void;
  onSelect: (id: number) => void;
  onRemove: (dsp: DSP) => void;
  onAddClick: () => void;
  onConnect: (dsp: DSP) => void;
  onDisconnect: (dsp: DSP) => void;
}) {
  const hasTabs = dsps.length > 0;
  const tabstripRef = useRef<HTMLDivElement>(null);
  const prevCount = useRef(dsps.length);
  const step = getStep(dsps.length);

  const updateFade = () => {
    const el = tabstripRef.current;
    if (!el) return;
    const atStart = el.scrollLeft <= 1;
    const atEnd = el.scrollLeft + el.clientWidth >= el.scrollWidth - 1;
    el.dataset.fadeStart = String(!atStart);
    el.dataset.fadeEnd = String(!atEnd && el.scrollWidth > el.clientWidth);
  };

  useEffect(() => {
    const el = tabstripRef.current;
    if (!el) return;
    const onWheel = (e: WheelEvent) => {
      if (Math.abs(e.deltaY) > Math.abs(e.deltaX)) {
        el.scrollLeft += e.deltaY;
        e.preventDefault();
      }
    };
    el.addEventListener('wheel', onWheel, { passive: false });
    return () => el.removeEventListener('wheel', onWheel);
  }, []);

  useEffect(() => {
    updateFade();
    const el = tabstripRef.current;
    el?.addEventListener('scroll', updateFade);
    window.addEventListener('resize', updateFade);
    return () => {
      el?.removeEventListener('scroll', updateFade);
      window.removeEventListener('resize', updateFade);
    };
  }, [dsps.length]);

  useEffect(() => {
    if (dsps.length > prevCount.current && tabstripRef.current) {
      tabstripRef.current.scrollTo({
        left: tabstripRef.current.scrollWidth,
        behavior: 'smooth',
      });
    }
    prevCount.current = dsps.length;
  }, [dsps.length]);

  return (
    <header className="topbar">
      <button
        className="logo-slot"
        onClick={() => {
          setSelect(null);
          setPage('home');
        }}
        aria-label="Go to home"
      >
        <AnimatedLogo />
      </button>

      <div className="tabstrip" ref={tabstripRef}>
        {dsps.map((dsp) => (
          <Tab
            key={dsp.id}
            dsp={dsp}
            step={step}
            active={selected === dsp.id && !(page == 'add-dsp')}
            dimmed={page === 'add-dsp'}
            onSelect={() => onSelect(dsp.id)}
            onRemove={() => onRemove(dsp)}
            onConnect={onConnect}
            onDisconnect={onDisconnect}
          />
        ))}
      </div>

      <div className="tabstrip-actions">
        {hasTabs ? (
          <button className="tab-add tab-action" aria-label="Add DSP" onClick={onAddClick}>
            <PlusIcon className="icon-tab-add" />
          </button>
        ) : (
          <button className="tab-add-empty tab-action" onClick={onAddClick}>
            <PlusIcon className="icon-tab-add-empty" />
            <span>Add DSP</span>
          </button>
        )}

        <button
          className="crown-action tab-action"
          title="Credits & Support"
          aria-label="Credits & Support"
          onClick={() => {
            setPage('credits');
            setSelect(null);
          }}
        >
          <CrownIcon className="icon-crown" />
        </button>
      </div>
    </header>
  );
}

export default TopBar;
