import { clsx } from 'clsx'
import { Match, Show, Switch, createEffect, createMemo, createSignal, on } from 'solid-js'

import { useNavigate, useSearchParams } from '@solidjs/router'
import { Button } from '~/components/_shared/Button'
import { CheckButton } from '~/components/_shared/CheckButton'
import { ConditionalWrapper } from '~/components/_shared/ConditionalWrapper'
import { FollowingButton } from '~/components/_shared/FollowingButton'
import { Icon } from '~/components/_shared/Icon'
import { useFollowing } from '~/context/following'
import { useLocalize } from '~/context/localize'
import { useSession } from '~/context/session'
import { Author, FollowingEntity } from '~/graphql/schema/core.gen'
import { mediaMatches } from '~/utils/media-query'
import { translit } from '~/utils/ru2en'
import { isCyrillic } from '~/utils/translate'
import { Userpic } from '../Userpic'
import styles from './AuthorBadge.module.scss'

type Props = {
  author: Author
  minimize?: boolean
  showMessageButton?: boolean
  iconButtons?: boolean
  nameOnly?: boolean
  inviteView?: boolean
  onInvite?: (id: number) => void
  selected?: boolean
  subscriptionsMode?: boolean
}
export const AuthorBadge = (props: Props) => {
  const { session, requireAuthentication } = useSession()
  const author = createMemo<Author>(() => session()?.user?.app_data?.profile as Author)
  const { follow, unfollow, follows, following } = useFollowing()
  const [isMobileView, setIsMobileView] = createSignal(false)
  const [isFollowed, setIsFollowed] = createSignal<boolean>(
    Boolean(follows?.authors?.some((authorEntity) => Boolean(authorEntity.id === props.author?.id)))
  )
  createEffect(() => setIsMobileView(!mediaMatches.sm))
  createEffect(
    on(
      [() => follows?.authors, () => props.author, following],
      ([followingAuthors, currentAuthor, _]) => {
        setIsFollowed(
          Boolean(followingAuthors?.some((followedAuthor) => followedAuthor.id === currentAuthor?.id))
        )
      },
      { defer: true }
    )
  )

  const [, changeSearchParams] = useSearchParams()
  const navigate = useNavigate()
  const { t, formatDate, lang } = useLocalize()

  const initChat = () => {
    // eslint-disable-next-line solid/reactivity
    requireAuthentication(() => {
      navigate('/inbox')
      changeSearchParams({
        initChat: props.author?.id.toString()
      })
    }, 'discussions')
  }

  const name = createMemo(() => {
    if (lang() !== 'ru' && isCyrillic(props.author.name || '')) {
      if (props.author.name === 'Дискурс') {
        return 'Discours'
      }

      return translit(props.author.name || '')
    }

    return props.author.name
  })

  const handleFollowClick = () => {
    requireAuthentication(async () => {
      const handle = isFollowed() ? unfollow : follow
      await handle(FollowingEntity.Author, props.author.slug)
    }, 'follow')
  }

  return (
    <div class={clsx(styles.AuthorBadge, { [styles.nameOnly]: props.nameOnly })}>
      <div class={styles.basicInfo}>
        <Userpic
          hasLink={true}
          size={isMobileView() ? 'M' : 'L'}
          name={name() || ''}
          userpic={props.author.pic || ''}
          slug={props.author.slug}
        />
        <ConditionalWrapper
          condition={!props.inviteView}
          wrapper={(children) => (
            <a href={`/author/${props.author.slug}`} class={styles.info}>
              {children}
            </a>
          )}
        >
          <div class={styles.name}>
            <span>{name()}</span>
          </div>
          <Show when={!props.nameOnly}>
            <Switch
              fallback={
                <div class={styles.bio}>
                  {t('Registered since {date}', {
                    date: formatDate(new Date((props.author.created_at || 0) * 1000))
                  })}
                </div>
              }
            >
              <Match when={props.author.bio}>
                <div class={clsx('text-truncate', styles.bio)} innerHTML={props.author.bio || ''} />
              </Match>
            </Switch>
            <Show when={props.author?.stat && !props.subscriptionsMode}>
              <div class={styles.bio}>
                <Show when={(props.author?.stat?.shouts || 0) > 0}>
                  <div>{t('some posts', { count: props.author.stat?.shouts ?? 0 })}</div>
                </Show>
                <Show when={(props.author?.stat?.comments || 0) > 0}>
                  <div>{t('some comments', { count: props.author.stat?.comments ?? 0 })}</div>
                </Show>
                <Show when={(props.author?.stat?.followers || 0) > 0}>
                  <div>{t('some followers', { count: props.author.stat?.followers ?? 0 })}</div>
                </Show>
              </div>
            </Show>
          </Show>
        </ConditionalWrapper>
      </div>
      <Show when={props.author.slug !== author()?.slug && !props.nameOnly}>
        <div class={styles.actions}>
          <FollowingButton
            action={handleFollowClick}
            isFollowed={isFollowed()}
            actionMessageType={following()?.slug === props.author.slug ? following()?.type : undefined}
          />
          <Show when={props.showMessageButton}>
            <Button
              variant={props.iconButtons ? 'secondary' : 'bordered'}
              size="S"
              value={props.iconButtons ? <Icon name="inbox-white" /> : t('Message')}
              onClick={initChat}
              class={clsx(styles.actionButton, { [styles.iconed]: props.iconButtons })}
            />
          </Show>
        </div>
      </Show>
      <Show when={props.inviteView}>
        <CheckButton
          text={t('Invite')}
          checked={Boolean(props.selected)}
          onClick={() => props.onInvite?.(props.author.id)}
        />
      </Show>
    </div>
  )
}
