"use client";

import { ReactNode, useMemo } from "react";
import type { SocialPollData } from "@/components/social/social-types";
import { VoiceMessagePlayer } from "@/components/social/SocialVoiceRecorder";

function renderBody(body: string, onTagClick?: (raw: string) => void) {
  const parts: ReactNode[] = [];
  const regex = /([@#][\w\u0600-\u06FF]+)/g;
  let last = 0;
  let match: RegExpExecArray | null;
  let key = 0;
  while ((match = regex.exec(body))) {
    if (match.index > last) parts.push(body.slice(last, match.index));
    const raw = match[1];
    parts.push(
      <button
        key={`t-${key++}`}
        type="button"
        className="font-semibold text-sky-600 hover:underline"
        onClick={() => onTagClick?.(raw)}
      >
        {raw}
      </button>,
    );
    last = match.index + raw.length;
  }
  if (last < body.length) parts.push(body.slice(last));
  return parts;
}

export type SocialPost = {
  id: number;
  body: string;
  post_type: string;
  is_pinned: boolean;
  view_count: number;
  created_at?: string | null;
  meta?: Record<string, unknown> | null;
  author: { id?: number | null; name: string };
  reply_to?: { id: number; body: string; author_name: string } | null;
  mentions?: Array<{ raw: string }>;
  attachments?: Array<{
    id: number;
    original_name: string;
    url: string;
    mime?: string | null;
    duration_seconds?: number | null;
  }>;
  poll?: SocialPollData | null;
  reactions?: Array<{ emoji: string; count: number }>;
};

function formatTime(iso?: string | null) {
  if (!iso) return "";
  try {
    return new Date(iso).toLocaleTimeString("fa-IR", {
      hour: "2-digit",
      minute: "2-digit",
      hour12: false,
      hourCycle: "h23",
    });
  } catch {
    return "";
  }
}

function isImageMime(mime?: string | null) {
  return mime?.startsWith("image/") ?? false;
}

function isVideoMime(mime?: string | null) {
  return mime?.startsWith("video/") ?? false;
}

function isAudioMime(mime?: string | null) {
  return mime?.startsWith("audio/") ?? false;
}

function PollBlock({
  poll,
  onVote,
  voting,
}: {
  poll: SocialPollData;
  onVote?: (optionId: number) => void;
  voting?: boolean;
}) {
  const voted = poll.my_option_id != null;

  return (
    <div className="mb-2 overflow-hidden rounded-xl border border-amber-100 bg-amber-50/50">
      <div className="border-b border-amber-100/80 px-3 py-2 text-sm font-bold text-slate-800">{poll.question}</div>
      <div className="space-y-1 p-2">
        {poll.options.map((opt) => {
          const selected = poll.my_option_id === opt.id;
          return (
            <button
              key={opt.id}
              type="button"
              disabled={voting || poll.is_closed}
              onClick={() => onVote?.(opt.id)}
              className={`relative w-full overflow-hidden rounded-lg border px-3 py-2 text-right text-sm transition ${
                selected
                  ? "border-teal-400 bg-teal-50 font-semibold text-teal-900"
                  : "border-transparent bg-white/80 hover:border-amber-200 hover:bg-white"
              } ${poll.is_closed ? "cursor-default" : ""}`}
            >
              {voted ? (
                <span
                  className="absolute inset-y-0 right-0 bg-teal-100/80 transition-all"
                  style={{ width: `${opt.percent}%` }}
                  aria-hidden
                />
              ) : null}
              <span className="relative flex items-center justify-between gap-2">
                <span>{opt.label}</span>
                {voted ? (
                  <span className="shrink-0 text-xs tabular-nums text-slate-500">
                    {opt.percent}% · {opt.votes_count}
                  </span>
                ) : null}
              </span>
            </button>
          );
        })}
      </div>
      <div className="border-t border-amber-100/80 px-3 py-1.5 text-[10px] text-slate-500">
        📊 {poll.total_votes} رأی
        {poll.is_closed ? " · بسته شده" : voted ? " · رأی شما ثبت شد" : " · برای رأی دادن یک گزینه را انتخاب کنید"}
      </div>
    </div>
  );
}

export function SocialMessageBubble({
  post,
  onOpenMenu,
  onTagClick,
  onVotePoll,
  votingPollId,
}: {
  post: SocialPost;
  onOpenMenu: (post: SocialPost, el: HTMLElement) => void;
  onTagClick?: (raw: string) => void;
  onVotePoll?: (postId: number, optionId: number) => void;
  votingPollId?: number | null;
}) {
  const isSystem = post.post_type === "system" || post.post_type === "roll_call_notice";
  const isVoice = post.post_type === "voice";
  const hideBody = isVoice && post.body === "🎤 پیام صوتی";

  const body = useMemo(() => renderBody(post.body, onTagClick), [post.body, onTagClick]);

  const audioAttachment = post.attachments?.find((a) => isAudioMime(a.mime) || isVoice);

  return (
    <article
      className={`group relative max-w-[min(560px,92%)] rounded-2xl rounded-br-md px-3.5 py-2.5 shadow-sm ring-1 ring-black/[0.04] ${
        isSystem ? "border border-teal-100 bg-teal-50/95" : "bg-white/95 backdrop-blur-[2px]"
      }`}
      onContextMenu={(e) => {
        e.preventDefault();
        onOpenMenu(post, e.currentTarget);
      }}
    >
      {!isSystem ? (
        <div className="mb-1 text-xs font-bold text-teal-700">{post.author.name}</div>
      ) : (
        <div className="mb-1 text-xs font-bold text-teal-800">سامانه</div>
      )}

      {post.reply_to ? (
        <div className="mb-2 rounded-lg border-r-4 border-teal-500 bg-slate-50/90 px-2.5 py-1.5 text-xs text-slate-600">
          <div className="font-semibold text-slate-700">{post.reply_to.author_name}</div>
          <div className="line-clamp-2">{post.reply_to.body}</div>
        </div>
      ) : null}

      {post.poll ? (
        <PollBlock poll={post.poll} onVote={(id) => onVotePoll?.(post.id, id)} voting={votingPollId === post.id} />
      ) : null}

      {audioAttachment ? (
        <div className="mb-2">
          <VoiceMessagePlayer url={audioAttachment.url} durationSeconds={audioAttachment.duration_seconds} />
        </div>
      ) : null}

      {post.attachments?.length && !audioAttachment ? (
        <div className="mb-2 space-y-2">
          {post.attachments.map((a) =>
            isImageMime(a.mime) ? (
              <a key={a.id} href={a.url} target="_blank" rel="noreferrer" className="block overflow-hidden rounded-xl">
                {/* eslint-disable-next-line @next/next/no-img-element */}
                <img src={a.url} alt={a.original_name} className="max-h-64 w-full object-cover" />
              </a>
            ) : isVideoMime(a.mime) ? (
              <video key={a.id} src={a.url} controls className="max-h-64 w-full rounded-xl bg-black/5" />
            ) : isAudioMime(a.mime) ? (
              <VoiceMessagePlayer key={a.id} url={a.url} durationSeconds={a.duration_seconds} />
            ) : (
              <a
                key={a.id}
                href={a.url}
                target="_blank"
                rel="noreferrer"
                className="flex items-center gap-2 rounded-xl border border-slate-100 bg-slate-50 px-3 py-2 text-xs text-slate-700 hover:bg-slate-100"
              >
                <span className="flex h-9 w-9 shrink-0 items-center justify-center rounded-lg bg-sky-100 text-sky-600">
                  <svg viewBox="0 0 24 24" className="h-5 w-5" fill="currentColor" aria-hidden>
                    <path d="M14 2H6c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V8l-6-6zm4 18H6V4h7v5h5v11z" />
                  </svg>
                </span>
                <span className="min-w-0 truncate font-medium">{a.original_name}</span>
              </a>
            ),
          )}
        </div>
      ) : null}

      {post.body.trim() && !hideBody && post.post_type !== "poll" ? (
        <div className="whitespace-pre-wrap text-sm leading-7 text-slate-800">{body}</div>
      ) : null}

      {post.meta && typeof post.meta.href === "string" ? (
        <div className="mt-2 overflow-hidden rounded-xl border border-teal-100 bg-gradient-to-l from-teal-50 to-white">
          {typeof post.meta.card_title === "string" ? (
            <div className="border-b border-teal-100/80 px-3 py-2 text-xs font-semibold text-slate-700">
              {String(post.meta.card_title)}
            </div>
          ) : null}
          <div className="px-3 py-2">
            <a
              href={String(post.meta.href)}
              className="inline-flex items-center gap-1.5 rounded-lg bg-teal-600 px-3 py-1.5 text-xs font-semibold text-white hover:bg-teal-700"
            >
              {post.meta.kind === "class_resource" ? "دریافت منبع" : "مشاهده"}
              <span aria-hidden>←</span>
            </a>
          </div>
        </div>
      ) : null}

      <div className="mt-2 flex items-center justify-between gap-2 text-[11px] text-slate-400">
        <div className="flex items-center gap-2">
          <span className="tabular-nums">{formatTime(post.created_at)}</span>
          {post.view_count > 0 ? <span>👁 {post.view_count}</span> : null}
          {post.is_pinned ? <span title="سنجاق شده">📌</span> : null}
        </div>
        <button
          type="button"
          className="rounded-md px-1.5 py-0.5 opacity-0 transition group-hover:opacity-100 hover:bg-slate-100"
          onClick={(e) => onOpenMenu(post, e.currentTarget)}
        >
          ⋮
        </button>
      </div>
    </article>
  );
}
