import { JSXElement, createMemo, createSignal, onCleanup } from 'solid-js';

type SSExpandableProps = {
  title: JSXElement;
  class?: string;
  children?: JSXElement;
  style?: string;
  initiallyExpanded?: boolean;
};

const TRANSITION_MS = 200;

function SSExpandable(props: SSExpandableProps) {
  const [height, setHeight] = createSignal<string | number>(props.initiallyExpanded ? 'auto' : 0);
  const isExpanded = createMemo(() => height() !== 0);
  let contentRef: HTMLDivElement | undefined;
  let timeoutId: number | undefined;

  const toggle = () => {
    if (timeoutId) clearTimeout(timeoutId);
    const targetHeight = contentRef?.scrollHeight ?? 0;

    if (isExpanded()) {
      setHeight(targetHeight);
      timeoutId = window.setTimeout(() => setHeight(0), 1);
      return;
    }

    setHeight(targetHeight);
    timeoutId = window.setTimeout(() => setHeight('auto'), TRANSITION_MS);
  };

  onCleanup(() => {
    if (timeoutId) clearTimeout(timeoutId);
  });

  return (
    <div
      class={`ss_expandable ${props.class ?? ''}`}
      style={props.style}
      data-state={isExpanded() ? 'open' : 'closed'}
    >
      <div
        class="ss_expandable__header"
        role="button"
        tabindex="0"
        aria-expanded={isExpanded()}
        onclick={toggle}
        onkeydown={event => {
          if (event.key === 'Enter' || event.key === ' ') {
            event.preventDefault();
            toggle();
          }
        }}
      >
        <span class="ss_expandable__icon" aria-hidden="true">
          {isExpanded() ? (
            <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-chevron-down"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M6 9l6 6l6 -6" /></svg>
          ) : (
            <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-chevron-right"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M9 6l6 6l-6 6" /></svg>
          )}
        </span>
        <span class="ss_expandable__title">{props.title}</span>
      </div>

      <div
        ref={el => (contentRef = el)}
        class="ss_expandable__content"
        style={{
          height: (typeof height() === 'number' ? `${height()}px` : height()) as any,
          'transition-duration': `${TRANSITION_MS}ms`,
        }}
      >
        <div class='ss_expandable__divider_wrapper'>
          <div class="ss_expandable__divider" />
          {props.children}
        </div>
      </div>
    </div>
  );
}

export { SSExpandable };
