import { useEffect, useState } from "react";
import { Link } from "react-router-dom";

function getImageFilename(post) {
  return post.image || post.image_filename || post.filename || null;
}

function getAuthorName(post, authorId) {
  return post.author?.name || post.author_name || (post.author_username ? `@${post.author_username}` : `User ${authorId || ""}`);
}

function getAuthorUsername(post) {
  return post.author_username || post.author?.username || null;
}

function getInitials(name) {
  if (!name) return "?";
  const cleaned = name.replace(/^@/, "");
  return cleaned
    .split(" ")
    .filter(Boolean)
    .slice(0, 2)
    .map((part) => part[0])
    .join("")
    .toUpperCase() || "?";
}

function formatDate(timestamp) {
  if (!timestamp) return null;
  try {
    const date = new Date(timestamp);
    if (Number.isNaN(date.getTime())) return String(timestamp);
    return new Intl.DateTimeFormat("en-US", {
      month: "short",
      day: "numeric",
      year: "numeric",
      hour: "numeric",
      minute: "2-digit",
    }).format(date);
  } catch {
    return String(timestamp);
  }
}

function AuthenticatedImage({ filename, alt, loadImage }) {
  const [source, setSource] = useState("");
  const [error, setError] = useState("");

  useEffect(() => {
    let active = true;
    let objectUrl = "";

    if (!filename) {
      setSource("");
      return () => {};
    }

    loadImage(filename)
      .then((blob) => {
        if (active) {
          objectUrl = URL.createObjectURL(blob);
          setSource(objectUrl);
        }
      })
      .catch(() => {
        if (active) {
          setError("Image unavailable.");
        }
      });

    return () => {
      active = false;
      if (objectUrl) {
        URL.revokeObjectURL(objectUrl);
      }
    };
  }, [filename, loadImage]);

  if (error) {
    return <p className="muted">{error}</p>;
  }
  return source ? <img className="post-image" src={source} alt={alt} loading="lazy" decoding="async" /> : null;
}

export function PostCard({ post, currentUserId, loadImage, onEdit, onDelete }) {
  const [editing, setEditing] = useState(false);
  const [form, setForm] = useState({ title: post.title || "", text: post.text || "", image: null, removeImage: false });
  const [error, setError] = useState("");

  const authorId = post.author_id ?? post.authorId ?? post.author?.id;
  const isOwner = authorId !== undefined && String(authorId) === String(currentUserId);
  const imageFilename = getImageFilename(post);
  const authorName = getAuthorName(post, authorId);
  const authorUsername = getAuthorUsername(post);
  const formattedDate = formatDate(post.created_at || post.createdAt);

  async function handleEdit(event) {
    event.preventDefault();
    setError("");
    if (form.image && form.removeImage) {
      setError("An image cannot be uploaded and removed at the same time.");
      return;
    }

    try {
      await onEdit(post.id, form);
      setEditing(false);
    } catch (editError) {
      setError(editError.message || "Unable to edit post.");
    }
  }

  async function handleDelete() {
    if (!window.confirm("Delete this post?")) {
      return;
    }
    try {
      await onDelete(post.id);
    } catch (deleteError) {
      setError(deleteError.message || "Unable to delete post.");
    }
  }

  const profilePath = authorId ? `/profile/${authorId}` : "/profile";

  return (
    <article className="panel post-card">
      <div className="post-top post-author">
        <Link to={profilePath} className="author-link" title={`View ${authorName}'s profile`}>
          <div className="author-avatar">{getInitials(authorName)}</div>
          <div className="author-meta">
            <span className="author-name">{authorName}</span>
            {authorUsername && !authorName.startsWith("@") ? (
              <span className="author-handle">@{authorUsername}</span>
            ) : null}
          </div>
        </Link>
        <div className="post-top-right">
          {formattedDate ? <span className="post-date">{formattedDate}</span> : null}
          {isOwner && !editing ? (
            <div className="post-owner-actions">
              <button
                type="button"
                className="icon-btn edit-icon-btn"
                title="Edit post"
                aria-label="Edit post"
                onClick={() => setEditing(true)}
              >
                <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
                  <path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7" />
                  <path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z" />
                </svg>
              </button>
              <button
                type="button"
                className="icon-btn delete-icon-btn"
                title="Delete post"
                aria-label="Delete post"
                onClick={handleDelete}
              >
                <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
                  <polyline points="3 6 5 6 21 6" />
                  <path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" />
                  <line x1="10" y1="11" x2="10" y2="17" />
                  <line x1="14" y1="11" x2="14" y2="17" />
                </svg>
              </button>
            </div>
          ) : null}
        </div>
      </div>

      {editing ? (
        <form onSubmit={handleEdit} className="post-form">
          <label>
            <span>Title</span>
            <input value={form.title} onChange={(event) => setForm((previous) => ({ ...previous, title: event.target.value }))} />
          </label>
          <label>
            <span>Text</span>
            <textarea value={form.text} onChange={(event) => setForm((previous) => ({ ...previous, text: event.target.value }))} rows="4" />
          </label>
          <label>
            <span>Replace image (optional)</span>
            <input type="file" accept="image/*" onChange={(event) => setForm((previous) => ({ ...previous, image: event.target.files?.[0] || null }))} />
          </label>
          <label className="checkbox-label">
            <input type="checkbox" checked={form.removeImage} onChange={(event) => setForm((previous) => ({ ...previous, removeImage: event.target.checked }))} />
            Remove current image
          </label>
          <div className="inline-actions">
            <button type="submit">Save</button>
            <button type="button" className="ghost-btn" onClick={() => setEditing(false)}>Cancel</button>
          </div>
        </form>
      ) : (
        <>
          <div className="post-copy">
            {post.title ? <h3>{post.title}</h3> : null}
            <p>{post.text ?? post.content}</p>
          </div>
          {imageFilename ? <AuthenticatedImage filename={imageFilename} alt={post.title || "Post image"} loadImage={loadImage} /> : null}
        </>
      )}
      {error ? <p className="error-text">{error}</p> : null}
    </article>
  );
}
