import { Link, useNavigate } from "react-router-dom";
import { useTranslation } from "react-i18next";
import { useRef, useState, useEffect } from "react";
import { FiTrash2, FiMoreHorizontal } from "react-icons/fi";
import type { Post } from "@/api/generated/private/models/post";
import Avatar from "@/components/ui/Avatar";
import IconButton from "@/components/ui/IconButton";
import { useAuth } from "@/hooks/useAuth";
import { canDeletePost, canEditPost } from "@/hooks/usePermissions";
import { formatRelative } from "@/utils/relativeTime";
import { apiSocialPostsDestroy } from "@/api/generated/private/posts/posts";
import { useQueryClient } from "@tanstack/react-query";
import MediaGallery from "./MediaGallery";
import PostActions from "./PostActions";

// Extended until orval regeneration adds these fields to the generated Post type
interface AuthorDetail {
  id: number;
  username: string;
  first_name?: string;
  last_name?: string;
  avatar?: string | null;
}

type EnrichedPost = Omit<Post, 'author_detail'> & {
  author_detail?: AuthorDetail;
};

interface Props {
  post: EnrichedPost;
  variant?: "compact" | "default" | "focused";
  clickable?: boolean;
  hideHubBadge?: boolean;
  onReplyClick?: () => void;
}

export default function Post({
  post,
  variant = "default",
  clickable = true,
  hideHubBadge = false,
  onReplyClick,
}: Props) {
  const { t } = useTranslation("social");
  const { user } = useAuth();
  const navigate = useNavigate();
  const queryClient = useQueryClient();

  const isFocused = variant === "focused";
  const isCompact = variant === "compact";

  const author = post.author_detail;
  const displayName = author?.username ?? `user${post.author}`;
  const fullName =
    author && (author.first_name || author.last_name)
      ? `${author.first_name} ${author.last_name}`.trim()
      : displayName;

  async function handleDelete(e: React.MouseEvent) {
    e.stopPropagation();
    if (!confirm("Smazat příspěvek?")) return;
    await apiSocialPostsDestroy(post.id);
    await queryClient.invalidateQueries({ queryKey: ["social", "posts"] });
  }

  function open(e: React.MouseEvent) {
    if (!clickable) return;
    const target = e.target as HTMLElement;
    if (target.closest("button, a, [role='button']")) return;
    navigate(`/social/post/${post.id}`);
  }

  const canDelete = canDeletePost(user, post as unknown as Post);
  const canEdit = canEditPost(user, post as unknown as Post);

  const [menuOpen, setMenuOpen] = useState(false);
  const menuRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    if (!menuOpen) return;
    function onClickOutside(e: MouseEvent) {
      if (menuRef.current && !menuRef.current.contains(e.target as Node)) {
        setMenuOpen(false);
      }
    }
    document.addEventListener("mousedown", onClickOutside);
    return () => document.removeEventListener("mousedown", onClickOutside);
  }, [menuOpen]);

  return (
    <article
      onClick={open}
      className={[
        "border-b border-brand-lines/10 px-4 py-3",
        isFocused ? "bg-brand-lines/5" : "",
        clickable ? "cursor-pointer hover:bg-brand-lines/5 transition-colors" : "",
      ].join(" ")}
    >
      <div className="flex gap-3">
        <Link
          to={`/social/profile/${author?.username ?? post.author}`}
          onClick={(e) => e.stopPropagation()}
          className="shrink-0"
        >
          <Avatar
            name={fullName}
            src={author?.avatar ?? null}
            size={isCompact ? 32 : 40}
          />
        </Link>

        <div className="min-w-0 flex-1">
          <header className="flex items-start justify-between gap-2">
            <div className="flex flex-wrap items-baseline gap-x-2 gap-y-0 text-sm">
              <Link
                to={`/social/profile/${author?.username ?? post.author}`}
                onClick={(e) => e.stopPropagation()}
                className="font-semibold text-brand-text hover:underline"
              >
                @{displayName}
              </Link>
              {post.hub_detail && !hideHubBadge && (
                <Link
                  to={`/social/h/${post.hub_detail.name}`}
                  onClick={(e) => e.stopPropagation()}
                  className="text-xs font-medium text-brand-accent/70 hover:text-brand-accent hover:underline"
                >
                  h/{post.hub_detail.name}
                </Link>
              )}
              <span className="text-brand-text/50">·</span>
              <time className="text-xs text-brand-text/60" dateTime={String(post.created_at)}>
                {formatRelative(post.created_at)}
              </time>
            </div>

            {(canDelete || canEdit) && (
              <div ref={menuRef} className="relative">
                <IconButton
                  icon={<FiMoreHorizontal size={14} />}
                  label={t("post.actions.more")}
                  onClick={(e) => { e.stopPropagation(); setMenuOpen((o) => !o); }}
                />
                {menuOpen && (
                  <div className="absolute right-0 top-full z-20 mt-1 min-w-[140px] overflow-hidden rounded-xl border border-brand-lines/20 bg-brand-bg shadow-lg">
                    {canDelete && (
                      <button
                        type="button"
                        onClick={handleDelete}
                        className="flex w-full items-center gap-2 px-3 py-2 text-sm text-red-400 hover:bg-brand-lines/10 transition-colors"
                      >
                        <FiTrash2 size={14} />
                        {t("post.actions.delete")}
                      </button>
                    )}
                  </div>
                )}
              </div>
            )}
          </header>

          {post.content && (
            <p className={`mt-1 whitespace-pre-wrap wrap-break-word text-brand-text ${isFocused ? "text-lg" : "text-[15px]"}`}>
              {post.content}
            </p>
          )}

          {post.contents?.length > 0 && <MediaGallery items={post.contents} />}

          {post.tags?.length > 0 && (
            <div className="mt-2 flex flex-wrap gap-1.5">
              {post.tags.map((tag) => (
                <span
                  key={tag.id}
                  className="rounded-full border border-brand-lines/20 bg-brand-lines/5 px-2 py-0.5 text-[11px] text-brand-text/80"
                  style={{ borderColor: tag.color ?? undefined }}
                >
                  {tag.name}
                </span>
              ))}
            </div>
          )}

          {!isCompact && (
            <PostActions
              postId={post.id}
              replyCount={post.reply_count}
              voteScore={Number(post.vote_score) || undefined}
              initialUserVote={(Number(post.user_vote) || 0) as -1 | 0 | 1}
              initialIsSaved={String(post.is_saved) === "true"}
              initialSaveCount={Number(post.save_count) || undefined}
              onReplyClick={onReplyClick}
            />
          )}
        </div>
      </div>
    </article>
  );
}
