"use client";

import { useState, useEffect, useCallback } from "react";
import Link from "next/link";
import { ArrowLeft, Heart, Send } from "lucide-react";
import ReactMarkdown from "react-markdown";
import remarkGfm from "remark-gfm";
import { api } from "@/lib/api";
import { formatDate } from "@/lib/utils";
import { hasNostrExtension, getPublicKey, signEvent, publishEvent, shortenPubkey, fetchNostrProfile, fetchLongformFromRelays, fetchEventFromRelays, type NostrProfile } from "@/lib/nostr";
import { Navbar } from "@/components/public/Navbar";
import { Footer } from "@/components/public/Footer";
import type { Components } from "react-markdown";

interface Post {
  id: string;
  slug: string;
  title: string;
  content: string;
  excerpt?: string;
  authorName?: string;
  authorPubkey?: string;
  publishedAt?: string;
  createdAt?: string;
  nostrEventId?: string;
  naddr?: string;
  categories?: { category: { id: string; name: string; slug: string } }[];
}

interface NostrReply {
  id: string;
  pubkey: string;
  content: string;
  created_at: number;
}

const markdownComponents: Components = {
  h1: ({ children }) => (
    <h1 className="text-3xl font-bold text-on-surface mb-4 mt-10">{children}</h1>
  ),
  h2: ({ children }) => (
    <h2 className="text-2xl font-bold text-on-surface mb-4 mt-8">{children}</h2>
  ),
  h3: ({ children }) => (
    <h3 className="text-xl font-bold text-on-surface mb-3 mt-6">{children}</h3>
  ),
  h4: ({ children }) => (
    <h4 className="text-lg font-semibold text-on-surface mb-2 mt-4">{children}</h4>
  ),
  p: ({ children }) => (
    <p className="text-on-surface-variant leading-relaxed mb-6">{children}</p>
  ),
  a: ({ href, children }) => (
    <a
      href={href}
      className="text-primary hover:underline"
      target="_blank"
      rel="noopener noreferrer"
    >
      {children}
    </a>
  ),
  ul: ({ children }) => (
    <ul className="list-disc ml-6 mb-6 space-y-2 text-on-surface-variant">{children}</ul>
  ),
  ol: ({ children }) => (
    <ol className="list-decimal ml-6 mb-6 space-y-2 text-on-surface-variant">{children}</ol>
  ),
  li: ({ children }) => (
    <li className="leading-relaxed">{children}</li>
  ),
  blockquote: ({ children }) => (
    <blockquote className="border-l-4 border-primary/30 pl-4 italic text-on-surface-variant mb-6">
      {children}
    </blockquote>
  ),
  code: ({ className, children }) => {
    const isBlock = className?.includes("language-");
    if (isBlock) {
      return (
        <code className={`${className} block`}>
          {children}
        </code>
      );
    }
    return (
      <code className="bg-surface-container-high px-2 py-1 rounded text-sm text-primary">
        {children}
      </code>
    );
  },
  pre: ({ children }) => (
    <pre className="bg-surface-container-highest p-4 rounded-lg overflow-x-auto mb-6 text-sm">
      {children}
    </pre>
  ),
  img: ({ src, alt }) => (
    <img src={src} alt={alt || ""} className="rounded-lg max-w-full mb-6" />
  ),
  hr: () => <hr className="border-surface-container-high my-8" />,
  table: ({ children }) => (
    <div className="overflow-x-auto mb-6">
      <table className="w-full text-left text-on-surface-variant">{children}</table>
    </div>
  ),
  th: ({ children }) => (
    <th className="px-4 py-2 font-semibold text-on-surface bg-surface-container-high">
      {children}
    </th>
  ),
  td: ({ children }) => (
    <td className="px-4 py-2">{children}</td>
  ),
};

function ArticleSkeleton() {
  const widths = [85, 92, 78, 95, 88, 72, 90, 83];
  return (
    <div className="animate-pulse max-w-3xl mx-auto">
      <div className="flex gap-2 mb-6">
        <div className="h-5 w-20 bg-surface-container-high rounded-full" />
        <div className="h-5 w-16 bg-surface-container-high rounded-full" />
      </div>
      <div className="h-12 w-3/4 bg-surface-container-high rounded mb-4" />
      <div className="h-12 w-1/2 bg-surface-container-high rounded mb-8" />
      <div className="h-5 w-48 bg-surface-container-high rounded mb-16" />
      <div className="space-y-4">
        {widths.map((w, i) => (
          <div
            key={i}
            className="h-4 bg-surface-container-high rounded"
            style={{ width: `${w}%` }}
          />
        ))}
      </div>
    </div>
  );
}

export default function BlogPostClient({ slug }: { slug: string }) {
  const [post, setPost] = useState<Post | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [liked, setLiked] = useState(false);
  const [likeCount, setLikeCount] = useState(0);
  const [comment, setComment] = useState("");
  const [replies, setReplies] = useState<NostrReply[]>([]);
  const [hasNostr, setHasNostr] = useState(false);
  const [submitting, setSubmitting] = useState(false);
  const [authorProfile, setAuthorProfile] = useState<NostrProfile | null>(null);
  const [liveContent, setLiveContent] = useState<string | null>(null);
  const [loadingContent, setLoadingContent] = useState(false);

  useEffect(() => {
    setHasNostr(hasNostrExtension());
  }, []);

  useEffect(() => {
    if (!slug) return;
    setLoading(true);
    setError(null);
    setLiveContent(null);
    api
      .getPost(slug)
      .then((data) => {
        setPost(data);
        setLoading(false);
        if (data?.authorPubkey) {
          fetchNostrProfile(data.authorPubkey)
            .then((profile) => setAuthorProfile(profile))
            .catch(() => {});
        }
        if (!data?.content && (data?.naddr || data?.nostrEventId)) {
          setLoadingContent(true);
          const fetchPromise = data.naddr
            ? fetchLongformFromRelays(data.naddr)
            : fetchEventFromRelays(data.nostrEventId!);
          fetchPromise
            .then((event) => {
              if (event?.content) {
                setLiveContent(event.content);
              }
            })
            .catch(() => {})
            .finally(() => setLoadingContent(false));
        }
      })
      .catch((err) => {
        setError(err.message);
        setLoading(false);
      });
  }, [slug]);

  useEffect(() => {
    if (!slug) return;
    api.getPostReactions(slug)
      .then((data) => setLikeCount(data.count))
      .catch(() => {});

    api.getPostReplies(slug)
      .then((data) => setReplies(data.replies || []))
      .catch(() => {});
  }, [slug]);

  const handleLike = useCallback(async () => {
    if (liked || !post?.nostrEventId || !hasNostr) return;
    try {
      const pubkey = await getPublicKey();
      const reactionEvent = {
        kind: 7,
        created_at: Math.floor(Date.now() / 1000),
        tags: [["e", post.nostrEventId], ["p", post.authorPubkey || ""]],
        content: "+",
        pubkey,
      };
      const signedReaction = await signEvent(reactionEvent);
      await publishEvent(signedReaction);
      setLiked(true);
      setLikeCount((c) => c + 1);
    } catch {
      // User rejected or extension unavailable
    }
  }, [liked, post, hasNostr]);

  const handleComment = useCallback(async () => {
    if (!comment.trim() || !post?.nostrEventId || !hasNostr) return;
    setSubmitting(true);
    try {
      const pubkey = await getPublicKey();
      const replyEvent = {
        kind: 1,
        created_at: Math.floor(Date.now() / 1000),
        tags: [["e", post.nostrEventId, "", "reply"], ["p", post.authorPubkey || ""]],
        content: comment.trim(),
        pubkey,
      };
      const signed = await signEvent(replyEvent);
      await publishEvent(signed);
      setReplies((prev) => [
        ...prev,
        {
          id: signed.id || Date.now().toString(),
          pubkey,
          content: comment.trim(),
          created_at: Math.floor(Date.now() / 1000),
        },
      ]);
      setComment("");
    } catch {
      // User rejected or extension unavailable
    } finally {
      setSubmitting(false);
    }
  }, [comment, post, hasNostr]);

  const categories = post?.categories?.map((c) => c.category) || [];

  return (
    <>
      <Navbar />

      <div className="min-h-screen">
        <div className="max-w-3xl mx-auto px-8 pt-12 pb-24">
          <Link
            href="/blog"
            className="inline-flex items-center gap-2 text-on-surface-variant hover:text-primary transition-colors mb-12 text-sm font-medium"
          >
            <ArrowLeft size={16} />
            Back to Blog
          </Link>

          {loading && <ArticleSkeleton />}

          {error && (
            <div className="bg-error-container/20 text-error rounded-xl p-6">
              Failed to load post: {error}
            </div>
          )}

          {!loading && !error && post && (
            <>
              <header className="mb-16">
                {categories.length > 0 && (
                  <div className="flex flex-wrap gap-2 mb-6">
                    {categories.map((cat) => (
                      <span
                        key={cat.id}
                        className="px-3 py-1 text-xs font-bold uppercase tracking-widest text-primary bg-primary/10 rounded-full"
                      >
                        {cat.name}
                      </span>
                    ))}
                  </div>
                )}

                <h1 className="text-4xl md:text-5xl font-black tracking-tight leading-tight mb-6">
                  {post.title}
                </h1>

                <div className="flex items-center gap-3 text-sm text-on-surface-variant/60">
                  {(authorProfile || post.authorName || post.authorPubkey) && (
                    <div className="flex items-center gap-2.5">
                      {authorProfile?.picture && (
                        <img
                          src={authorProfile.picture}
                          alt={authorProfile.name || post.authorName || "Author"}
                          className="w-8 h-8 rounded-full object-cover bg-zinc-800 shrink-0"
                          onError={(e) => { (e.target as HTMLImageElement).style.display = "none"; }}
                        />
                      )}
                      <span className="font-medium text-on-surface-variant">
                        {authorProfile?.name || post.authorName || shortenPubkey(post.authorPubkey!)}
                      </span>
                    </div>
                  )}
                  {(post.publishedAt || post.createdAt) && (
                    <>
                      {(authorProfile || post.authorName || post.authorPubkey) && (
                        <span className="text-on-surface-variant/30">·</span>
                      )}
                      <span>
                        {formatDate(post.publishedAt || post.createdAt!)}
                      </span>
                    </>
                  )}
                </div>
              </header>

              <article className="mb-16">
                {loadingContent ? (
                  <div className="animate-pulse space-y-4">
                    {[85, 92, 78, 95, 88, 72, 90, 83].map((w, i) => (
                      <div
                        key={i}
                        className="h-4 bg-surface-container-high rounded"
                        style={{ width: `${w}%` }}
                      />
                    ))}
                  </div>
                ) : (
                  <ReactMarkdown
                    remarkPlugins={[remarkGfm]}
                    components={markdownComponents}
                  >
                    {post.content || liveContent || ""}
                  </ReactMarkdown>
                )}
              </article>

              <section className="bg-surface-container-low rounded-xl p-8 mb-16">
                <div className="flex items-center gap-6 mb-8">
                  <button
                    onClick={handleLike}
                    disabled={!hasNostr}
                    title={hasNostr ? "Like this post" : "Install a Nostr extension to interact"}
                    className={`flex items-center gap-2 px-4 py-2 rounded-lg transition-colors ${
                      liked
                        ? "bg-primary/20 text-primary"
                        : hasNostr
                          ? "bg-surface-container-high text-on-surface hover:bg-surface-bright"
                          : "bg-surface-container-high text-on-surface/40 cursor-not-allowed"
                    }`}
                  >
                    <Heart size={18} fill={liked ? "currentColor" : "none"} />
                    <span className="font-semibold">{likeCount}</span>
                  </button>
                  {!hasNostr && (
                    <span className="text-on-surface-variant/50 text-xs">
                      Install a Nostr extension to like and comment
                    </span>
                  )}
                </div>

                <h3 className="text-lg font-bold mb-6">
                  Comments {replies.length > 0 && `(${replies.length})`}
                </h3>

                {hasNostr && (
                  <div className="flex gap-3 mb-8">
                    <textarea
                      value={comment}
                      onChange={(e) => setComment(e.target.value)}
                      placeholder="Share your thoughts..."
                      rows={3}
                      className="flex-1 bg-surface-container-highest text-on-surface rounded-lg p-4 resize-none placeholder:text-on-surface-variant/40 focus:outline-none focus:ring-1 focus:ring-primary/40"
                    />
                    <button
                      onClick={handleComment}
                      disabled={!comment.trim() || submitting}
                      className="self-end px-4 py-3 bg-primary text-on-primary rounded-lg font-semibold hover:scale-105 transition-transform disabled:opacity-30 disabled:cursor-not-allowed"
                    >
                      <Send size={18} />
                    </button>
                  </div>
                )}

                {replies.length > 0 ? (
                  <div className="space-y-6">
                    {replies.map((r) => (
                      <div
                        key={r.id}
                        className="bg-surface-container-high rounded-lg p-4"
                      >
                        <div className="flex items-center gap-2.5 mb-2">
                          <span className="font-semibold text-xs font-mono text-on-surface-variant/70">
                            {shortenPubkey(r.pubkey)}
                          </span>
                          <span className="text-on-surface-variant/30">·</span>
                          <span className="text-xs text-on-surface-variant/50">
                            {formatDate(new Date(r.created_at * 1000))}
                          </span>
                        </div>
                        <p className="text-on-surface-variant text-sm leading-relaxed">
                          {r.content}
                        </p>
                      </div>
                    ))}
                  </div>
                ) : (
                  <p className="text-on-surface-variant/50 text-sm">
                    No comments yet. Be the first to share your thoughts.
                  </p>
                )}
              </section>
            </>
          )}
        </div>
      </div>

      <Footer />
    </>
  );
}
