import { AppState } from '@/ui_models/app_state';
import { Icon, IconType } from './Icon';
import { Switch } from './Switch';
import { observer } from 'mobx-react-lite';
import { useRef, useState } from 'preact/hooks';
import {
  Disclosure,
  DisclosureButton,
  DisclosurePanel,
} from '@reach/disclosure';

type Props = {
  appState: AppState;
  closeOnBlur: (event: { relatedTarget: EventTarget | null }) => void;
  setLockCloseOnBlur: (lock: boolean) => void;
};

export const NotesOptions = observer(
  ({ appState, closeOnBlur, setLockCloseOnBlur }: Props) => {
    const [tagsMenuOpen, setTagsMenuOpen] = useState(false);
    const [tagsMenuPosition, setTagsMenuPosition] = useState({
      top: 0,
      right: 0,
    });

    const notes = Object.values(appState.notes.selectedNotes);
    const hidePreviews = !notes.some((note) => !note.hidePreview);
    const locked = !notes.some((note) => !note.locked);
    const archived = !notes.some((note) => !note.archived);
    const trashed = !notes.some((note) => !note.trashed);
    const pinned = !notes.some((note) => !note.pinned);

    const trashButtonRef = useRef<HTMLButtonElement>();
    const tagsButtonRef = useRef<HTMLButtonElement>();

    const iconClass = 'fill-current color-neutral mr-2';
    const buttonClass =
      'flex items-center border-0 focus:inner-ring-info ' +
      'cursor-pointer hover:bg-contrast color-text bg-transparent h-10 px-3 ' +
      'text-left';

    return (
      <>
        <Switch
          onBlur={closeOnBlur}
          className="h-10"
          checked={locked}
          onChange={() => {
            appState.notes.setLockSelectedNotes(!locked);
          }}
        >
          <span className="flex items-center">
            <Icon type={IconType.PencilOff} className={iconClass} />
            Prevent editing
          </span>
        </Switch>
        <Switch
          onBlur={closeOnBlur}
          className="h-10"
          checked={!hidePreviews}
          onChange={() => {
            appState.notes.setHideSelectedNotePreviews(!hidePreviews);
          }}
        >
          <span className="flex items-center">
            <Icon type={IconType.RichText} className={iconClass} />
            Show preview
          </span>
        </Switch>
        <div className="h-1px my-2 bg-secondary-contrast"></div>
        <Disclosure
          open={tagsMenuOpen}
          onChange={() => {
            const buttonRect = tagsButtonRef.current.getBoundingClientRect();
            const { offsetTop, offsetWidth } = tagsButtonRef.current;
            setTagsMenuPosition({
              top: offsetTop,
              right:
                buttonRect.right + 265 > document.body.clientWidth
                  ? offsetWidth
                  : -offsetWidth,
            });
            setTagsMenuOpen(!tagsMenuOpen);
          }}
        >
          <DisclosureButton
            onKeyUp={(event) => {
              if (event.key === 'Escape') {
                setTagsMenuOpen(false);
              }
            }}
            onBlur={closeOnBlur}
            ref={tagsButtonRef}
            className={`${buttonClass} justify-between`}
          >
            <div className="flex items-center">
              <Icon type={IconType.Hashtag} className={iconClass} />
              {'Add tag'}
            </div>
            <Icon
              type={IconType.ChevronRight}
              className="fill-current color-neutral"
            />
          </DisclosureButton>
          <DisclosurePanel
            onKeyUp={(event) => {
              if (event.key === 'Escape') {
                setTagsMenuOpen(false);
                tagsButtonRef.current.focus();
              }
            }}
            style={{
              ...tagsMenuPosition,
            }}
            className="sn-dropdown sn-dropdown-anchor-right flex flex-col py-2 max-w-265"
          >
            {appState.tags.tags.map((tag) => (
              <button
                key={tag.title}
                className={buttonClass}
                onBlur={closeOnBlur}
                onClick={() => {
                  appState.tags.addTagToSelectedNotes(tag);
                }}
              >
                {tag.title}
              </button>
            ))}
          </DisclosurePanel>
        </Disclosure>
        <button
          onBlur={closeOnBlur}
          className={buttonClass}
          onClick={() => {
            appState.notes.setPinSelectedNotes(!pinned);
          }}
        >
          <Icon
            type={pinned ? IconType.Unpin : IconType.Pin}
            className={iconClass}
          />
          {pinned ? 'Unpin notes' : 'Pin notes'}
        </button>
        <button
          onBlur={closeOnBlur}
          className={buttonClass}
          onClick={() => {
            appState.notes.setArchiveSelectedNotes(!archived);
          }}
        >
          <Icon
            type={archived ? IconType.Unarchive : IconType.Archive}
            className={iconClass}
          />
          {archived ? 'Unarchive' : 'Archive'}
        </button>
        <button
          ref={trashButtonRef}
          onBlur={closeOnBlur}
          className={buttonClass}
          onClick={async () => {
            setLockCloseOnBlur(true);
            await appState.notes.setTrashSelectedNotes(
              !trashed,
              trashButtonRef
            );
            setLockCloseOnBlur(false);
          }}
        >
          <Icon type={IconType.Trash} className={iconClass} />
          {trashed ? 'Restore' : 'Move to Trash'}
        </button>
      </>
    );
  }
);
