/**
 * PostsFeed — Renders a reverse-chronological feed of published posts
 * for a given creator. Used on the public creator profile page.
 */

import { useCallback, useEffect, useState } from "react";
import { generateHTML } from "@tiptap/html";
import StarterKit from "@tiptap/starter-kit";
import Link from "@tiptap/extension-link";
import {
  listPosts,
  getDownloadUrl,
  type PostRead,
} from "../api/posts";
import styles from "./PostsFeed.module.css";

// Tiptap extensions matching those in PostEditor — needed for generateHTML
const extensions = [StarterKit, Link];

function formatDate(iso: string): string {
  return new Date(iso).toLocaleDateString(undefined, {
    year: "numeric",
    month: "short",
    day: "numeric",
  });
}

function formatFileSize(bytes: number): string {
  if (bytes < 1024) return `${bytes} B`;
  if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
  return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
}

function FileIcon() {
  return (
    <svg className={styles.attachmentIcon} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
      <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" />
      <polyline points="7 10 12 15 17 10" />
      <line x1="12" y1="15" x2="12" y2="3" />
    </svg>
  );
}

function AttachmentButton({ attachment }: { attachment: PostRead["attachments"][number] }) {
  const [downloading, setDownloading] = useState(false);

  const handleDownload = useCallback(async () => {
    if (downloading) return;
    setDownloading(true);
    try {
      const { url } = await getDownloadUrl(String(attachment.id));
      window.open(url, "_blank", "noopener");
    } catch (err) {
      console.error("Download failed:", err);
    } finally {
      setDownloading(false);
    }
  }, [attachment.id, downloading]);

  return (
    <button className={styles.attachment} onClick={handleDownload} disabled={downloading}>
      <FileIcon />
      <span className={styles.attachmentName}>{attachment.filename}</span>
      <span className={styles.attachmentSize}>{formatFileSize(attachment.size_bytes)}</span>
    </button>
  );
}

function renderBody(bodyJson: Record<string, unknown>): string {
  try {
    return generateHTML(bodyJson as Parameters<typeof generateHTML>[0], extensions);
  } catch {
    // Fallback: if body_json isn't valid Tiptap JSON, try plain text
    return "<p>(Content unavailable)</p>";
  }
}

interface PostsFeedProps {
  creatorId: number | string;
}

export default function PostsFeed({ creatorId }: PostsFeedProps) {
  const [posts, setPosts] = useState<PostRead[]>([]);
  const [total, setTotal] = useState(0);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {
    let cancelled = false;
    setLoading(true);
    setError(null);

    listPosts(String(creatorId), 1, 50)
      .then((res) => {
        if (!cancelled) {
          setPosts(res.items);
          setTotal(res.total);
        }
      })
      .catch((err) => {
        if (!cancelled) {
          setError(err instanceof Error ? err.message : "Failed to load posts");
        }
      })
      .finally(() => {
        if (!cancelled) setLoading(false);
      });

    return () => { cancelled = true; };
  }, [creatorId]);

  if (loading) {
    return (
      <section className={styles.section}>
        <div className={styles.sectionHeader}>
          <h2 className={styles.sectionTitle}>Posts</h2>
        </div>
        <div className={styles.loading}>Loading posts…</div>
      </section>
    );
  }

  if (error) {
    return (
      <section className={styles.section}>
        <div className={styles.sectionHeader}>
          <h2 className={styles.sectionTitle}>Posts</h2>
        </div>
        <div className={styles.error}>{error}</div>
      </section>
    );
  }

  if (total === 0) {
    return null; // Don't show empty posts section on public profile
  }

  return (
    <section className={styles.section}>
      <div className={styles.sectionHeader}>
        <h2 className={styles.sectionTitle}>Posts</h2>
        <span className={styles.postCount}>({total})</span>
      </div>
      <div className={styles.feed}>
        {posts.map((post) => (
          <article key={post.id} className={styles.card}>
            <h3 className={styles.cardTitle}>{post.title}</h3>
            <div className={styles.cardMeta}>{formatDate(post.created_at)}</div>
            <div
              className={styles.cardBody}
              dangerouslySetInnerHTML={{ __html: renderBody(post.body_json) }}
            />
            {post.attachments.length > 0 && (
              <div className={styles.attachments}>
                {post.attachments.map((att) => (
                  <AttachmentButton key={att.id} attachment={att} />
                ))}
              </div>
            )}
          </article>
        ))}
      </div>
    </section>
  );
}
