import { useEffect } from '../lib/teact/teact';

import {
  MIN_SCREEN_WIDTH_FOR_STATIC_LEFT_COLUMN,
  MOBILE_SCREEN_LANDSCAPE_MAX_HEIGHT,
  MOBILE_SCREEN_LANDSCAPE_MAX_WIDTH,
  MOBILE_SCREEN_MAX_WIDTH,
} from '../config';
import { IS_IOS } from '../util/browser/windowEnvironment';
import { createCallbackManager } from '../util/callbacks';
import { updateSizes } from '../util/windowSize';
import useForceUpdate from './useForceUpdate';

type MediaQueryCacheKey = 'mobile' | 'tablet' | 'landscape' | 'touch';

const mediaQueryCache = new Map<MediaQueryCacheKey, MediaQueryList>();
const callbacks = createCallbackManager();

let isMobile: boolean;
let isTablet: boolean;
let isLandscape: boolean;
let isTouchScreen: boolean;

export function getIsMobile() {
  return isMobile;
}

export function getIsTablet() {
  return isTablet;
}

export function getIsWebAppsFullscreenSupported() {
  return !getIsMobile();
}

function handleMediaQueryChange() {
  isMobile = mediaQueryCache.get('mobile')?.matches || false;
  isTablet = !isMobile && (mediaQueryCache.get('tablet')?.matches || false);
  isLandscape = mediaQueryCache.get('landscape')?.matches || false;
  isTouchScreen = mediaQueryCache.get('touch')?.matches || false;
  updateSizes();
  callbacks.runCallbacks();
}

function initMediaQueryCache() {
  const mobileQuery = window.matchMedia(`(max-width: ${MOBILE_SCREEN_MAX_WIDTH}px), \
  (max-width: ${MOBILE_SCREEN_LANDSCAPE_MAX_WIDTH}px and max-height: ${MOBILE_SCREEN_LANDSCAPE_MAX_HEIGHT}px)`);
  mediaQueryCache.set('mobile', mobileQuery);
  mobileQuery.addEventListener('change', handleMediaQueryChange);

  const tabletQuery = window.matchMedia(`(max-width: ${MIN_SCREEN_WIDTH_FOR_STATIC_LEFT_COLUMN}px)`);
  mediaQueryCache.set('tablet', tabletQuery);
  tabletQuery.addEventListener('change', handleMediaQueryChange);

  const landscapeQuery = window.matchMedia(
    IS_IOS
      ? '(orientation: landscape)'
      // Source: https://web.archive.org/web/20160509220835/http://blog.abouthalf.com/development/orientation-media-query-challenges-in-android-browsers/
      // Feature is marked as deprecated now, but it is still supported
      // https://developer.mozilla.org/en-US/docs/Web/CSS/@media/device-aspect-ratio#browser_compatibility
      : 'screen and (min-device-aspect-ratio: 1/1) and (orientation: landscape)',
  );
  mediaQueryCache.set('landscape', landscapeQuery);
  landscapeQuery.addEventListener('change', handleMediaQueryChange);

  const isTouchScreenQuery = window.matchMedia('(pointer: coarse)');
  mediaQueryCache.set('touch', isTouchScreenQuery);
  isTouchScreenQuery.addEventListener('change', handleMediaQueryChange);
}

initMediaQueryCache();
handleMediaQueryChange();

export default function useAppLayout() {
  const forceUpdate = useForceUpdate();

  useEffect(() => callbacks.addCallback(forceUpdate), [forceUpdate]);

  return {
    isMobile,
    isTablet,
    isLandscape,
    isDesktop: !isMobile && !isTablet,
    isTouchScreen,
  };
}
