---
import { Icon } from 'astro-icon/components'
import { Markdown } from 'astro-remote'
import { Schema } from 'astro-seo-schema'
import { actions } from 'astro:actions'

import { commentStatusById } from '../constants/commentStatus'
import { karmaUnlocksById } from '../constants/karmaUnlocks'
import { getServiceUserRoleInfo } from '../constants/serviceUserRoles'
import { cn } from '../lib/cn'
import {
  makeCommentUrl,
  MAX_COMMENT_DEPTH,
  type CommentWithRepliesPopulated,
} from '../lib/commentsWithReplies'
import { computeKarmaUnlocks } from '../lib/karmaUnlocks'
import { formatDateShort } from '../lib/timeAgo'

import BadgeSmall from './BadgeSmall.astro'
import CommentModeration from './CommentModeration.astro'
import CommentReply from './CommentReply.astro'
import TimeFormatted from './TimeFormatted.astro'
import Tooltip from './Tooltip.astro'
import UserBadge from './UserBadge.astro'

import type { HTMLAttributes } from 'astro/types'

type Props = HTMLAttributes<'div'> & {
  comment: CommentWithRepliesPopulated
  depth?: number
  showPending?: boolean
  highlightedCommentId: number | null
  serviceSlug: string
  itemReviewedId: string
}

const {
  comment,
  depth = 0,
  showPending = false,
  highlightedCommentId = null,
  serviceSlug,
  itemReviewedId,
  class: className,
  ...htmlProps
} = Astro.props
const user = Astro.locals.user
const userCommentsDisabled = user ? user.karmaUnlocks.commentsDisabled : false
const authorUnlocks = computeKarmaUnlocks(comment.author.totalKarma)

function checkIsHighlightParent(c: CommentWithRepliesPopulated, highlight: number | null): boolean {
  if (!highlight) return false
  if (c.id === highlight) return true
  if (!c.replies?.length) return false
  return c.replies.some((r) => checkIsHighlightParent(r, highlight))
}
const isHighlightParent = checkIsHighlightParent(comment, highlightedCommentId)
const isHighlighted = comment.id === highlightedCommentId

// Get user's current vote if any
const userVote = user ? comment.votes.find((v) => v.userId === user.id) : null

const isAuthor = user?.id === comment.author.id
const isAdminOrVerifier = !!user && (user.admin || user.verifier)
const isAuthorOrPrivileged = isAuthor || isAdminOrVerifier

// Check if user is new (less than 1 week old)
const isNewUser =
  new Date().getTime() - new Date(comment.author.createdAt).getTime() < 7 * 24 * 60 * 60 * 1000

const isRatingActive =
  comment.rating !== null &&
  !comment.parentId &&
  comment.ratingActive &&
  !comment.suspicious &&
  (comment.status === 'APPROVED' || comment.status === 'VERIFIED')

// Skip rendering if comment is not approved/verified and user is not the author or admin/verifier
const shouldShow =
  comment.status === 'APPROVED' ||
  comment.status === 'VERIFIED' ||
  ((showPending || isHighlightParent || isHighlighted) && comment.status === 'PENDING') ||
  ((showPending || isHighlightParent || isHighlighted) && comment.status === 'HUMAN_PENDING') ||
  ((isHighlightParent || isHighlighted) && comment.status === 'REJECTED') ||
  isAuthorOrPrivileged
if (!shouldShow) return null

const commentUrl = makeCommentUrl({ serviceSlug, commentId: comment.id, origin: Astro.url.origin })
---

<style>
  .collapse-toggle:checked + .comment-header .collapse-symbol::before {
    content: '[+]';
  }

  .collapse-symbol::before {
    content: '[-]';
  }
</style>

<div
  {...htmlProps}
  id={`comment-${comment.id.toString()}`}
  class={cn([
    'group',
    depth > 0 && 'ml-3 border-b-0 border-l border-zinc-800 pt-2 pl-2 sm:ml-4',
    comment.author.serviceAffiliations.some((affiliation) => affiliation.service.slug === serviceSlug) &&
      'bg-[#182a1f]',
    (comment.status === 'PENDING' || comment.status === 'HUMAN_PENDING') && 'bg-[#292815]',
    comment.status === 'REJECTED' && 'bg-[#2f1f1f]',
    isHighlighted && 'bg-[#192633]',
    comment.suspicious &&
      'opacity-25 transition-opacity not-has-[[data-collapse-toggle]:checked]:opacity-100! focus-within:opacity-100 hover:opacity-100 focus:opacity-100',
    className,
  ])}
>
  {
    isRatingActive && comment.rating !== null && (
      <Schema
        item={{
          '@context': 'https://schema.org',
          '@type': 'Review',
          '@id': commentUrl,
          author: {
            '@type': 'Person',
            name: comment.author.displayName ?? comment.author.name,
            image: comment.author.picture ?? undefined,
            url: new URL(`/u/${comment.author.name}`, Astro.url).href,
          },
          datePublished: comment.createdAt.toISOString(),
          reviewBody: comment.content,
          reviewAspect: 'User comment',
          commentCount: comment.replies?.length ?? 0,
          itemReviewed: { '@id': itemReviewedId },
          reviewRating: {
            '@type': 'Rating',
            ratingValue: comment.rating,
            bestRating: 5,
            worstRating: 1,
          },
        }}
      />
    )
  }
  <input
    type="checkbox"
    id={`collapse-${comment.id.toString()}`}
    data-collapse-toggle
    class="collapse-toggle peer/collapse hidden"
    checked={comment.suspicious}
  />

  <div class="comment-header flex items-center gap-2 text-sm">
    <label for={`collapse-${comment.id.toString()}`} class="cursor-pointer text-zinc-500 hover:text-zinc-300">
      <span class="collapse-symbol text-xs"></span>
      <span class="sr-only">Toggle comment visibility</span>
    </label>

    <span class="flex items-center gap-1">
      <UserBadge
        user={comment.author}
        size="md"
        class={cn('text-day-300', isAuthor && 'font-medium text-green-500')}
      />

      {
        (comment.author.verified || comment.author.admin || comment.author.verifier) && (
          <Tooltip
            text={`${
              comment.author.admin || comment.author.verifier
                ? `KYCnot.me ${comment.author.admin ? 'Admin' : 'Moderator'}${comment.author.verifiedLink ? '. ' : ''}`
                : ''
            }${comment.author.verifiedLink ? `Related to ${comment.author.verifiedLink}` : ''}`}
          >
            <Icon name="ri:verified-badge-fill" class="size-4 text-cyan-300" />
          </Tooltip>
        )
      }
    </span>

    {/* User badges - more compact but still with text */}
    <div class="flex flex-wrap items-center gap-1">
      {
        comment.author.admin && (
          <BadgeSmall icon="ri:shield-star-fill" color="green" text="Admin" variant="faded" inlineIcon />
        )
      }
      {
        comment.author.verifier && !comment.author.admin && (
          <BadgeSmall
            icon="ri:graduation-cap-fill"
            color="teal"
            text="Moderator"
            variant="faded"
            inlineIcon
          />
        )
      }

      {
        isNewUser && !comment.author.admin && !comment.author.verifier && (
          <Tooltip text={`Joined ${formatDateShort(comment.author.createdAt, { hourPrecision: true })}`}>
            <BadgeSmall icon="ri:user-add-fill" color="purple" text="New User" variant="faded" inlineIcon />
          </Tooltip>
        )
      }
      {
        authorUnlocks.highKarmaBadge && !comment.author.admin && !comment.author.verifier && (
          <BadgeSmall
            icon={karmaUnlocksById.highKarmaBadge.icon}
            color="lime"
            text="High Karma"
            variant="faded"
            inlineIcon
          />
        )
      }
      {
        authorUnlocks.negativeKarmaBadge && !authorUnlocks.untrustedBadge && (
          <BadgeSmall
            icon={karmaUnlocksById.negativeKarmaBadge.icon}
            color="orange"
            text="Negative Karma"
            variant="faded"
            inlineIcon
          />
        )
      }

      {
        (authorUnlocks.untrustedBadge || comment.author.spammer) && (
          <BadgeSmall
            icon={karmaUnlocksById.untrustedBadge.icon}
            color="red"
            text="Untrusted User"
            variant="faded"
            inlineIcon
          />
        )
      }

      {
        comment.author.serviceAffiliations.map((affiliation) => {
          const roleInfo = getServiceUserRoleInfo(affiliation.role)
          return (
            <BadgeSmall
              icon={roleInfo.icon}
              color={roleInfo.color}
              text={`${roleInfo.label} at ${affiliation.service.name}`}
              variant="faded"
              inlineIcon
            />
          )
        })
      }
    </div>
  </div>

  <div class="mt-0.5 flex flex-wrap items-center gap-1 text-xs text-zinc-400">
    <span class="flex items-center gap-1">
      <Icon name="ri:arrow-up-line" class="size-3" />
      {comment.upvotes}
    </span>

    <span class="text-zinc-700">•</span>

    <a href={commentUrl} class="hover:text-zinc-300">
      <TimeFormatted date={comment.createdAt} hourPrecision />
    </a>

    {comment.suspicious && <BadgeSmall icon="ri:spam-2-fill" color="red" text="Potential SPAM" inlineIcon />}

    {
      comment.requiresAdminReview && isAuthorOrPrivileged && (
        <BadgeSmall icon="ri:alert-fill" color="yellow" text="Reported" inlineIcon />
      )
    }

    {
      comment.rating !== null && !comment.parentId && (
        <Tooltip
          text="Not counting for the total"
          position="right"
          enabled={!isRatingActive}
          class={cn('flex items-center gap-1', isRatingActive ? 'text-yellow-400' : 'text-yellow-400/60')}
        >
          <Icon name={isRatingActive ? 'ri:star-fill' : 'ri:star-line'} class="size-3" />
          {comment.rating.toLocaleString()}/5
        </Tooltip>
      )
    }

    {
      comment.status === 'VERIFIED' && (
        <BadgeSmall
          icon={commentStatusById.VERIFIED.icon}
          color={commentStatusById.VERIFIED.color}
          text={commentStatusById.VERIFIED.label}
          inlineIcon
        />
      )
    }

    {
      (comment.status === 'PENDING' || comment.status === 'HUMAN_PENDING') &&
        (showPending || isHighlightParent || isAuthorOrPrivileged) && (
          <BadgeSmall
            icon={commentStatusById.PENDING.icon}
            color={commentStatusById.PENDING.color}
            text={commentStatusById.PENDING.label}
            inlineIcon
          />
        )
    }

    {
      comment.status === 'REJECTED' && isAuthorOrPrivileged && (
        <BadgeSmall
          icon={commentStatusById.REJECTED.icon}
          color={commentStatusById.REJECTED.color}
          text={commentStatusById.REJECTED.label}
          inlineIcon
        />
      )
    }

    {/* Service usage verification indicators */}
    {
      comment.orderId && comment.orderIdStatus === 'APPROVED' && (
        <BadgeSmall icon="ri:verified-badge-fill" color="green" text="Valid order ID" inlineIcon />
      )
    }
    {
      comment.orderId && comment.orderIdStatus === 'REJECTED' && (
        <BadgeSmall icon="ri:close-circle-fill" color="red" text="Invalid order ID" inlineIcon />
      )
    }
    {
      comment.kycRequested && (
        <BadgeSmall icon="ri:user-forbid-fill" color="red" text="KYC issue" inlineIcon />
      )
    }
    {
      comment.fundsBlocked && (
        <BadgeSmall icon="ri:wallet-3-fill" color="orange" text="Funds blocked" inlineIcon />
      )
    }
  </div>

  <div class={cn(['comment-body mt-2 peer-checked/collapse:hidden'])}>
    {
      isAuthor && comment.status === 'REJECTED' && (
        <div class="mb-2 inline-block rounded-xs bg-red-500/30 px-2 py-1 text-xs text-red-300">
          This comment has been rejected and is only visible to you
        </div>
      )
    }

    <div class="text-sm">
      {
        !!comment.content && (
          <div class="prose prose-invert prose-sm max-w-none overflow-auto">
            <Markdown content={comment.content} />
          </div>
        )
      }
    </div>
  </div>

  {
    comment.communityNote && (
      <div class="mt-2 peer-checked/collapse:hidden">
        <div class="border-l-2 border-zinc-600 bg-zinc-900/30 py-0.5 pl-2 text-xs">
          <span class="prose prose-sm prose-invert prose-strong:text-zinc-300/90 text-xs text-zinc-300">
            <Markdown content={`**Added context:** ${comment.communityNote}`} />
          </span>
        </div>
      </div>
    )
  }

  {
    user && (user.admin || user.verifier) && comment.internalNote && (
      <div class="mt-2 peer-checked/collapse:hidden">
        <div class="border-l-2 border-red-600 bg-red-900/20 py-0.5 pl-2 text-xs">
          <span class="font-medium text-red-400">Internal note:</span>
          <span class="text-red-300">{comment.internalNote}</span>
        </div>
      </div>
    )
  }

  {
    user && (user.admin || user.verifier) && comment.privateContext && (
      <div class="mt-2 peer-checked/collapse:hidden">
        <div class="border-l-2 border-blue-600 bg-blue-900/20 py-0.5 pl-2 text-xs">
          <span class="font-medium text-blue-400">Private context:</span>
          <span class="text-blue-300">{comment.privateContext}</span>
        </div>
      </div>
    )
  }

  <div class="mt-2 flex items-center gap-3 text-xs peer-checked/collapse:hidden">
    <div class="flex items-center gap-1">
      <form method="POST" action={actions.comment.vote} class="inline" data-astro-reload>
        <input type="hidden" name="commentId" value={comment.id} />
        <input type="hidden" name="downvote" value="false" />
        <Tooltip
          as="button"
          type="submit"
          disabled={!user?.totalKarma || user.totalKarma < 20}
          class={cn([
            'rounded-sm p-1 hover:bg-zinc-800',
            userVote?.downvote === false ? 'text-blue-500' : 'text-zinc-500',
            (!user?.totalKarma || user.totalKarma < 20) && 'cursor-not-allowed text-zinc-700',
          ])}
          text={user?.totalKarma && user.totalKarma >= 20 ? 'Upvote' : 'Need 20+ karma to vote'}
          position="right"
          aria-label="Upvote"
        >
          <Icon name="ri:arrow-up-line" class="h-3.5 w-3.5" />
        </Tooltip>
      </form>
      <form method="POST" action={actions.comment.vote} class="inline" data-astro-reload>
        <input type="hidden" name="commentId" value={comment.id} />
        <input type="hidden" name="downvote" value="true" />
        <Tooltip
          as="button"
          text={user?.totalKarma && user.totalKarma >= 20 ? 'Downvote' : 'Need 20+ karma to vote'}
          position="right"
          disabled={!user?.totalKarma || user.totalKarma < 20}
          class={cn([
            'rounded-sm p-1 hover:bg-zinc-800',
            userVote?.downvote === true ? 'text-red-500' : 'text-zinc-500',
            (!user?.totalKarma || user.totalKarma < 20) && 'cursor-not-allowed text-zinc-700',
          ])}
          aria-label="Downvote"
        >
          <Icon name="ri:arrow-down-line" class="h-3.5 w-3.5" />
        </Tooltip>
      </form>
    </div>
    {
      user && userCommentsDisabled ? (
        <span class="text-xs text-red-400">You cannot reply due to low karma.</span>
      ) : (
        <label
          for={`reply-toggle-${comment.id.toString()}`}
          class="flex cursor-pointer items-center gap-1 text-zinc-400 hover:text-zinc-200"
        >
          <Icon name="ri:reply-line" class="h-3.5 w-3.5" />
          Reply
        </label>
      )
    }
    {
      user && (
        <form
          method="POST"
          action={`${actions.notification.preferences.watchComment}&comment=${comment.id.toString()}#comment-${comment.id.toString()}`}
          class="inline"
          data-astro-reload
        >
          <input type="hidden" name="commentId" value={comment.id} />
          <input type="hidden" name="watch" value={comment.isWatchingReplies ? 'false' : 'true'} />
          <button
            type="submit"
            class="flex cursor-pointer items-center gap-1 text-zinc-400 hover:text-zinc-200"
          >
            <Icon name={comment.isWatchingReplies ? 'ri:eye-off-line' : 'ri:eye-line'} class="size-3" />
            {comment.isWatchingReplies ? 'Unwatch' : 'Watch'}
          </button>
        </form>
      )
    }
  </div>
  <CommentModeration class="mt-2 peer-checked/collapse:hidden" comment={comment} />

  {
    user && userCommentsDisabled ? null : (
      <>
        <input type="checkbox" id={`reply-toggle-${comment.id.toString()}`} class="peer/reply hidden" />
        <CommentReply
          serviceId={comment.serviceId}
          parentId={comment.id}
          commentId={comment.id}
          class="mt-2 hidden peer-checked/collapse:hidden peer-checked/reply:block"
        />
      </>
    )
  }

  {
    comment.replies && comment.replies.length > 0 && depth < MAX_COMMENT_DEPTH && (
      <div class="replies mt-3 peer-checked/collapse:hidden">
        {comment.replies.map((reply) => (
          <Astro.self
            comment={reply}
            depth={depth + 1}
            showPending={showPending}
            highlightedCommentId={isHighlightParent ? highlightedCommentId : null}
            serviceSlug={serviceSlug}
            itemReviewedId={itemReviewedId}
          />
        ))}
      </div>
    )
  }
</div>
