import React, { Fragment, useMemo, useState } from 'react';
import { Disclosure, Menu, Transition } from '@headlessui/react';
import { MenuIcon, XIcon } from '@heroicons/react/outline';
import { useAuth } from 'src/services/auth';
import Gravatar from 'react-gravatar';
import { Link, useLocation } from 'react-router-dom';
import clsx from 'clsx';
import _ from 'lodash';

import { UserModal } from '../UserModal';

const HYDRA_LOGOUT_URL = `${process.env.REACT_APP_HYDRA_PUBLIC_URL}/oauth2/sessions/logout`;

const navigation = [
  { name: 'Dashboard', to: '/dashboard', requiresAdmin: false },
  { name: 'Users', to: '/users', requiresAdmin: true },
  { name: 'Apps', to: '/apps', requiresAdmin: true },
];

function classNames(...classes: any[]) {
  return classes.filter(Boolean).join(' ');
}

function filterNavigationByDashboardRole(isAdmin: boolean) {
  if (isAdmin) {
    return navigation;
  }

  return navigation.filter((item) => !item.requiresAdmin);
}

// eslint-disable-next-line @typescript-eslint/no-empty-interface
interface HeaderProps {}

const Header: React.FC<HeaderProps> = () => {
  const [currentUserModal, setCurrentUserModal] = useState(false);
  const [currentUserId, setCurrentUserId] = useState(null);
  const { logOut, currentUser, isAdmin } = useAuth();

  const { pathname } = useLocation();

  const currentUserModalOpen = (id: any) => {
    setCurrentUserId(id);
    setCurrentUserModal(true);
  };

  const currentUserModalClose = () => {
    setCurrentUserModal(false);
    setCurrentUserId(null);
  };

  const navigationItems = filterNavigationByDashboardRole(isAdmin);

  const signOutUrl = useMemo(() => {
    const { hostname } = window.location;
    // If we are developing locally, we need to use the init cluster's public URL
    if (hostname === 'localhost') {
      return HYDRA_LOGOUT_URL;
    }
    return `https://${hostname.replace(/^dashboard/, 'sso')}/oauth2/sessions/logout`;
  }, []);

  return (
    <>
      <Disclosure as="nav" className="bg-white shadow relative z-10">
        {({ open }) => (
          <div className="relative">
            <div className="max-w-7xl mx-auto px-2 sm:px-6 lg:px-8">
              <div className="relative flex justify-between h-16">
                <div className="absolute inset-y-0 left-0 flex items-center sm:hidden">
                  {/* Mobile menu button */}
                  <Disclosure.Button className="inline-flex items-center justify-center p-2 rounded-md text-gray-400 hover:text-gray-500 hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-inset focus:ring-primary-500">
                    <span className="sr-only">Open main menu</span>
                    {open ? (
                      <XIcon className="block h-6 w-6" aria-hidden="true" />
                    ) : (
                      <MenuIcon className="block h-6 w-6" aria-hidden="true" />
                    )}
                  </Disclosure.Button>
                </div>
                <div className="flex-1 flex items-center justify-center sm:items-stretch sm:justify-start">
                  <Link to="/" className="flex-shrink-0 flex items-center">
                    <img className="block lg:hidden" src="/assets/logo-small.svg" alt="Stackspin" />
                    <img className="hidden lg:block" src="/assets/logo.svg" alt="Stackspin" />
                  </Link>
                  <div className="hidden sm:ml-6 sm:flex sm:space-x-8">
                    {/* Current: "border-primary-500 text-gray-900", Default: "border-transparent text-gray-500 hover:border-gray-300 hover:text-gray-700" */}
                    {navigationItems.map((item) => (
                      <Link
                        key={item.name}
                        to={item.to}
                        className={clsx(
                          'border-primary-50 text-gray-900 inline-flex items-center px-1 pt-1 border-b-2 text-sm font-medium',
                          {
                            'border-primary-500 text-gray-500 hover:border-gray-300 hover:text-gray-700 inline-flex items-center px-1 pt-1 text-sm font-medium':
                              pathname.includes(item.to),
                          },
                        )}
                      >
                        {item.name}
                      </Link>
                    ))}
                  </div>
                </div>
                <div className="absolute inset-y-0 right-0 flex items-center pr-2 sm:static sm:inset-auto sm:ml-6 sm:pr-0">
                  {/* Profile dropdown */}
                  <Menu as="div" className="ml-3 relative">
                    <div>
                      <Menu.Button className="bg-white rounded-full flex text-sm focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary">
                        <span className="sr-only">Open user menu</span>
                        <span className="inline-flex items-center justify-center h-8 w-8 rounded-full bg-gray-500 overflow-hidden">
                          <Gravatar email={currentUser?.email || undefined} size={32} rating="pg" protocol="https://" />
                        </span>
                      </Menu.Button>
                    </div>
                    <Transition
                      as={Fragment}
                      enter="transition ease-out duration-200"
                      enterFrom="transform opacity-0 scale-95"
                      enterTo="transform opacity-100 scale-100"
                      leave="transition ease-in duration-75"
                      leaveFrom="transform opacity-100 scale-100"
                      leaveTo="transform opacity-0 scale-95"
                    >
                      <Menu.Items className="origin-top-right absolute right-0 mt-2 w-48 rounded-md shadow-lg py-1 bg-white ring-1 ring-black ring-opacity-5 focus:outline-none">
                        <Menu.Item>
                          {({ active }) => (
                            <a
                              onClick={() => currentUserModalOpen(currentUser?.id)}
                              className={classNames(
                                active ? 'bg-gray-100 cursor-pointer' : '',
                                'block px-4 py-2 text-sm text-gray-700 cursor-pointer',
                              )}
                            >
                              Configure profile
                            </a>
                          )}
                        </Menu.Item>
                        <Menu.Item>
                          {({ active }) => (
                            <a
                              onClick={() => logOut()}
                              href={signOutUrl}
                              className={classNames(
                                active ? 'bg-gray-100 cursor-pointer' : '',
                                'block px-4 py-2 text-sm text-gray-700 cursor-pointer',
                              )}
                            >
                              Sign out
                            </a>
                          )}
                        </Menu.Item>
                      </Menu.Items>
                    </Transition>
                  </Menu>
                </div>
              </div>
            </div>

            <Disclosure.Panel className="sm:hidden">
              <div className="pt-2 pb-4 space-y-1">
                {navigation.map((item) => (
                  <Link
                    key={item.name}
                    to={item.to}
                    className={clsx(
                      'border-transparent text-gray-500 hover:text-gray-700 block pl-3 pr-4 py-2 border-l-4 text-base font-medium',
                      {
                        'bg-primary-50 border-primary-400 text-primary-700 block pl-3 pr-4 py-2': pathname.includes(
                          item.to,
                        ),
                      },
                    )}
                  >
                    {item.name}
                  </Link>
                ))}
              </div>
            </Disclosure.Panel>
          </div>
        )}
      </Disclosure>

      {currentUserModal && (
        <UserModal open={currentUserModal} onClose={currentUserModalClose} userId={currentUserId} setUserId={_.noop} />
      )}
    </>
  );
};

export default Header;
