import React, { useEffect, useLayoutEffect, useState } from 'react';
import { Col, Row, Card, CardBody, Button, CardHeader, Nav, NavItem, NavLink, TabContent, TabPane } from 'reactstrap';
import { useTranslation } from 'react-i18next';
import { useResponsive } from '@farfetch/react-context-responsive';
import JKLobbyUserList from '../sessions/JKLobbyUserList';
import JKLobbyUserSwiper from '../sessions/JKLobbyUserSwiper';
import JKLobbyChat from '../sessions/JKLobbyChat';
import { useDispatch, useSelector } from 'react-redux';
import { fetchOnlineMusicians } from '../../store/features/onlineMusiciansSlice';
import { fetchUserLatencies } from '../../store/features/latencySlice';
import { useAuth } from '../../context/UserAuth';
import { sessionPrivacyMap } from '../../config';
import jkCustomUrlScheme from '../../helpers/jkCustomUrlScheme';
import useNativeAppCheck from '../../hooks/useNativeAppCheck';
import { useNativeApp } from '../../context/NativeAppContext';
import JKModalDialog from '../common/JKModalDialog';
import JKTooltip from '../common/JKTooltip';
import { updateUser } from '../../helpers/rest';
import { postUserAppInteraction } from '../../helpers/rest';
import { useVisbilityState } from '../../hooks/useVisibilityState';
import { useHistory } from 'react-router-dom'

function JKMusicSessionsLobby() {
  const INTERACTION_CLIENT = 'browser';
  const INTERACTION_SCREEN = 'session:lobby';
  const INTERACTION_PAGE_ENTER = 'page:enter';
  const INTERACTION_PAGE_EXIT = 'page:exit';

  const { t } = useTranslation('sessions');
  const { greaterThan } = useResponsive();
  const dispatch = useDispatch();
  const { currentUser } = useAuth();
  const isNativeAppAvailable = useNativeAppCheck();
  const { nativeAppUnavailable, setNativeAppUnavailable } = useNativeApp();
  const history = useHistory();

  const onlineMusicians = useSelector(state => state.onlineMusician.musicians);
  const loadingStatus = useSelector(state => state.onlineMusician.status);

  const [selectedUsers, setSelectedUsers] = useState([]);
  const [submitted, setSubmitted] = useState(false);
  const [activeTab, setActiveTab] = useState('1');
  const [showNotificationsModal, setShowNotificationsModal] = useState(false);

  const NOTIFICATION_MODAL_INTERVAL = 1000 * 10 //10 seconds
  const MUSICIANS_FETCH_INTERVAL = 1000 * 20 //20 seconds
  const LIVENESS_UPDATE_INTERVAL = 1000 * 60 * 1 //1 minute

  const documentVisibility = useVisbilityState();

  useEffect(() => {
    dispatch(fetchOnlineMusicians());
    //check if browser notifications are enabled
    try {
      const notificationsEnabled = localStorage.getItem('showLobbyChatNotifications');
      const dontAskAgain = localStorage.getItem('dontAskLobbyChatNotificationPermission');
      if (notificationsEnabled === 'true' || dontAskAgain === 'true') {
        return;
      } else {
        setTimeout(() => {
          setShowNotificationsModal(true);
        }, NOTIFICATION_MODAL_INTERVAL);
      }
    } catch (error) {
      console.log('Error reading localStorage', error);
    }
  }, []);

  //periodically fetch online musicians
  useEffect(() => {
    const interval = setInterval(() => {
      dispatch(fetchOnlineMusicians());
    }, MUSICIANS_FETCH_INTERVAL);
    return () => clearInterval(interval);
  }, []);

  useEffect(() => {
    if (loadingStatus === 'succeeded' && onlineMusicians.length > 0) {
      const otherUserIds = onlineMusicians.map(p => p.id);
      const options = { currentUserId: currentUser.id, otherUserIds };
      dispatch(fetchUserLatencies(options));
    }
  }, [loadingStatus]);

  //update user liveness when user switches tabs
  useEffect(() => {
    if(currentUser){
      postInteraction(documentVisibility);
    }
  }, [documentVisibility]);

  //update user liveness when user leaves the page
  useEffect(() => {
    const unlisten = history.listen(() => {
      console.log('User is leaving the page');
      // Do something before the user leaves the page
      postInteraction('hidden');
    });

    return () => {
      console.log('Component is unmounting');
      unlisten();
      // Do something before the component unmounts
    };
  }, [history]);

  //periodically update user liveness
  useEffect(() => {
    const interval = setInterval(() => {
      if(documentVisibility === 'visible'){
        postInteraction('visible');
      }
    }, LIVENESS_UPDATE_INTERVAL);
    return () => clearInterval(interval);
  }, [])
  

  const postInteraction = visibilityState => {
   
    const options = {
      client: INTERACTION_CLIENT,
      screen: INTERACTION_SCREEN,
    };
    if (visibilityState === 'visible') {
      options.act = INTERACTION_PAGE_ENTER;
    } else {
      options.act = INTERACTION_PAGE_EXIT;
    }

    postUserAppInteraction(currentUser.id, options)
      .then(response => {
        console.log('User app interactions updated', response);
      })
      .catch(error => {
        console.log('Error updating user app interactions', error);
      });
  };

  const handleClick = async () => {
    const payload = {
      privacy: sessionPrivacyMap.public,
      description: t('list.descriptions.public_open_session', { ns: 'sessions' }),
      inviteeIds: selectedUsers
    };
    try {
      //throw new Error('test');
      await isNativeAppAvailable();
      //window.open jamkazam app url using custom URL scheme
      //an example URL would be: jamkazam://url=https://www.jamkazam.com/client#/createSession/privacy~2|description~hello|inviteeIds~1,2,3,4
      const q = `privacy~${payload.privacy}|description~${payload.description}|inviteeIds~${payload.inviteeIds}`;
      const urlScheme = jkCustomUrlScheme('createSession', q);
      setSubmitted(true);
      window.open(urlScheme);
      //history.push('/sessions');
    } catch (error) {
      toggleAppUnavilableModel();
    } finally {
      setSubmitted(false);
    }
    return false;
  };

  const toggleAppUnavilableModel = () => {
    setNativeAppUnavailable(prev => !prev);
    if (!nativeAppUnavailable) {
      setSubmitted(false);
    }
  };

  const toggleShowNotificationsModel = () => {
    setShowNotificationsModal(prev => !prev);
  };

  const grantShowNotificationsPermission = () => {
    setShowNotificationsModal(false);
    
    try {
      if (!window.Notification) {
        console.log('Your web browser does not support notifications.');
        alert(t('lobby.chat_notifications.browser_not_supported', { ns: 'sessions' }));
      } else {
        // check if permission is already granted
        if (Notification.permission === 'granted') {
          // show notification here
        } else {
          // request permission from user
          Notification.requestPermission()
            .then(function(p) {
              if (p === 'granted') {
                updateUser(currentUser.id, { accept_desktop_notifications: true }).then(() => {
                  console.log('User granted permission for desktop notifications');
                  new Notification(t('lobby.chat_notifications.title'), {
                    body: 'Notifications will appear here.',
                  });
                  localStorage.setItem('showLobbyChatNotifications', true);
                });
              } else {
                console.log('User blocked notifications.');
              }
            })
            .catch(function(err) {
              console.error(err);
            });
        }
      }
    } catch (error) {}
  };

  const handleDontAsk = e => {
    const checked = e.target.checked;
    if (!checked) {
      return;
    }
    try {
      localStorage.setItem('dontAskLobbyChatNotificationPermission', true);
    } catch (error) {}
  };

  return (
    <>
      <Card>
        <CardHeader className="card-header bg-light mb-2">
          <div className="d-flex justify-content-between">
            <div className="d-flex">
              <h5 className="mb-0 mr-1">{t('lobby.page_title', { ns: 'sessions' })}</h5>
              <JKTooltip
                placement="top"
                title={t('lobby.page_title_tooltip')}
              />
            </div>
            {greaterThan.sm && (
              <div className="align-self-end">
                <Button
                  color="primary"
                  className="ml-2"
                  onClick={handleClick}
                  disabled={submitted || selectedUsers.length === 0}
                >
                 {t('lobby.create_session_button', { ns: 'sessions' })} 
                </Button>
              </div>
            )}
          </div>
        </CardHeader>
        <CardBody className="pt-0">
          {greaterThan.sm ? (
            <Row className="justify-content-between">
              <Col>
                <div className="table-responsive-xl px-2">
                  <JKLobbyUserList
                    onlineMusicians={onlineMusicians}
                    setSelectedUsers={setSelectedUsers}
                  />
                </div>
              </Col>
              <Col>
                <JKLobbyChat />
              </Col>
            </Row>
          ) : (
            <Row className="swiper-container d-block d-md-none" data-testid="sessionsSwiper">
              <Nav tabs>
                <NavItem>
                  <NavLink style={{ cursor: 'pointer'}} className={ activeTab === '1' ? 'active' : null } onClick={() => setActiveTab('1')}>
                  {t('lobby.users.title', { ns: 'sessions' })} 
                  </NavLink>
                </NavItem>
                <NavItem>
                  <NavLink style={{ cursor: 'pointer'}} className={ activeTab === '2' ? 'active' : null } onClick={() => setActiveTab('2')}>
                  {t('lobby.chat.title', { ns: 'sessions' })} 
                  </NavLink>
                </NavItem>
              </Nav>
              <TabContent activeTab={activeTab}>
                <TabPane tabId="1">
                  <Row>
                    <Col sm="12">
                      <JKLobbyUserSwiper
                        loadingStatus={loadingStatus}
                        onlineMusicians={onlineMusicians}
                        setSelectedUsers={setSelectedUsers}
                      />
                    </Col>
                  </Row>
                </TabPane>
                <TabPane tabId="2">
                  <Row>
                    <Col sm="12">
                      <JKLobbyChat />
                    </Col>
                  </Row>
                </TabPane>
              </TabContent>
            </Row>
          )}
        </CardBody>
      </Card>
      <JKModalDialog
        show={nativeAppUnavailable}
        onToggle={toggleAppUnavilableModel}
        title={t('modals.native_app_unavailable.title', { ns: 'common' })}
      >
        <p>{t('modals.native_app_unavailable.body', { ns: 'common' })}</p>
        <div className="d-flex flex-row">
          <a
            href="https://www.jamkazam.com/downloads"
            onClick={() => toggleAppUnavilableModel()}
            target="_blank"
            className="btn btn-primary mr-2"
          >
            {t('modals.native_app_unavailable.download_button', { ns: 'common' })}
          </a>
          <a
            href="https://www.jamkazam.com/help_desk"
            onClick={() => toggleAppUnavilableModel()}
            target="_blank"
            className="btn btn-light"
          >
            {t('modals.native_app_unavailable.help_button', { ns: 'common' })}
          </a>
        </div>
      </JKModalDialog>

      <JKModalDialog
        show={showNotificationsModal}
        onToggle={toggleShowNotificationsModel}
        title={t('lobby.chat_notifications.title', { ns: 'sessions' })}
        showFooter={false}
      >
        <p>{t('lobby.chat_notifications.body', { ns: 'sessions' })}</p>
        <div className="">
          <div>
            <label htmlFor="">
              <input type="checkbox" className="mr-2" onChange={handleDontAsk} />
              {t('lobby.chat_notifications.dont_ask_again', { ns: 'sessions' })}
            </label>
          </div>
          <div className="d-flex justify-content-end">
            <Button color="primary" className="ml-2" onClick={grantShowNotificationsPermission}>
              {t('lobby.chat_notifications.grant_permission', { ns: 'sessions' })}
            </Button>
            <Button color="secondary" outline={true} className="ml-2" onClick={() => toggleShowNotificationsModel()}>
              {t('lobby.chat_notifications.no_thanks', { ns: 'sessions' })}
            </Button>
          </div>
        </div>
      </JKModalDialog>
    </>
  );
}

export default JKMusicSessionsLobby;
