"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 { AlertCircle, Heart, MessageCircle } from "lucide-react"
import { useCallback, useEffect, useState } from "react"
import { Avatar, AvatarFallback, AvatarImage } from "./ui/avatar"
import { Button } from "./ui/button"
import { EmptyState } from "./ui/empty-state"
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 (showLoading = true) => {
      if (showLoading) {
        setLoading(true)
        setLoadError(null)
      }
      try {
        const items = await listCommentsByPost(postId)
        setComments(items)
      } catch (err: unknown) {
        setLoadError(toApiError(err).msg)
      } finally {
        setLoading(false)
      }
    },
    [postId],
  )

  useEffect(() => {
    let cancelled = false

    void (async () => {
      try {
        const items = await listCommentsByPost(postId)
        if (cancelled) return
        setComments(items)
      } catch (err: unknown) {
        if (cancelled) return
        setLoadError(toApiError(err).msg)
      } finally {
        if (!cancelled) setLoading(false)
      }
    })()

    return () => {
      cancelled = true
    }
  }, [postId])

  return (
    <div className="space-y-4">
      <div className="flex items-center justify-between border-b border-border/60 pb-3">
        <h2 className="font-semibold">评论</h2>
        <span className="text-xs text-muted-foreground">
          {loading && comments.length === 0 ? "加载中" : `${comments.length} 条`}
        </span>
      </div>

      <form
        className="space-y-3 rounded-xl border border-border/80 bg-card p-3 shadow-sm"
        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="min-h-20 resize-none bg-transparent"
          rows={2}
          value={content}
          onChange={(event) => setContent(event.target.value)}
        />
        <div className="flex justify-end">
          <Button size="sm" disabled={!content.trim() || submitting}>
            发送
          </Button>
        </div>
      </form>

      {loading && comments.length === 0 ? (
        <EmptyState title="评论加载中" icon={MessageCircle} className="min-h-[180px]" />
      ) : loadError ? (
        <EmptyState
          title="评论加载失败"
          description={loadError}
          icon={AlertCircle}
          className="min-h-[180px]"
        />
      ) : comments.length === 0 ? (
        <EmptyState
          title="还没有评论"
          description="可以写下第一条评论。"
          icon={MessageCircle}
          className="min-h-[180px] border-dashed"
        />
      ) : (
        <div className="overflow-hidden rounded-xl border border-border/80 bg-card shadow-sm">
          {comments.map((comment) => (
            <div
              key={comment.id}
              className="flex gap-3 border-b border-border/60 p-4 last:border-0"
            >
              <Avatar className="h-8 w-8">
                <AvatarImage src={comment.author.avatar} />
                <AvatarFallback>{comment.author.nickname[0]}</AvatarFallback>
              </Avatar>
              <div className="min-w-0 flex-1">
                <div className="mb-0.5 flex items-center gap-2">
                  <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 leading-relaxed">{comment.content}</p>
                <button
                  type="button"
                  aria-label={comment.liked ? "取消点赞评论" : "点赞评论"}
                  disabled={pendingLike[comment.id]}
                  className="mt-2 flex items-center gap-1 text-xs text-muted-foreground transition-colors hover:text-foreground disabled:pointer-events-none disabled:opacity-60"
                  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-destructive text-destructive" : ""}`}
                  />
                  {comment.likeCount}
                </button>
              </div>
            </div>
          ))}
        </div>
      )}
    </div>
  )
}
