"use client"

import { addComment, listCommentsByPost, toggleCommentLike } from "@/lib/api/comments"
import { toApiError } from "@/lib/errors"
import { notifyInfo } from "@/lib/toast"
import type { Comment } from "@/lib/types"
import { useRequireAuth } from "@/lib/use-require-auth"
import { Heart } from "lucide-react"
import { useCallback, useEffect, useState } from "react"
import { Avatar, AvatarFallback, AvatarImage } from "./ui/avatar"
import { Button } from "./ui/button"
import { Textarea } from "./ui/textarea"

interface PostCommentsProps {
  postId: string
}

export function PostComments({ postId }: PostCommentsProps) {
  const [comments, setComments] = useState<Comment[]>([])
  const [loading, setLoading] = useState(true)
  const [loadError, setLoadError] = useState<string | null>(null)
  const [content, setContent] = useState("")
  const [submitting, setSubmitting] = useState(false)
  const [pendingLike, setPendingLike] = useState<Record<string, boolean>>({})
  const { requireAuth } = useRequireAuth()

  const refresh = useCallback(async () => {
    setLoading(true)
    setLoadError(null)
    try {
      const items = await listCommentsByPost(postId)
      setComments(items)
    } catch (err: unknown) {
      setLoadError(toApiError(err).msg)
    } finally {
      setLoading(false)
    }
  }, [postId])

  useEffect(() => {
    void refresh()
  }, [refresh])

  return (
    <div className="space-y-4">
      <h2 className="font-semibold">
        评论 ({loading && comments.length === 0 ? "..." : comments.length})
      </h2>

      <form
        className="flex gap-3"
        onSubmit={(event) => {
          event.preventDefault()
          requireAuth(async () => {
            if (submitting) return

            const nextContent = content.trim()
            if (!nextContent) return

            setSubmitting(true)
            const decision = await addComment(postId, nextContent)
            if (!decision.ok) {
              notifyInfo(decision.error.msg)
              setSubmitting(false)
              return
            }

            setContent("")
            await refresh()
            setSubmitting(false)
          })
        }}
      >
        <Textarea
          placeholder="写下你的评论..."
          className="flex-1"
          rows={2}
          value={content}
          onChange={(event) => setContent(event.target.value)}
        />
        <Button className="self-end" disabled={!content.trim() || submitting}>
          发送
        </Button>
      </form>

      {loading && comments.length === 0 ? (
        <p className="text-sm text-muted-foreground text-center py-8">加载中...</p>
      ) : loadError ? (
        <p className="text-sm text-muted-foreground text-center py-8">加载失败：{loadError}</p>
      ) : comments.length === 0 ? (
        <p className="text-sm text-muted-foreground text-center py-8">还没有评论</p>
      ) : (
        <div className="space-y-4">
          {comments.map((comment) => (
            <div key={comment.id} className="flex gap-3">
              <Avatar className="h-8 w-8">
                <AvatarImage src={comment.author.avatar} />
                <AvatarFallback>{comment.author.nickname[0]}</AvatarFallback>
              </Avatar>
              <div className="flex-1 min-w-0">
                <div className="flex items-center gap-2 mb-0.5">
                  <span className="text-sm font-medium">{comment.author.nickname}</span>
                  <span className="text-xs text-muted-foreground">
                    {new Date(comment.createdAt).toLocaleString("zh-CN")}
                  </span>
                </div>
                <p className="text-sm">{comment.content}</p>
                <button
                  type="button"
                  disabled={pendingLike[comment.id]}
                  className="flex items-center gap-1 text-xs text-muted-foreground hover:text-foreground mt-1 transition-colors"
                  onClick={() =>
                    requireAuth(() => {
                      if (pendingLike[comment.id]) return

                      const prevLiked = comment.liked
                      const prevCount = comment.likeCount
                      const nextLiked = !prevLiked

                      setComments((current) =>
                        current.map((item) => {
                          if (item.id !== comment.id) return item
                          return {
                            ...item,
                            liked: nextLiked,
                            likeCount: Math.max(0, prevCount + (nextLiked ? 1 : -1)),
                          }
                        }),
                      )
                      setPendingLike((current) => ({ ...current, [comment.id]: true }))

                      toggleCommentLike(comment.id, prevLiked)
                        .then((decision) => {
                          if (!decision.ok) {
                            throw decision.error
                          }
                        })
                        .catch((err: unknown) => {
                          setComments((current) =>
                            current.map((item) => {
                              if (item.id !== comment.id) return item
                              return {
                                ...item,
                                liked: prevLiked,
                                likeCount: prevCount,
                              }
                            }),
                          )
                          notifyInfo(toApiError(err).msg)
                        })
                        .finally(() => {
                          setPendingLike((current) => ({ ...current, [comment.id]: false }))
                        })
                    })
                  }
                >
                  <Heart
                    className={`h-3 w-3 ${comment.liked ? "fill-red-500 text-red-500" : ""}`}
                  />
                  {comment.likeCount}
                </button>
              </div>
            </div>
          ))}
        </div>
      )}
    </div>
  )
}
