import {JSONContent} from '@tiptap/core'
import clsx from 'clsx'
import {CompatibilityScore} from 'common/profiles/compatibility-score'
import {Profile} from 'common/profiles/profile'
import {capitalize} from 'lodash'
import Image from 'next/image'
import Link from 'next/link'
import {Row} from 'web/components/layout/row'
import {CompatibleBadge} from 'web/components/widgets/compatible-badge'
import {Content} from 'web/components/widgets/editor'
import HideProfileButton from 'web/components/widgets/hide-profile-button'
import {CompassLoadingIndicator} from 'web/components/widgets/loading-indicator'
import {LoadMoreUntilNotVisible} from 'web/components/widgets/visibility-observer'
import {useAllChoices} from 'web/hooks/use-choices'
import {useUser} from 'web/hooks/use-user'
import {useT} from 'web/lib/locale'
import {getSeekingGenderText} from 'web/lib/profile/seeking'

import {Col} from './layout/col'

export const ProfileGrid = (props: {
  profiles: Profile[]
  loadMore: () => Promise<boolean>
  isLoadingMore: boolean
  isReloading: boolean
  compatibilityScores: Record<string, CompatibilityScore> | undefined
  starredUserIds: string[] | undefined
  refreshStars: () => Promise<void>
  onHide?: (userId: string) => void
  hiddenUserIds?: string[]
  onUndoHidden?: (userId: string) => void
  showPhotos?: boolean | null
}) => {
  const {
    profiles,
    loadMore,
    isLoadingMore,
    isReloading,
    compatibilityScores,
    starredUserIds,
    refreshStars,
    onHide,
    hiddenUserIds,
    onUndoHidden,
    showPhotos,
  } = props

  const user = useUser()
  const t = useT()

  const other_profiles = profiles.filter((profile) => profile.user_id !== user?.id)

  return (
    <div className="relative">
      <div
        className={clsx(
          'grid grid-cols-1 sm:grid-cols-1 lg:grid-cols-1 xl:grid-cols-2 gap-6 py-4',
          isReloading && 'animate-pulse opacity-80',
        )}
      >
        {other_profiles.map((profile) => (
          <ProfilePreview
            key={profile.id}
            profile={profile}
            compatibilityScore={compatibilityScores?.[profile.user_id]}
            hasStar={starredUserIds?.includes(profile.user_id) ?? false}
            refreshStars={refreshStars}
            onHide={onHide}
            isHidden={hiddenUserIds?.includes(profile.user_id) ?? false}
            onUndoHidden={onUndoHidden}
            showPhotos={showPhotos}
          />
        ))}
      </div>

      <LoadMoreUntilNotVisible loadMore={loadMore} />

      {isLoadingMore && (
        <div className="flex justify-center py-4">
          <CompassLoadingIndicator />
        </div>
      )}

      {!isLoadingMore && !isReloading && other_profiles.length === 0 && (
        <div className="py-8 text-center">
          <p>{t('profile_grid.no_profiles', 'No profiles found.')}</p>
          <p>
            {t(
              'profile_grid.notification_cta',
              "Feel free to click on Get Notified and we'll notify you when new users match your search!",
            )}
          </p>
        </div>
      )}
    </div>
  )
}

function ProfilePreview(props: {
  profile: Profile
  compatibilityScore: CompatibilityScore | undefined
  hasStar: boolean
  refreshStars: () => Promise<void>
  onHide?: (userId: string) => void
  isHidden?: boolean
  onUndoHidden?: (userId: string) => void
  showPhotos?: boolean | null
}) {
  const {profile, compatibilityScore, onHide, isHidden, onUndoHidden, showPhotos} = props
  const {user} = profile
  const choicesIdsToLabels = useAllChoices()
  const t = useT()
  // const currentUser = useUser()

  const bio = profile.bio as JSONContent

  // If this profile was just hidden, render a compact placeholder with Undo action.
  if (isHidden) {
    return (
      <div className="block rounded-lg border border-canvas-300 bg-canvas-50 dark:bg-gray-800/50 p-3 text-sm">
        <Row className="items-center justify-between gap-2">
          <span className="text-ink-700 dark:text-ink-300">
            {t(
              'profile_grid.profile_hidden_short',
              "You won't see {name} in your search results anymore.",
              {name: user?.name},
            )}
          </span>
          <button
            className="text-primary-500 hover:text-primary-700 underline"
            onClick={(e: React.MouseEvent<HTMLButtonElement>) => {
              e.preventDefault()
              e.stopPropagation()
              onUndoHidden?.(profile.user_id)
            }}
          >
            {t('profile_grid.undo', 'Undo')}
          </button>
        </Row>
      </div>
    )
  }

  if (bio && bio.content) {
    const newBio = []
    let i = 0
    for (const c of bio.content) {
      if ((c?.content?.length || 0) == 0) continue
      if (c.type === 'paragraph') {
        newBio.push(c)
      } else if (['heading'].includes(c.type ?? '')) {
        newBio.push({
          type: 'paragraph',
          content: c.content,
        })
      } else if (c.type === 'image') {
        continue
      } else {
        newBio.push(c)
      }
      i += 1
      if (i >= 5) break
    }
    bio.content = newBio
  }

  const seekingGenderText = getSeekingGenderText(profile, t)

  // if (!profile.work?.length && !profile.occupation_title && !profile.interests?.length && (profile.bio_length || 0) < 100) {
  //   return null
  // }

  const isPhotoRendered = showPhotos !== false && profile.pinned_url
  return (
    <Link
      // onClick={() => track('click profile preview')}
      href={`/${user.username}`}
      className="cursor-pointer group block rounded-lg overflow-hidden bg-transparent hover:bg-gray-50 dark:hover:bg-gray-800/50 h-full border border-canvas-300"
    >
      <Col className="relative h-40 w-full overflow-hidden rounded transition-all">
        <Row className="absolute top-2 right-2 items-start justify-end px-2 pb-3 z-10">
          {/*  {currentUser ? (*/}
          {/*    <StarButton*/}
          {/*      className="!pt-0"*/}
          {/*      isStarred={hasStar}*/}
          {/*      refresh={refreshStars}*/}
          {/*      targetProfile={profile}*/}
          {/*      hideTooltip*/}
          {/*    />*/}
          {/*  ) : (*/}
          {/*    <div />*/}
          {/*  )}*/}
          {compatibilityScore && (
            <CompatibleBadge compatibility={compatibilityScore} className={'pt-1'} />
          )}
          {/* Hide profile button */}
          {onHide && (
            <HideProfileButton
              hiddenUserId={profile.user_id}
              onHidden={onHide}
              className="ml-2"
              stopPropagation
              eyeOff
            />
          )}
        </Row>

        <Col
          className={clsx(
            'absolute inset-x-0 top-[-15px] bg-gradient-to-b to-transparent px-4 pt-0',
            isPhotoRendered && 'mr-24',
          )}
        >
          <div>
            <div className="flex-1 min-w-0">
              <h3 className="text-lg font-medium text-gray-900 dark:text-white truncate">
                {user.name}
                {profile.age && `, ${profile.age}`}
                {/*{profile.gender && <GenderIcon gender={profile.gender} className={clsx('h-4 w-4')} hasColor />}*/}
              </h3>
              <div className="line-clamp-4">
                {/*TODO: fix nested <a> links warning (one from Link above, one from link in bio below)*/}
                {profile.headline && <p>{profile.headline}</p>}
                {profile.keywords?.map(capitalize)?.join(' • ')}
                <Content className="w-full" content={bio} />
                {seekingGenderText && <p>{seekingGenderText}.</p>}
                {(!!profile.work?.length || profile.occupation_title) && (
                  <p>
                    {t('profile.optional.category.work', 'Work')}: {profile.occupation_title}
                    {profile.occupation_title && !!profile.work?.length && ', '}
                    {profile.work?.map((id) => choicesIdsToLabels['work'][id]).join(' • ')}
                    {/*{(profile.work?.length || 0) > 3 && ',...'}*/}
                  </p>
                )}
                {!!profile.interests?.length && (
                  <p>
                    {t('profile.optional.interests', 'Interests')}:{' '}
                    {profile.interests
                      ?.map((id) => choicesIdsToLabels['interests'][id])
                      .join(' • ')}
                  </p>
                )}
              </div>
            </div>
          </div>
          {/*<Row className="gap-1 text-xs">*/}
          {/*  {city} • {capitalize(convertGender(gender as Gender))}*/}
          {/*</Row>*/}
        </Col>

        {/* Profile image moved to bottom right */}
        {isPhotoRendered && (
          <div className="absolute bottom-4 right-2 w-24 h-24 rounded-xl overflow-hidden shadow-lg">
            <Image
              src={profile.pinned_url!}
              width={128}
              height={128}
              alt=""
              className="h-full w-full object-cover"
              loading="lazy"
              priority={false}
            />
          </div>
        )}
      </Col>
    </Link>
  )
}
