import { useState, useEffect, useRef, Fragment, useCallback } from 'react'
import { Route, Link, Routes, useSearchParams } from 'react-router-dom'

import svg4everybody from 'svg4everybody'

import Icon from './ui/Icon'
import { Discover, Discussions, Blog, Tag, Home } from './ui/Feeds'
import { Friends, Readers } from './ui/Users'
import Settings from './ui/Settings'
import Contacts from './ui/Contacts'
import Chat from './ui/Chat'
import Header from './ui/Header'
import Post from './ui/Post'
import Thread from './ui/Thread'
import Login from './ui/Login'

import { useCookies } from 'react-cookie'

import { me, trends } from './api'
import { useVisitor } from './ui/VisitorContext'
import Avatar from './ui/Avatar'
import { Toaster } from 'react-hot-toast'

/**
 * 
 * @param {import('react').PropsWithChildren<{}> & {
 * footer: string
 * }} props props
 */
export default function App({ footer }) {

  let contentRef = useRef(null)
  const [cookie, setCookie] = useCookies(['hash'])

  const [allTrends, setAllTrends] = useState([])

  const [visitor, setVisitor] = useVisitor()

  const params = useSearchParams()

  useEffect(() => {
    svg4everybody()
    if (params['hash']) {
      setCookie('hash', params['hash'], { path: '/' })
      let retpath = params['retpath'] || `${window.location.protocol}//${window.location.host}${window.location.pathname}`
      window.history.replaceState({}, document.title, retpath)
    }
  }, [setCookie, footer, params])

  let updateStatus = useCallback(() => {
    // refresh server visitor state (unread counters)
    me().then(visitor => {
      setVisitor(visitor)
    }).catch(console.error)
  }, [setVisitor])

  const [hash, setHash] = useState(cookie.hash)

  const [eventSource, setEventSource] = /** @param EventSource? */ useState({})

  /**
   * @param {import("./api").SecureUser} visitor
   */
   let auth = useCallback((visitor) => {
    setVisitor(prevState => {
      if (visitor.hash != prevState.hash) {
        setHash(visitor.hash)
      }
      return visitor
    })
  }, [setVisitor])

  useEffect(() => {
    let es
    const anonymousUser = {
      uid: 0
    }
    if (hash) {
      me().then(visitor => auth(visitor))
        .catch(() => setVisitor(anonymousUser))
      if ('EventSource' in window) {
        const eventParams = new URLSearchParams({ hash: hash })
        let url = new URL(`https://juick.com/api/events?${eventParams.toString()}`)
        console.log(url.toString())
        es = new EventSource(url.toString())
        es.onopen = () => {
          console.log('online')
        }
        es.onerror = () => {
          es.removeEventListener('read', updateStatus)
          es.removeEventListener('msg', updateStatus)
        }
        es.addEventListener('read', updateStatus)
        es.addEventListener('msg', updateStatus)
        setEventSource(es)
      }
    } else {
      setVisitor(anonymousUser)
    }
    return (() => {
      if (es && es.removeEventListener) {
        es.removeEventListener('read', updateStatus)
        es.removeEventListener('msg', updateStatus)
      }
    })
  }, [auth, hash, setVisitor, updateStatus])

  useEffect(() => {
    const getTrends = async () => {
      setAllTrends(await trends())
    }
    getTrends().catch(console.error)
  }, [])

  return (
    <>
      <Header />
      <Toaster />
      {
        <aside id="sidebar">
          <div id="sidebar_wrapper">
            {
              <nav id="global">
                {visitor.uid > 0 ?
                  <>
                    <div id="ctitle">
                      <Avatar user={visitor} />
                    </div>
                    <Link to={{ pathname: '/post' }}>
                      <Icon name="ei-pencil" size="s" />
                      <span className="desktop">Post</span>
                    </Link>
                    <Link to="/?show=my">
                      <Icon name="ei-clock" size="s" />
                      <span className="desktop">My feed</span>
                    </Link>
                    <Link to="/pm">
                      <Icon name="ei-envelope" size="s" />
                      <span className="desktop">Messages</span>
                    </Link>
                    <Link to="/settings" rel="nofollow">
                      <Icon name="ei-gear" size="s" />
                      <span className="desktop">Settings</span>
                    </Link>
                  </> :
                  <Link to={{ pathname: '/login' }}>
                    <Icon name="ei-user" size="s" />
                    <span className="desktop">Login</span>
                  </Link>
                }
                <Link to={{ pathname: '/discover' }} rel="nofollow">
                  <Icon name="ei-search" size="s" />
                  <span className="desktop">Discover</span>
                </Link>
                <Link to="/?show=discuss">
                  <Icon name="ei-bell" size="s" />
                  <span className="desktop">Discussions</span>
                </Link>
                <Link to='/?media=1' rel="nofollow">
                  <Icon name="ei-camera" size="s" />
                  <span className="desktop">Photos</span>
                </Link>
              </nav>
            }
            <div className="tags desktop">
              <h4>Trends</h4>
              {allTrends.map((it, index) => (
                <Fragment key={it.tag}>
                  {index > 0 && ' '}
                  <Link to={`/tag/${it.tag}`}>#{it.tag}</Link>
                </Fragment>
              ))}
            </div>
            <div id="footer" className="desktop">
              <div id="footer-left">&copy; 2008-2023, Juick team
                {footer && (<><br />Sponsors: <span dangerouslySetInnerHTML={{ __html: footer }}></span></>)}</div>
              <div id="footer-right">
                &nbsp;&middot;&nbsp;<Link to="/help/contacts" rel="nofollow">Contacts</Link>
                &nbsp;&middot;&nbsp;<Link to="/help/tos" rel="nofollow">TOS</Link>
              </div>
            </div>
          </div>
        </aside>
      }
      <section id="content" ref={contentRef}>
        <Routes>
          <Route exact path="/" element={<Discussions />} />
          <Route exact path="/home" element={<Home />} />
          <Route exact path="/discover" element={<Discover />} />
          <Route exact path="/settings" element={<Settings onChange={auth} />} />
          <Route exact path="/login" element={<Login onAuth={auth} />} />
          <Route exact path="/post" element={<Post />} />
          <Route exact path="/pm" element={<Contacts />} />
          <Route exact path="/pm/:user" element={<Chat connection={eventSource} />} />
          <Route exact path="/:user/friends" element={<Friends />} />
          <Route exact path="/:user/readers" element={<Readers />} />
          <Route exact path="/:user" element={<Blog />} />
          <Route exact path="/tag/:tag" element={<Tag />} />
          <Route exact path="/:user/:mid" element={<Thread connection={eventSource} />} />
        </Routes>
      </section>
    </>
  )
}