import LinkButton from '@/components/LinkButton'
import { useNavigate } from '@/router'
import { NonIdealState, Section, SectionCard } from '@blueprintjs/core'
import { css } from '@emotion/css'
import { useTypedQuery } from '@inject/graphql/graphql'
import { GetUser } from '@inject/graphql/queries'
import { notify } from '@inject/shared/notification/engine'
import notEmpty from '@inject/shared/utils/notEmpty'
import { useCallback, useMemo, type FC } from 'react'
import ListItem from './ListItem'
import Options from './Options'
import UserDetailRow from './UserDetailRow'
import UserDetailSetting from './UserDetailSetting'

const listTitle = css`
  font-weight: bolder;
  margin-bottom: 0.5rem;
`

const detailCard = css`
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  align-items: flex-start;
`

const lists = css`
  display: grid;
  grid-template-columns: 1fr 1fr;

  @media (max-width: 40rem) {
    display: flex;
    flex-direction: column;
    gap: 1rem;
  }
`

interface UserDetailProps {
  userId: string
}

const UserDetail: FC<UserDetailProps> = ({ userId }) => {
  const nav = useNavigate()

  const [{ data: userData }, refetch] = useTypedQuery({
    query: GetUser,
    variables: {
      userId,
    },
    requestPolicy: 'network-only',
  })
  const {
    username,
    firstName,
    lastName,
    definitions: definitionsDirty,
    exercises: exercisesDirty,
    teams: teamsDirty,
  } = userData?.user || {}
  const subtitle = useMemo(() => {
    if (firstName && lastName) return `${firstName} ${lastName}`
    if (firstName) return firstName
    if (lastName) return lastName
    return
  }, [firstName, lastName])
  const definitions = useMemo(
    () => (definitionsDirty || []).filter(notEmpty),
    [definitionsDirty]
  )
  const exercises = useMemo(
    () => (exercisesDirty || []).filter(notEmpty),
    [exercisesDirty]
  )
  const teams = useMemo(() => (teamsDirty || []).filter(notEmpty), [teamsDirty])

  const handleDelete = useCallback(() => {
    notify('User deleted successfully', { intent: 'success' })
    nav('/users')
  }, [nav])

  if (!userData || !userData.user) {
    return (
      <NonIdealState
        icon='low-voltage-pole'
        description='Unable to display user'
      />
    )
  }

  return (
    <>
      <LinkButton
        link={['/users']}
        button={{
          text: 'Back',
          icon: 'chevron-left',
          minimal: true,
        }}
      />

      <Section
        title={username}
        subtitle={subtitle}
        icon='user'
        rightElement={
          <Options
            userId={userId}
            onRefetch={refetch}
            onDelete={handleDelete}
          />
        }
      >
        <SectionCard padded className={detailCard}>
          <UserDetailRow
            name='Date joined'
            value={new Date(userData.user.dateJoined)}
          />
          <UserDetailRow
            name='Last login'
            value={
              userData.user.lastLogin ? new Date(userData.user.lastLogin) : null
            }
          />
          <UserDetailRow
            name='Tags'
            value={userData.user.tags.map(tag => tag.name).join(', ')}
          />
          <UserDetailRow name='Imported' value={userData.user.isImported} />
        </SectionCard>
        <SectionCard padded>
          <UserDetailSetting user={userData.user} />
        </SectionCard>
        {exercises.length + teams.length + definitions.length > 0 && (
          <SectionCard padded className={lists}>
            {definitions.length > 0 && (
              <div>
                <div className={listTitle}>Definitions:</div>
                {definitions.map(definition => (
                  <ListItem
                    key={definition.id}
                    name={`${definition.name} (ID: ${definition.id})`}
                    onClick={() =>
                      definition.id &&
                      nav('/exercise-panel/definition/:definitionId', {
                        params: {
                          definitionId: definition.id.toString(),
                        },
                        state: { fromUserDetail: true },
                      })
                    }
                  />
                ))}
              </div>
            )}
            {exercises.length + teams.length > 0 && (
              <div>
                <div className={listTitle}>Exercises:</div>
                {exercises &&
                  exercises.map(exercise => (
                    <ListItem
                      key={exercise.id}
                      name={`${exercise.name} (ID: ${exercise.id}) - instructor`}
                      onClick={() =>
                        nav('/exercise-panel/exercise/:exerciseId', {
                          params: { exerciseId: exercise.id || '' },
                          state: { fromUserDetail: true },
                        })
                      }
                    />
                  ))}
                {teams &&
                  teams.map(team => (
                    <ListItem
                      key={team.id}
                      name={`${team.exercise.name} (ID: ${team.exercise.id}) - ${team.name + (team.role ?? `, ${team.role}`)}`}
                      onClick={() =>
                        nav('/exercise-panel/exercise/:exerciseId', {
                          params: { exerciseId: team.exercise.id },
                          state: { fromUserDetail: true },
                        })
                      }
                    />
                  ))}
              </div>
            )}
          </SectionCard>
        )}
      </Section>
    </>
  )
}

export default UserDetail
