"use client"

import { useEffect, useMemo, useState } from "react"
import Link from "next/link"
import { Mail, MailOpen, Plus, Send, Inbox, Search, Loader2 } from "lucide-react"
import { useTranslations } from "next-intl"

import { Badge } from "@/shared/components/ui/badge"
import { Button } from "@/shared/components/ui/button"
import { Card, CardContent, CardHeader } from "@/shared/components/ui/card"
import { EmptyState } from "@/shared/components/ui/empty-state"
import { Input } from "@/shared/components/ui/input"
import { Tabs, TabsList, TabsTrigger } from "@/shared/components/ui/tabs"
import { cn, formatDate } from "@/shared/lib/utils"
import { usePermission } from "@/shared/hooks/use-permission"
import { Permissions } from "@/shared/types/permissions"

import { getMessagesAction } from "../actions"
import type { Message, MessageType } from "../types"

type Tab = "inbox" | "sent"

export function MessageList({
  messages,
  currentUserId,
  initialType = "inbox",
}: {
  messages: Message[]
  currentUserId: string
  initialType?: MessageType
}) {
  const t = useTranslations("messages")
  const [tab, setTab] = useState<Tab>(initialType === "sent" ? "sent" : "inbox")
  const [keyword, setKeyword] = useState("")
  const [searchResults, setSearchResults] = useState<{ kw: string; tab: Tab; items: Message[] } | null>(null)
  const { hasPermission } = usePermission()
  const canSend = hasPermission(Permissions.MESSAGE_SEND)

  // 防抖搜索：keyword 或 tab 变化时调用 getMessagesAction
  useEffect(() => {
    const kw = keyword.trim()
    if (kw.length === 0) {
      return
    }

    let cancelled = false
    const timer = setTimeout(async () => {
      if (cancelled) return
      const res = await getMessagesAction({ type: tab, keyword: kw })
      if (cancelled) return
      if (res.success && res.data) {
        setSearchResults({ kw, tab, items: res.data.items })
      }
    }, 400)

    return () => {
      cancelled = true
      clearTimeout(timer)
    }
  }, [keyword, tab])

  // 当前搜索结果是否匹配最新的 keyword 和 tab
  const currentResults = searchResults && searchResults.kw === keyword.trim() && searchResults.tab === tab
    ? searchResults.items
    : null

  // 搜索中：keyword 非空且尚无匹配结果
  const searching = keyword.trim().length > 0 && currentResults === null

  // 当 keyword 为空时使用 prop messages，否则使用搜索结果
  const displayMessages = currentResults ?? messages

  const filtered = useMemo(() => {
    if (tab === "inbox") return displayMessages.filter((m) => m.receiverId === currentUserId)
    return displayMessages.filter((m) => m.senderId === currentUserId)
  }, [displayMessages, tab, currentUserId])

  return (
    <div className="space-y-6">
      <div className="flex flex-wrap items-center justify-between gap-3">
        <Tabs value={tab} onValueChange={(v) => setTab(v as Tab)}>
          <TabsList>
            <TabsTrigger value="inbox" className="gap-2">
              <Inbox className="h-4 w-4" />
              {t("tabs.inbox")}
            </TabsTrigger>
            <TabsTrigger value="sent" className="gap-2">
              <Send className="h-4 w-4" />
              {t("tabs.sent")}
            </TabsTrigger>
          </TabsList>
        </Tabs>
        {canSend ? (
          <Button asChild>
            <Link href="/messages/compose">
              <Plus className="mr-2 h-4 w-4" />
              {t("actions.compose")}
            </Link>
          </Button>
        ) : null}
      </div>

      {/* 搜索框 */}
      <div className="relative">
        <Search className="text-muted-foreground absolute left-3 top-1/2 size-4 -translate-y-1/2" aria-hidden="true" />
        <Input
          type="search"
          aria-label={t("search.placeholder")}
          placeholder={t("search.placeholder")}
          value={keyword}
          onChange={(e) => setKeyword(e.target.value)}
          className="pl-9"
        />
        {searching ? (
          <Loader2 className="text-muted-foreground absolute right-3 top-1/2 size-4 -translate-y-1/2 animate-spin" aria-hidden="true" />
        ) : null}
      </div>

      {filtered.length === 0 ? (
        <EmptyState
          title={tab === "inbox" ? t("empty.inboxEmpty") : t("empty.sentEmpty")}
          description={
            tab === "inbox"
              ? t("empty.inboxEmptyDesc")
              : t("empty.sentEmptyDesc")
          }
          icon={Mail}
          className="h-auto border-none shadow-none"
        />
      ) : (
        <div className="space-y-3">
          {filtered.map((m) => {
            const isReceived = m.receiverId === currentUserId
            const counterpart = isReceived ? m.senderName : m.receiverName
            const unread = isReceived && !m.isRead
            return (
              <Link key={m.id} href={`/messages/${m.id}`} className="block" aria-label={m.subject ?? t("meta.noSubject")}>
                <Card className={cn("transition-colors hover:bg-accent/50", unread && "border-primary/40")}>
                  <CardHeader className="flex flex-row items-start justify-between gap-2 space-y-0 pb-3">
                    <div className="space-y-1">
                      <div className="flex items-center gap-2">
                        {unread ? (
                          <Mail className="h-4 w-4 text-primary" aria-hidden="true" />
                        ) : (
                          <MailOpen className="text-muted-foreground h-4 w-4" aria-hidden="true" />
                        )}
                        <span className={cn("text-sm font-medium", unread && "text-primary")}>
                          {m.subject ?? t("meta.noSubject")}
                        </span>
                        {unread ? <Badge variant="default" className="text-xs">{t("status.new")}</Badge> : null}
                      </div>
                      <p className="text-muted-foreground text-xs">
                        {isReceived ? t("meta.from") : t("meta.to")}: {counterpart ?? t("meta.unknown")}
                      </p>
                    </div>
                    <span className="text-muted-foreground shrink-0 text-xs">
                      {formatDate(m.createdAt)}
                    </span>
                  </CardHeader>
                  <CardContent className="pt-0">
                    <p className="text-muted-foreground line-clamp-2 text-sm whitespace-pre-wrap">
                      {m.content}
                    </p>
                  </CardContent>
                </Card>
              </Link>
            )
          })}
        </div>
      )}
    </div>
  )
}
