import { useMemo, useState, type ReactNode } from "react";
import { OwnPostPerformanceItem, ThreadsReply } from "../../api/haixun";
import { MentionProfileLookup } from "../../components/MentionProfileLookup";
import { Badge, Button, Textarea } from "../../components/ui";
import { shortText } from "../../lib/format";
import { replyMediaPreviews } from "../../lib/replyMedia";
import {
  buildReplyTree,
  countPendingThreads,
  describeReplyTarget,
  flattenThread,
  formatReplyRelation,
  hasOwnReplyTo,
  isOwnReply,
  needsMyReply,
  replyLane,
  ReplyTreeNode,
  threadHasPending
} from "../../lib/replyTree";

type InboxFilter = "pending" | "all" | "answered";

type Props = {
  accountId: string;
  post: OwnPostPerformanceItem;
  replies: ThreadsReply[];
  accountUsername?: string;
  replyTextByKey: Record<string, string>;
  generatingKey: string;
  publishingKey: string;
  selectedPersonaId: string;
  onReplyTextChange: (key: string, value: string) => void;
  onGenerate: (key: string, reply: ThreadsReply) => void;
  onPublish: (key: string, replyToId: string) => void;
};

export function ReplyInboxPanel({
  accountId,
  post,
  replies,
  accountUsername,
  replyTextByKey,
  generatingKey,
  publishingKey,
  selectedPersonaId,
  onReplyTextChange,
  onGenerate,
  onPublish
}: Props) {
  const [filter, setFilter] = useState<InboxFilter>("pending");

  const replyById = useMemo(() => new Map(replies.map((reply) => [reply.id, reply])), [replies]);
  const replyTree = useMemo(() => buildReplyTree(replies, post.media_id), [replies, post.media_id]);
  const pendingCount = useMemo(() => countPendingThreads(replyTree, replies, accountUsername), [replyTree, replies, accountUsername]);

  const visibleThreads = useMemo(() => {
    return replyTree.filter((root) => {
      if (filter === "pending") return threadHasPending(root, replies, accountUsername);
      if (filter === "answered") return !threadHasPending(root, replies, accountUsername) && !isOwnReply(root, accountUsername);
      return true;
    });
  }, [filter, replyTree, replies, accountUsername]);

  const [expanded, setExpanded] = useState<Record<string, boolean>>({});
  const isExpanded = (id: string, pending: boolean) => expanded[id] ?? pending;

  if (!replies.length) {
    return <p className="muted">這篇目前沒有留言。</p>;
  }

  const mineName = accountUsername ? `@${accountUsername.replace(/^@/, "")}` : "你";

  return (
    <div className="hx-reply-feed">
      <div className="hx-reply-feed__toolbar">
        <FilterChip active={filter === "pending"} count={pendingCount} onClick={() => setFilter("pending")}>待回覆</FilterChip>
        <FilterChip active={filter === "all"} count={replyTree.length} onClick={() => setFilter("all")}>全部</FilterChip>
        <FilterChip
          active={filter === "answered"}
          count={replyTree.filter((root) => !threadHasPending(root, replies, accountUsername) && !isOwnReply(root, accountUsername)).length}
          onClick={() => setFilter("answered")}
        >
          已回覆
        </FilterChip>
      </div>

      {visibleThreads.length === 0 ? (
        <p className="muted hx-reply-feed__empty">沒有符合篩選的留言。</p>
      ) : (
        <div className="hx-reply-feed__list">
          {visibleThreads.map((root) => {
            const pending = threadHasPending(root, replies, accountUsername);
            const open = isExpanded(root.id, pending);
            const replyTarget = pickReplyTarget(root, replies, accountUsername);
            const replyTargetLane = replyTarget ? replyLane(replyTarget, replyById, accountUsername) : null;
            const context = describeReplyTarget(root, post.media_id, post.text || "", replyById, accountUsername);

            return (
              <section key={root.id} className={`hx-reply-feed__thread ${pending ? "is-pending" : ""}`}>
                <button
                  type="button"
                  className="hx-reply-feed__thread-head"
                  onClick={() => setExpanded((current) => ({ ...current, [root.id]: !open }))}
                >
                  <span className="hx-reply-feed__thread-main">
                    <strong>{root.username ? `@${root.username}` : "訪客"}</strong>
                    <span className="hx-reply-feed__sep">·</span>
                    <span className="muted hx-reply-feed__thread-context">{contextLabel(context)}</span>
                  </span>
                  <span className="hx-reply-feed__thread-meta">
                    {pending ? <Badge variant="warning">待回覆</Badge> : <Badge variant="neutral">已處理</Badge>}
                    <span className="muted hx-text-sm">{formatReplyTime(root.timestamp)}</span>
                    <span className="hx-reply-feed__chevron">{open ? "▾" : "▸"}</span>
                  </span>
                </button>

                {open ? (
                  <div className="hx-reply-feed__thread-body">
                    <ReplyFeedItems
                      nodes={flattenThread(root)}
                      post={post}
                      replies={replies}
                      replyById={replyById}
                      accountUsername={accountUsername}
                      mineName={mineName}
                    />

                    {replyTarget ? (
                      <div className="hx-reply-feed__composer">
                        <p className="muted hx-text-sm">
                          回覆 {replyTarget.username ? `@${replyTarget.username}` : "這則留言"}
                          {replyTargetLane === "asking_me" ? "（在問你）" : ""}
                        </p>
                        <Textarea
                          value={replyTextByKey[`reply:${replyTarget.id}`] || ""}
                          onChange={(e) => onReplyTextChange(`reply:${replyTarget.id}`, e.target.value)}
                          placeholder="輸入回覆...（可輸入 @帳號 查詢對方）"
                        />
                        <MentionProfileLookup
                          accountId={accountId}
                          text={replyTextByKey[`reply:${replyTarget.id}`] || ""}
                          label="留言中的 @ 提及"
                        />
                        <div className="button-row">
                          <Button
                            variant="soft"
                            loading={generatingKey === `reply:${replyTarget.id}`}
                            disabled={!selectedPersonaId}
                            onClick={() => onGenerate(`reply:${replyTarget.id}`, replyTarget)}
                          >
                            AI 生成
                          </Button>
                          <Button
                            variant="primary"
                            loading={publishingKey === `reply:${replyTarget.id}`}
                            disabled={!replyTextByKey[`reply:${replyTarget.id}`]?.trim()}
                            onClick={() => onPublish(`reply:${replyTarget.id}`, replyTarget.id)}
                          >
                            發送回覆
                          </Button>
                        </div>
                      </div>
                    ) : null}
                  </div>
                ) : null}
              </section>
            );
          })}
        </div>
      )}
    </div>
  );
}

function FilterChip({ active, count, onClick, children }: { active: boolean; count: number; onClick: () => void; children: ReactNode }) {
  return (
    <button type="button" className={`hx-reply-filter ${active ? "is-active" : ""}`} onClick={onClick}>
      {children}
      <span className="hx-reply-filter__count">{count}</span>
    </button>
  );
}

function contextLabel(context: ReturnType<typeof describeReplyTarget>) {
  if (context.kind === "post") return "留言在你的貼文";
  if (context.kind === "me") return "在問你";
  return context.label;
}

function formatReplyTime(value?: string) {
  const raw = (value || "").trim();
  if (!raw) return "";
  const ms = Date.parse(raw);
  if (!Number.isFinite(ms)) return raw;
  return new Date(ms).toLocaleString("zh-TW", { month: "numeric", day: "numeric", hour: "2-digit", minute: "2-digit" });
}

function pickReplyTarget(root: ReplyTreeNode, replies: ThreadsReply[], accountUsername?: string): ThreadsReply | null {
  for (const node of flattenThread(root)) {
    if (needsMyReply(node, replies, accountUsername)) return node;
  }
  return null;
}

function ReplyFeedItems({
  nodes,
  post,
  replies,
  replyById,
  accountUsername,
  mineName
}: {
  nodes: ReplyTreeNode[];
  post: OwnPostPerformanceItem;
  replies: ThreadsReply[];
  replyById: Map<string, ThreadsReply>;
  accountUsername?: string;
  mineName: string;
}) {
  return (
    <div className="hx-reply-feed__items">
      {nodes.map((node) => {
        const lane = replyLane(node, replyById, accountUsername);
        const mine = lane === "mine";
        const relation = formatReplyRelation(node, post.media_id, replyById, accountUsername);
        const answered = !mine && hasOwnReplyTo(replies, node.id, accountUsername);
        const mediaItems = replyMediaPreviews(node);

        return (
          <div
            key={node.id}
            className={`hx-reply-feed__item hx-reply-feed__item--${lane}`}
            style={{ paddingLeft: `${8 + Math.min(node.depth, 3) * 14}px` }}
          >
            <div className="hx-reply-feed__item-head">
              <span>{mine ? mineName : node.username ? `@${node.username}` : "訪客"}</span>
              {relation ? <span className="muted hx-text-sm hx-reply-feed__relation">{relation}</span> : null}
              {node.timestamp ? <span className="muted hx-text-xs">{formatReplyTime(node.timestamp)}</span> : null}
              {mediaItems.length === 1 ? <span className="hx-reply-feed__tag">{mediaItems[0].label}</span> : null}
              {mediaItems.length > 1 ? <span className="hx-reply-feed__tag">{mediaItems.length} 張</span> : null}
              {answered ? <span className="hx-reply-feed__tag">已回</span> : null}
            </div>
            {node.text ? <p className="hx-reply-feed__item-text">{node.text}</p> : null}
            {mediaItems.length > 0 ? (
              <div className={`hx-reply-feed__media-grid ${mediaItems.length === 1 ? "is-single" : ""}`}>
                {mediaItems.map((media, index) => (
                  <a
                    key={`${node.id}-media-${index}`}
                    href={node.permalink || media.src}
                    target="_blank"
                    rel="noreferrer"
                    className="hx-reply-feed__media"
                  >
                    <img src={media.src} alt={media.label} loading="lazy" />
                    {media.kind === "video" ? <span className="hx-reply-feed__media-badge">▶ 影片</span> : null}
                    {mediaItems.length > 1 ? <span className="hx-reply-feed__media-badge">{media.label}</span> : null}
                  </a>
                ))}
              </div>
            ) : null}
          </div>
        );
      })}
    </div>
  );
}