"use client"

import { useEffect, useState } from "react"
import Link from "next/link"
import { useRouter } from "next/navigation"
import { toast } from "sonner"
import { useTranslations } from "next-intl"
import { ArrowLeft, Loader2, Mail, Reply, RotateCcw, Star, Trash2 } from "lucide-react"

import { Badge } from "@/shared/components/ui/badge"
import { Button } from "@/shared/components/ui/button"
import { Card, CardContent, CardHeader, CardTitle } from "@/shared/components/ui/card"
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/shared/components/ui/dialog"
import { ConfirmDeleteDialog } from "@/shared/components/ui/confirm-delete-dialog"
import { cn, formatDate } from "@/shared/lib/utils"
import { usePermission } from "@/shared/hooks/use-permission"
import { Permissions } from "@/shared/types/permissions"

import { deleteMessageAction, getMessageThreadAction, recallMessageAction, toggleMessageStarAction } from "../actions"
import { buildReplyHref } from "../lib/build-reply-href"
import { MessageReportBlock } from "./message-report-block"
import type { Message } from "../types"

export function MessageDetail({
  message,
  currentUserId,
  backHref = "/messages",
}: {
  message: Message
  currentUserId: string
  backHref?: string
}) {
  const t = useTranslations("messages")
  const router = useRouter()
  const [isWorking, setIsWorking] = useState(false)
  const [deleteOpen, setDeleteOpen] = useState(false)
  const [recallOpen, setRecallOpen] = useState(false)
  const [isRecalling, setIsRecalling] = useState(false)
  const [isStarred, setIsStarred] = useState(message.isStarred)
  const [isTogglingStar, setIsTogglingStar] = useState(false)
  // P1-3: 线程状态
  const [thread, setThread] = useState<Message[]>([])
  const [loadingThread, setLoadingThread] = useState(true)
  // P2-4: 撤回状态（同步 UI，撤回成功后立即显示占位）
  const [isRecalled, setIsRecalled] = useState(message.recalledAt !== null)
  const { hasPermission } = usePermission()
  const canSend = hasPermission(Permissions.MESSAGE_SEND)
  const canDelete = hasPermission(Permissions.MESSAGE_DELETE)

  const isReceived = message.receiverId === currentUserId
  // P2-4: 仅发送方在 2 分钟窗口内、且消息未被撤回时可撤回
  const canRecall =
    !isReceived &&
    canSend &&
    !isRecalled &&
    Date.now() - new Date(message.createdAt).getTime() <= 2 * 60 * 1000
  const counterpart = isReceived ? message.senderName : message.receiverName
  const counterpartLabel = isReceived ? t("meta.from") : t("meta.to")

  // P1-3: 获取消息线程（根消息 + 回复链）
  useEffect(() => {
    let active = true
    setLoadingThread(true)
    void getMessageThreadAction(message.id)
      .then((res) => {
        if (!active) return
        if (res.success && res.data) {
          setThread(res.data)
        } else {
          setThread([])
        }
      })
      .catch(() => {
        if (!active) return
        setThread([])
      })
      .finally(() => {
        if (active) setLoadingThread(false)
      })
    return () => {
      active = false
    }
  }, [message.id])

  const handleDelete = async () => {
    setIsWorking(true)
    try {
      const res = await deleteMessageAction(message.id)
      if (res.success) {
        toast.success(res.message)
        router.push("/messages")
        router.refresh()
      } else {
        toast.error(res.message || t("messages.deleteFailed"))
      }
    } catch {
      toast.error(t("messages.deleteFailed"))
    } finally {
      setIsWorking(false)
      setDeleteOpen(false)
    }
  }

  const handleToggleStar = async () => {
    setIsTogglingStar(true)
    const prevStarred = isStarred
    // 乐观更新
    setIsStarred(!prevStarred)
    try {
      const res = await toggleMessageStarAction(message.id)
      if (res.success) {
        toast.success(t("messages.starToggled"))
      } else {
        // 回滚
        setIsStarred(prevStarred)
        toast.error(res.message)
      }
    } catch {
      // 回滚
      setIsStarred(prevStarred)
      toast.error(t("messages.sendFailed"))
    } finally {
      setIsTogglingStar(false)
    }
  }

  // P2-4: 消息撤回（仅发送方，2 分钟窗口内）
  const handleRecall = async () => {
    setIsRecalling(true)
    try {
      const res = await recallMessageAction(message.id)
      if (res.success) {
        // 同步 UI：立即显示"已撤回"占位
        setIsRecalled(true)
        toast.success(t("messages.recalled"))
        router.refresh()
      } else {
        // 失败：根据返回消息判断是否超时
        if (res.message === "Recall window expired") {
          toast.error(t("messages.recallExpired"))
        } else {
          toast.error(res.message || t("messages.recallFailed"))
        }
      }
    } catch {
      toast.error(t("messages.recallFailed"))
    } finally {
      setIsRecalling(false)
      setRecallOpen(false)
    }
  }

  // P1-7: 使用纯函数构建回复链接（替代组件内字符串拼接）
  const replyHref = buildReplyHref(message, currentUserId, canSend)

  // 线程展示：根消息已渲染在主区域，这里仅展示回复（时间正序）
  // data-access 返回倒序（最新在前），UI 反转为正序（最早回复在前）
  const replies = thread
    .filter((m) => m.id !== message.id)
    .slice()
    .reverse()

  return (
    <div className="space-y-6">
      <div className="flex items-center justify-between gap-2">
        <div className="flex items-center gap-2">
          <Button asChild variant="ghost" size="icon" aria-label={t("actions.back")}>
            <Link href={backHref}>
              <ArrowLeft className="h-4 w-4" />
            </Link>
          </Button>
          <h2 className="text-2xl font-bold tracking-tight">{t("title.detail")}</h2>
        </div>
        <div className="flex flex-wrap items-center gap-2">
          <Button
            onClick={handleToggleStar}
            disabled={isTogglingStar}
            variant={isStarred ? "default" : "outline"}
            aria-pressed={isStarred}
          >
            <Star
              className={cn("mr-2 h-4 w-4", isStarred && "fill-current")}
            />
            {isStarred ? t("actions.unstar") : t("actions.star")}
          </Button>
          {/* P2-4: 撤回按钮（仅发送方可见且未撤回、未超时） */}
          {canRecall ? (
            <Button
              onClick={() => setRecallOpen(true)}
              disabled={isRecalling}
              variant="outline"
            >
              <RotateCcw className="mr-2 h-4 w-4" />
              {t("actions.recall")}
            </Button>
          ) : null}
          {canSend && !isRecalled ? (
            <Button asChild variant="outline">
              <Link href={replyHref ?? "#"}>
                <Reply className="mr-2 h-4 w-4" />
                {t("actions.reply")}
              </Link>
            </Button>
          ) : null}
          {canDelete ? (
            <Button onClick={() => setDeleteOpen(true)} disabled={isWorking} variant="destructive">
              <Trash2 className="mr-2 h-4 w-4" />
              {t("actions.delete")}
            </Button>
          ) : null}
          {/* P2-5: 举报 + 屏蔽（仅收到的消息，非自己发送的） */}
          {isReceived && !isRecalled ? (
            <MessageReportBlock
              messageId={message.id}
              senderId={message.senderId}
              currentUserId={currentUserId}
            />
          ) : null}
        </div>
      </div>

      <Card>
        <CardHeader className="space-y-2">
          <div className="flex flex-wrap items-center gap-2">
            <Mail className="text-muted-foreground h-4 w-4" aria-hidden="true" />
            {/* P2-4: 已撤回状态优先显示 */}
            {isRecalled ? (
              <Badge variant="secondary">{t("status.recalled")}</Badge>
            ) : isReceived && !message.isRead ? (
              <Badge variant="default">{t("status.new")}</Badge>
            ) : isReceived ? (
              <Badge variant="secondary">{t("status.read")}</Badge>
            ) : (
              <Badge variant="outline">{t("status.sent")}</Badge>
            )}
            {isStarred ? (
              <span className="inline-flex items-center gap-1 text-xs text-yellow-600">
                <Star className="h-3.5 w-3.5 fill-yellow-400 text-yellow-400" aria-hidden="true" />
                {t("actions.star")}
              </span>
            ) : null}
          </div>
          <CardTitle className="text-2xl">{message.subject ?? t("meta.noSubject")}</CardTitle>
          <div className="flex flex-wrap items-center gap-2 text-xs text-muted-foreground">
            <span>
              {counterpartLabel}: <span className="font-medium">{counterpart ?? t("meta.unknown")}</span>
            </span>
            <span>·</span>
            <span>{formatDate(message.createdAt)}</span>
            {message.readAt && isReceived ? (
              <>
                <span>·</span>
                <span>{t("meta.readAt", { date: formatDate(message.readAt) })}</span>
              </>
            ) : null}
          </div>
        </CardHeader>
        <CardContent>
          {/* P2-4: 已撤回消息显示占位文案，隐藏原始内容 */}
          {isRecalled ? (
            <p className="text-muted-foreground italic text-sm">{t("status.recalled")}</p>
          ) : (
            <p className="text-sm leading-relaxed whitespace-pre-wrap">{message.content}</p>
          )}
        </CardContent>
      </Card>

      {/* P1-3: 消息线程（回复链） */}
      <Card>
        <CardHeader>
          <CardTitle className="flex items-center gap-2 text-base">
            {t("thread.title")}
            {loadingThread ? (
              <Loader2 className="h-4 w-4 animate-spin" aria-hidden="true" />
            ) : (
              <span className="text-muted-foreground text-xs">
                {replies.length > 0
                  ? t("thread.replyCount", { count: replies.length })
                  : t("thread.noReplies")}
              </span>
            )}
          </CardTitle>
        </CardHeader>
        <CardContent className="space-y-3">
          {loadingThread ? null : replies.length === 0 ? (
            <p className="text-muted-foreground text-sm">{t("thread.noReplies")}</p>
          ) : (
            replies.map((reply) => {
              const replyIsReceived = reply.receiverId === currentUserId
              const replyCounterpart = replyIsReceived ? reply.senderName : reply.receiverName
              const replyIsSelf = reply.senderId === currentUserId
              const replyRecalled = reply.recalledAt !== null
              return (
                <div
                  key={reply.id}
                  className={cn(
                    "rounded-md border p-3",
                    replyIsSelf ? "border-primary/40 bg-primary/5" : "bg-muted/30"
                  )}
                >
                  <div className="mb-1 flex items-center justify-between gap-2 text-xs text-muted-foreground">
                    <span className="font-medium">
                      {replyIsSelf ? t("thread.you") : (replyCounterpart ?? t("meta.unknown"))}
                    </span>
                    <span>{formatDate(reply.createdAt)}</span>
                  </div>
                  {/* P2-4: 线程中已撤回回复显示占位文案 */}
                  {replyRecalled ? (
                    <p className="text-muted-foreground italic text-sm">{t("status.recalled")}</p>
                  ) : (
                    <p className="text-sm leading-relaxed whitespace-pre-wrap">{reply.content}</p>
                  )}
                </div>
              )
            })
          )}
        </CardContent>
      </Card>

      <ConfirmDeleteDialog
        open={deleteOpen}
        onOpenChange={setDeleteOpen}
        title={t("empty.deleteTitle")}
        description={t("empty.deleteDesc", { subject: message.subject ?? t("meta.noSubject") })}
        onConfirm={handleDelete}
        isWorking={isWorking}
      />

      {/* P2-4: 撤回确认对话框 */}
      <Dialog open={recallOpen} onOpenChange={setRecallOpen}>
        <DialogContent>
          <DialogHeader>
            <DialogTitle>{t("actions.recall")}</DialogTitle>
            <DialogDescription>{t("messages.recallConfirm")}</DialogDescription>
          </DialogHeader>
          <DialogFooter>
            <Button variant="outline" onClick={() => setRecallOpen(false)} disabled={isRecalling}>
              {t("actions.cancel")}
            </Button>
            <Button onClick={handleRecall} disabled={isRecalling}>
              {isRecalling ? (
                <Loader2 className="mr-2 h-4 w-4 animate-spin" aria-hidden="true" />
              ) : (
                <RotateCcw className="mr-2 h-4 w-4" aria-hidden="true" />
              )}
              {t("actions.recall")}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </div>
  )
}
