"use client";

/**
 * Article comments section. Renders under every news + articles detail
 * page. Anonymous visitors see all comments + a "Sign in to comment"
 * CTA. Signed-in members get a composer + reply + vote affordances.
 *
 * Real users and seeded users (is_ai_seeded=true) participate in the same
 * thread with no visible difference to readers. The is_ai_seeded flag is
 * internal-only — kept for editorial accounting, never surfaced in the UI.
 */
import { useEffect, useMemo, useState } from "react";
import Link from "next/link";
import { createClient } from "@/lib/supabase/client";

type Comment = {
  id: string;
  article_slug: string;
  parent_comment_id: string | null;
  user_id: string | null;
  content: string;
  author_username: string | null;
  author_display_name: string | null;
  author_avatar_url: string | null;
  is_ai_seeded: boolean;
  upvotes: number;
  downvotes: number;
  vote_score: number;
  status: string;
  created_at: string;
};

interface Props {
  articleSlug: string;
}

function timeAgo(iso: string) {
  const t = Date.now() - new Date(iso).getTime();
  const m = Math.floor(t / 60000);
  if (m < 1) return "just now";
  if (m < 60) return `${m}m ago`;
  const h = Math.floor(m / 60);
  if (h < 24) return `${h}h ago`;
  const d = Math.floor(h / 24);
  if (d < 30) return `${d}d ago`;
  return new Date(iso).toLocaleDateString();
}

export default function ArticleComments({ articleSlug }: Props) {
  const supabase = createClient();
  const [user, setUser] = useState<{ id: string; email?: string } | null>(null);
  const [comments, setComments] = useState<Comment[]>([]);
  const [loading, setLoading] = useState(true);
  const [body, setBody] = useState("");
  const [replyTo, setReplyTo] = useState<string | null>(null);
  const [submitting, setSubmitting] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [myVotes, setMyVotes] = useState<Record<string, number>>({});

  // Hydrate user + comments
  useEffect(() => {
    supabase.auth.getUser().then(({ data }) => {
      setUser(data.user ? { id: data.user.id, email: data.user.email } : null);
    });
    fetchComments();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [articleSlug]);

  async function fetchComments() {
    setLoading(true);
    try {
      const r = await fetch(`/api/comments?article_slug=${encodeURIComponent(articleSlug)}`);
      const j = await r.json();
      if (Array.isArray(j.comments)) setComments(j.comments);
    } finally {
      setLoading(false);
    }
  }

  async function submit() {
    if (!body.trim()) return;
    if (!user) return;
    setSubmitting(true);
    setError(null);
    try {
      const r = await fetch("/api/comments", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          article_slug: articleSlug,
          content: body.trim(),
          parent_comment_id: replyTo,
        }),
      });
      const j = await r.json();
      if (!r.ok) {
        setError(j.error || "Failed to post comment");
      } else {
        setBody("");
        setReplyTo(null);
        await fetchComments();
      }
    } finally {
      setSubmitting(false);
    }
  }

  async function vote(commentId: string, value: 1 | -1) {
    if (!user) return;
    const current = myVotes[commentId] || 0;
    const next = current === value ? 0 : value;
    setMyVotes((m) => ({ ...m, [commentId]: next }));
    // Optimistic counter update
    setComments((cs) => cs.map((c) => {
      if (c.id !== commentId) return c;
      const upDelta = (next === 1 ? 1 : 0) - (current === 1 ? 1 : 0);
      const dnDelta = (next === -1 ? 1 : 0) - (current === -1 ? 1 : 0);
      return {
        ...c,
        upvotes: Math.max(0, c.upvotes + upDelta),
        downvotes: Math.max(0, c.downvotes + dnDelta),
        vote_score: c.vote_score + upDelta - dnDelta,
      };
    }));
    try {
      await fetch(`/api/comments/${commentId}/vote`, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ vote: next }),
      });
    } catch { /* swallow — UI already updated optimistically */ }
  }

  // Build threaded tree
  const tree = useMemo(() => {
    const roots: Comment[] = [];
    const childrenMap = new Map<string, Comment[]>();
    for (const c of comments) {
      if (c.parent_comment_id) {
        const arr = childrenMap.get(c.parent_comment_id) || [];
        arr.push(c);
        childrenMap.set(c.parent_comment_id, arr);
      } else {
        roots.push(c);
      }
    }
    return { roots, childrenMap };
  }, [comments]);

  const total = comments.length;

  return (
    <section className="mt-10 border-t border-[#DCE6F2] pt-8">
      <header className="flex items-center justify-between mb-5">
        <h2 className="font-heading text-white text-xl font-bold">
          Discussion {total > 0 && <span className="text-[#666] font-normal">· {total}</span>}
        </h2>
      </header>

      {/* Composer or sign-in CTA */}
      {user ? (
        <div className="bg-[#F8FAFC] border border-[#DCE6F2] rounded-md p-4 mb-6">
          {replyTo && (
            <div className="flex items-center justify-between mb-2 text-xs text-[#888]">
              <span>Replying to comment…</span>
              <button onClick={() => setReplyTo(null)} className="text-[#1D4ED8] hover:underline">Cancel reply</button>
            </div>
          )}
          <textarea
            value={body}
            onChange={(e) => setBody(e.target.value)}
            placeholder={replyTo ? "Write your reply…" : "Share your take on this story…"}
            rows={3}
            className="w-full bg-[#111] border border-[#DCE6F2] rounded text-white text-sm font-body p-2 resize-none focus:outline-none focus:border-[#1D4ED8]"
          />
          {error && <p className="text-[11px] text-red-400 mt-1">{error}</p>}
          <div className="flex items-center justify-between mt-2">
            <span className="text-[10px] text-[#666]">Markdown + image links supported · 5000 char max</span>
            <button
              onClick={submit}
              disabled={submitting || !body.trim()}
              className="bg-[#1D4ED8] hover:bg-[#1E3A8A] disabled:opacity-50 text-white font-body text-xs font-semibold px-4 py-1.5 rounded transition-colors"
            >
              {submitting ? "Posting…" : replyTo ? "Post reply" : "Post comment"}
            </button>
          </div>
        </div>
      ) : (
        <div className="brand-gradient rounded-md p-5 mb-6 text-center">
          <p className="text-white font-body text-sm mb-3">
            Sign in to join the discussion. Vote, reply, and follow industry conversations.
          </p>
          <div className="flex gap-3 justify-center">
            <Link
              href={`/forum/login?next=${encodeURIComponent(typeof window !== "undefined" ? window.location.pathname : "")}`}
              className="bg-white hover:bg-[#F1F5F9] text-[#0F172A] font-body text-xs font-semibold px-5 py-2 rounded transition-colors"
            >
              Sign in
            </Link>
            <Link
              href={`/forum/register?next=${encodeURIComponent(typeof window !== "undefined" ? window.location.pathname : "")}`}
              className="border border-white text-white hover:bg-white/10 font-body text-xs font-semibold px-5 py-2 rounded transition-colors"
            >
              Create account
            </Link>
          </div>
        </div>
      )}

      {/* Comment list */}
      {loading ? (
        <p className="text-[#666] text-sm">Loading comments…</p>
      ) : tree.roots.length === 0 ? (
        <p className="text-[#666] text-sm italic">No comments yet — be the first.</p>
      ) : (
        <ul className="space-y-5">
          {tree.roots.map((c) => (
            <CommentItem
              key={c.id}
              comment={c}
              children={tree.childrenMap.get(c.id) || []}
              canInteract={!!user}
              onReply={(id) => { setReplyTo(id); document.querySelector("textarea")?.focus(); }}
              onVote={vote}
              myVote={myVotes[c.id] || 0}
              myChildVotes={myVotes}
            />
          ))}
        </ul>
      )}
    </section>
  );
}

function CommentItem({
  comment, children, canInteract, onReply, onVote, myVote, myChildVotes,
}: {
  comment: Comment;
  children: Comment[];
  canInteract: boolean;
  onReply: (id: string) => void;
  onVote: (id: string, v: 1 | -1) => void;
  myVote: number;
  myChildVotes: Record<string, number>;
}) {
  return (
    <li className="bg-[#F8FAFC] border border-[#DCE6F2] rounded-md p-4">
      <header className="flex items-center gap-2 mb-2">
        {comment.author_avatar_url ? (
          /* eslint-disable-next-line @next/next/no-img-element */
          <img src={comment.author_avatar_url} alt="" className="w-7 h-7 rounded-full bg-[#FFFFFF] object-cover flex-shrink-0" />
        ) : (
          <div className="w-7 h-7 rounded-full bg-[#FFFFFF] text-[#1D4ED8] text-xs font-bold flex items-center justify-center flex-shrink-0">
            {(comment.author_display_name || "?").trim().charAt(0).toUpperCase()}
          </div>
        )}
        <div className="text-sm font-semibold text-white">
          {comment.author_display_name || "Member"}
        </div>
        <span className="text-[11px] text-[#666]">· {timeAgo(comment.created_at)}</span>
      </header>
      <div className="text-[#cbd5e1] text-sm whitespace-pre-wrap leading-relaxed">{comment.content}</div>
      <footer className="mt-2.5 flex items-center gap-3 text-xs">
        <div className="inline-flex items-center gap-1">
          <button
            disabled={!canInteract}
            onClick={() => onVote(comment.id, 1)}
            title={canInteract ? "Upvote" : "Sign in to vote"}
            className={`px-1.5 py-0.5 rounded text-base leading-none disabled:cursor-not-allowed disabled:opacity-50 ${
              myVote === 1 ? "text-emerald-400" : "text-[#666] hover:text-emerald-400"
            }`}
          >
            ▲
          </button>
          <span className="font-mono text-[#888] text-[11px] min-w-[18px] text-center">{comment.vote_score}</span>
          <button
            disabled={!canInteract}
            onClick={() => onVote(comment.id, -1)}
            title={canInteract ? "Downvote" : "Sign in to vote"}
            className={`px-1.5 py-0.5 rounded text-base leading-none disabled:cursor-not-allowed disabled:opacity-50 ${
              myVote === -1 ? "text-red-400" : "text-[#666] hover:text-red-400"
            }`}
          >
            ▼
          </button>
        </div>
        {canInteract && (
          <button onClick={() => onReply(comment.id)} className="text-[#1D4ED8] hover:underline text-[11px]">
            Reply
          </button>
        )}
      </footer>

      {children.length > 0 && (
        <ul className="mt-4 space-y-3 pl-5 border-l border-[#DCE6F2]">
          {children.map((kid) => (
            <CommentItem
              key={kid.id}
              comment={kid}
              children={[]}
              canInteract={canInteract}
              onReply={onReply}
              onVote={onVote}
              myVote={myChildVotes[kid.id] || 0}
              myChildVotes={myChildVotes}
            />
          ))}
        </ul>
      )}
    </li>
  );
}
