import 'dayjs/locale/ru';

import {
  useEffect,
  useState,
} from 'react';

import dayjs from 'dayjs';
import { observer } from 'mobx-react';

import { rpcClient } from './api/request';
import AlertRoot, { alertRootRef } from './components/AlertRoot';
import FastAnswerPopupRoot, {
  fastAnswerPopupRootRef,
} from './components/FastAnswerPopupRoot';
import RecordingSheetRoot, {
  recordingSheetRef,
} from './components/RecordingSheetRoot';
import ToastRoot, {
  toast,
  toastRootRef,
} from './components/ToastRoot';
import {
  getDomain,
  getEndpoint,
  IS_DEV,
} from './config';
import {
  parsePresentationIdFromSearch,
} from './presentation/parsePresentationStyle';
import { PresentationProvider } from './presentation/PresentationContext';
import type { PresentationId } from './presentation/types';
import {
  RouterRoot,
  routerRootRef,
} from './router/router';
import store from './stores/store';
import {
  ColorEnumBGOY,
  setColorTheme,
} from './utils/themeColor';

dayjs.locale('ru');

if (!IS_DEV) {
  console.log = () => { };
  console.error = () => { };
  console.warn = () => { };
  console.info = () => { };
  console.debug = () => { };
  console.trace = () => { };
  console.dir = () => { };
  console.dirxml = () => { };
  console.group = () => { };
}

rpcClient.setUseEncrypt(!IS_DEV);
rpcClient.setDomains([getDomain()]);
rpcClient.setEndpoint(getEndpoint());

rpcClient.setToast((message) => {
  toast(message);
});

const MainApp = () => {
  const [presentationId, setPresentationId] = useState<PresentationId>(() =>
    typeof window !== 'undefined'
      ? parsePresentationIdFromSearch(window.location.search)
      : 'telegram'
  );

  useEffect(() => {
    const onResize = () => store.setViewportWidth(window.innerWidth);
    onResize();
    window.addEventListener('resize', onResize);

    // Block iOS Safari / WebView pinch-to-zoom & double-tap-zoom
    const blockGesture = (e: Event) => e.preventDefault();
    document.addEventListener('gesturestart', blockGesture);
    document.addEventListener('gesturechange', blockGesture);
    document.addEventListener('gestureend', blockGesture);

    let lastTouchEnd = 0;
    const blockDoubleTap = (e: TouchEvent) => {
      const now = Date.now();
      if (now - lastTouchEnd <= 350) e.preventDefault();
      lastTouchEnd = now;
    };
    document.addEventListener('touchend', blockDoubleTap, { passive: false });

    const blockWheelZoom = (e: WheelEvent) => {
      if (e.ctrlKey) e.preventDefault();
    };
    window.addEventListener('wheel', blockWheelZoom, { passive: false });

    const blockKeyZoom = (e: KeyboardEvent) => {
      if (
        (e.ctrlKey || e.metaKey) &&
        ['+', '=', '-', '_', '0'].includes(e.key)
      ) {
        e.preventDefault();
      }
    };
    window.addEventListener('keydown', blockKeyZoom);

    const searchParams = new URLSearchParams(window.location.search);

    const cap = searchParams.get('cap');
    store.setCap(!!cap);

    const dark = searchParams.get('dark');
    if (dark) {
      document.body.classList.add('dark');
    } else {
      document.body.classList.remove('dark');
    }

    const theme = searchParams.get('theme');
    if (theme) {
      setColorTheme(theme as ColorEnumBGOY);
    }

    setPresentationId(parsePresentationIdFromSearch(window.location.search));

    return () => {
      window.removeEventListener('resize', onResize);
      document.removeEventListener('gesturestart', blockGesture);
      document.removeEventListener('gesturechange', blockGesture);
      document.removeEventListener('gestureend', blockGesture);
      document.removeEventListener('touchend', blockDoubleTap);
      window.removeEventListener('wheel', blockWheelZoom);
      window.removeEventListener('keydown', blockKeyZoom);
    };
  }, []);

  useEffect(() => {
    document.documentElement.setAttribute('data-presentation', presentationId);
    return () => {
      document.documentElement.removeAttribute('data-presentation');
    };
  }, [presentationId]);

  return (
    <div
      data-presentation={presentationId}
      className="fixed inset-0 flex flex-col overflow-hidden bg-[var(--tg-bg)] text-[var(--tg-text-primary)]"
      style={{
        paddingTop: 'env(safe-area-inset-top)',
        paddingBottom: 'env(safe-area-inset-bottom)',
      }}
    >
      <PresentationProvider id={presentationId}>
        <RouterRoot ref={routerRootRef} />
      </PresentationProvider>
      <FastAnswerPopupRoot ref={fastAnswerPopupRootRef} />
      <ToastRoot ref={toastRootRef} />
      <RecordingSheetRoot ref={recordingSheetRef} />
      <AlertRoot ref={alertRootRef} />
    </div>
  );
};

export default observer(MainApp);
