import React, { useEffect, useMemo, useState } from "react";
import { useTranslation } from "react-i18next";
import { loadAuth } from "../../auth/authStorage";
import {
  fetchPostLikeState,
  recordPostShare,
  togglePostLike,
  updatePostVisibility,
  fetchProfile,
  editPost,
  deletePost,
} from "../../api/client";
import { useAuth } from "../../auth/AuthContext";
import { trackEvent } from "../../utils/analytics";

function isAuthed() {
  try {
    const auth = loadAuth();
    return !!(auth && auth.access_token);
  } catch {
    return false;
  }
}

function requestAuth(message) {
  try {
    window.dispatchEvent(
      new CustomEvent("sociowire:auth-required", {
        detail: { message, mode: "login" },
      })
    );
  } catch {}
  trackEvent("auth_required", { context: "wall", mode: "login" });
}

// Time formatting is now handled in the component with translations

function formatRelativeTime(createdAt) {
  try {
    if (!createdAt) return "now";
    const d = createdAt instanceof Date ? createdAt : new Date(String(createdAt));
    if (Number.isNaN(d.getTime())) return "now";

    const s = Math.floor((Date.now() - d.getTime()) / 1000);
    if (s < 60) return "now";
    const m = Math.floor(s / 60);
    if (m < 60) return `${m}m`;
    const h = Math.floor(m / 60);
    if (h < 48) return `${h}h`;
    const days = Math.floor(h / 24);
    return `${days}d`;
  } catch {
    return "now";
  }
}

function formatCount(value) {
  const n = Number(value);
  if (!Number.isFinite(n)) return "0";
  if (n < 1000) return String(Math.max(0, Math.floor(n)));
  if (n < 1000000) return `${(n / 1000).toFixed(1)}k`;
  return `${(n / 1000000).toFixed(1)}m`;
}

function categoryLabel(post) {
  const c = (post?.category || "NEWS").toString().toUpperCase();
  if (c === "EVENT") return "EVENTS";
  return c;
}

function categoryIconClass(post) {
  const c = (post?.category || "NEWS").toString().toUpperCase();
  switch (c) {
    case "EVENT":
    case "EVENTS":
      return "fa-regular fa-calendar";
    case "FRIENDS":
      return "fa-solid fa-user-group";
    case "MARKET":
      return "fa-solid fa-store";
    default:
      return "fa-regular fa-newspaper";
  }
}

function normalizeImageUrl(raw) {
  const v = (raw || "").toString().trim();
  if (!v) return "";
  const lower = v.toLowerCase();
  if (
    lower === "null" ||
    lower === "undefined" ||
    lower === "none" ||
    lower === "false" ||
    lower === "0" ||
    lower === "self" ||
    lower === "default"
  ) {
    return "";
  }
  if (lower.startsWith("data:")) return "";
  if (
    lower.startsWith("http://") ||
    lower.startsWith("https://") ||
    lower.startsWith("//") ||
    lower.startsWith("/") ||
    lower.startsWith("./")
  ) {
    return v;
  }
  return "";
}

const wallAvatarCache = new Map();
const wallAvatarInflight = new Map();

async function getAvatarForUser(name) {
  const key = (name || "").toLowerCase().trim();
  if (!key) return "";
  if (wallAvatarCache.has(key)) return wallAvatarCache.get(key);
  if (wallAvatarInflight.has(key)) return wallAvatarInflight.get(key);
  const p = (async () => {
    const profile = await fetchProfile(name);
    const url = (profile && profile.avatar_url) ? String(profile.avatar_url) : "";
    wallAvatarCache.set(key, url);
    wallAvatarInflight.delete(key);
    return url;
  })().catch(() => {
    wallAvatarCache.set(key, "");
    wallAvatarInflight.delete(key);
    return "";
  });
  wallAvatarInflight.set(key, p);
  return p;
}

export default function PostCard({ post, selected, onSelect, onPostDeleted, onPostUpdated }) {
  const { t } = useTranslation();
  const [liked, setLiked] = useState(false);
  const [authed, setAuthed] = useState(isAuthed());
  const [activeImageIndex, setActiveImageIndex] = useState(0);
  const [failedImageIndices, setFailedImageIndices] = useState(() => new Set());
  const [imgFailed, setImgFailed] = useState(false);
  const [showPrivacy, setShowPrivacy] = useState(false);
  const [privacySaving, setPrivacySaving] = useState(false);
  const [privacyError, setPrivacyError] = useState("");
  const [postVisibility, setPostVisibility] = useState(
    (post?.visibility || "public").toString()
  );
  const [postGroupId, setPostGroupId] = useState(
    (post?.group_id || "").toString()
  );
  const [postUsers, setPostUsers] = useState("");
  const [applyToImages, setApplyToImages] = useState(true);
  const [counts, setCounts] = useState(() => ({
    like: post?.like_count ?? 0,
    comment: post?.comment_count ?? 0,
    share: post?.share_count ?? 0,
  }));
  const { username, token } = useAuth();

  // Edit/Delete state
  const [showEditDelete, setShowEditDelete] = useState(false);
  const [isEditing, setIsEditing] = useState(false);
  const [editTitle, setEditTitle] = useState("");
  const [editSnippet, setEditSnippet] = useState("");
  const [editSaving, setEditSaving] = useState(false);
  const [showDeleteConfirm, setShowDeleteConfirm] = useState(false);
  const [deleting, setDeleting] = useState(false);

  const postId = post?.id ?? post?._id ?? 0;

  useEffect(() => {
    let active = true;
    if (!authed || !postId) return () => {};
    fetchPostLikeState(postId).then((res) => {
      if (!active) return;
      if (res?.ok && res.liked) setLiked(true);
    });
    return () => {
      active = false;
    };
  }, [authed, postId]);

  useEffect(() => {
    const handler = () => {
      const next = isAuthed();
      setAuthed(next);
      if (!next) setLiked(false);
    };
    window.addEventListener("sociowire:auth-changed", handler);
    return () => window.removeEventListener("sociowire:auth-changed", handler);
  }, []);

  useEffect(() => {
    setCounts({
      like: post?.like_count ?? 0,
      comment: post?.comment_count ?? 0,
      share: post?.share_count ?? 0,
    });
  }, [post?.like_count, post?.comment_count, post?.share_count]);
  useEffect(() => {
    setPostVisibility((post?.visibility || "public").toString());
    setPostGroupId((post?.group_id || "").toString());
  }, [post?.visibility, post?.group_id]);

  const mediaUrls = useMemo(() => {
    const list = [];
    const seen = new Set();
    const addUrl = (value) => {
      const normalized = normalizeImageUrl(value);
      if (!normalized || seen.has(normalized)) {
        return;
      }
      seen.add(normalized);
      list.push(normalized);
    };
    if (Array.isArray(post?.media_urls)) {
      post.media_urls.forEach(addUrl);
    }
    [post?.image_large, post?.image_medium, post?.image_small, post?.image, post?.media_url].forEach(addUrl);
    return list;
  }, [post?.media_urls, post?.image_large, post?.image_medium, post?.image_small, post?.image, post?.media_url]);
  const mediaKey = mediaUrls.join("|");

  useEffect(() => {
    setActiveImageIndex(0);
    setFailedImageIndices(new Set());
    setImgFailed(false);
  }, [mediaKey]);

  const title = post?.title || "Untitled";
  const snippet = post?.snippet || "";
  const author = (post?.author || post?.Author || "anon").toString();
  const isAuthor =
    username && author && author.toLowerCase() === username.toLowerCase();
  const [authorAvatar, setAuthorAvatar] = useState("");
  const sub = (post?.sub_category || post?.subCategory || "").toString();
  const timeAgo = formatRelativeTime(post?.created_at || post?.CreatedAt || post?.createdAt);
  const cat = categoryLabel(post);
  const metaLine = useMemo(() => {
    const parts = [];
    if (sub) parts.push(sub);
    if (post?.region) parts.push(post.region);
    return parts.join(" • ");
  }, [sub, post?.region]);

  const safeImageIndex = mediaUrls.length
    ? Math.min(Math.max(activeImageIndex, 0), mediaUrls.length - 1)
    : 0;
  const activeImage = mediaUrls[safeImageIndex] || "";
  const hasGalleryImage = Boolean(activeImage && !imgFailed);

  const findNextAvailableIndex = (current, failed) => {
    if (mediaUrls.length === 0) return -1;
    for (let offset = 1; offset <= mediaUrls.length; offset += 1) {
      const idx = (current + offset) % mediaUrls.length;
      if (!failed.has(idx)) {
        return idx;
      }
    }
    return -1;
  };
  const findPrevAvailableIndex = (current, failed) => {
    if (mediaUrls.length === 0) return -1;
    for (let offset = 1; offset <= mediaUrls.length; offset += 1) {
      const idx = (current - offset + mediaUrls.length) % mediaUrls.length;
      if (!failed.has(idx)) {
        return idx;
      }
    }
    return -1;
  };

  const handleImageError = () => {
    if (!activeImage) {
      setImgFailed(true);
      return;
    }
    const nextFailed = new Set(failedImageIndices);
    nextFailed.add(safeImageIndex);
    setFailedImageIndices(nextFailed);
    if (nextFailed.size >= mediaUrls.length) {
      setImgFailed(true);
      return;
    }
    const nextIndex = findNextAvailableIndex(safeImageIndex, nextFailed);
    if (nextIndex >= 0) {
      setActiveImageIndex(nextIndex);
    }
  };

  useEffect(() => {
    let cancelled = false;
    const who = (author || "").trim();
    if (!who) {
      setAuthorAvatar("");
      return;
    }
    getAvatarForUser(who).then((url) => {
      if (cancelled) return;
      setAuthorAvatar(url || "");
    });
    return () => {
      cancelled = true;
    };
  }, [author]);

  return (
    <article
      className={"post-card sw-wall-card" + (selected ? " selected" : "")}
      onClick={() => {
        trackEvent("post_view", {
          post_id: postId,
          post_title: title?.slice(0, 100),
          post_category: cat,
          post_author: author,
          content_type: "post",
        });
        onSelect && onSelect(post);
      }}
    >
      <div className="sw-wall-head">
        <div className="sw-wall-avatar">
          {authorAvatar ? <img src={authorAvatar} alt={author} /> : (author ? author[0]?.toUpperCase() : "U")}
        </div>
        <div className="sw-wall-meta">
          <div className="sw-wall-author">{author}</div>
          <div className="sw-wall-time">{timeAgo}</div>
        </div>
        <div className="sw-wall-badge">{cat}</div>
      </div>

      {hasGalleryImage ? (
        <div className="sw-wall-gallery">
          <div className="sw-wall-image">
            <img
              src={activeImage}
              alt=""
              loading="lazy"
              onError={handleImageError}
            />
            {mediaUrls.length > 1 && (
              <div className="sw-wall-gallery-count">
                {safeImageIndex + 1}/{mediaUrls.length}
              </div>
            )}
            {mediaUrls.length > 1 && (
              <>
                <button
                  type="button"
                  className="sw-wall-gallery-arrow left"
                  onClick={(e) => {
                    e.stopPropagation();
                    const prev = findPrevAvailableIndex(safeImageIndex, failedImageIndices);
                    if (prev >= 0) setActiveImageIndex(prev);
                  }}
                  aria-label="Previous image"
                >
                  <i className="fa-solid fa-chevron-left" />
                </button>
                <button
                  type="button"
                  className="sw-wall-gallery-arrow right"
                  onClick={(e) => {
                    e.stopPropagation();
                    const next = findNextAvailableIndex(safeImageIndex, failedImageIndices);
                    if (next >= 0) setActiveImageIndex(next);
                  }}
                  aria-label="Next image"
                >
                  <i className="fa-solid fa-chevron-right" />
                </button>
              </>
            )}
          </div>
          {mediaUrls.length > 1 && (
            <div className="sw-wall-gallery-thumbs">
              {mediaUrls.map((value, idx) => (
                <button
                  key={`thumb-${value}-${idx}`}
                  type="button"
                  className={`sw-wall-gallery-thumb${idx === safeImageIndex ? " active" : ""}`}
                  onClick={() => setActiveImageIndex(idx)}
                >
                  <img src={value} alt="" loading="lazy" />
                </button>
              ))}
            </div>
          )}
        </div>
      ) : (
        <div className="sw-wall-image sw-wall-image-fallback" aria-hidden="true">
          <div className="sw-wall-image-fallback-inner">
            <i className={categoryIconClass(post)} />
            <span>{categoryLabel(post)}</span>
          </div>
        </div>
      )}

      <div className="sw-wall-body">
        <div className="sw-wall-title">{title}</div>
        {snippet ? <div className="sw-wall-snippet">{snippet}</div> : null}
        {metaLine ? <div className="sw-wall-meta-line">{metaLine}</div> : null}
      </div>

      <div className="sw-wall-footer">
        <div className="sw-wall-stats">
          <span><i className="fa-regular fa-heart" /> {formatCount(counts.like)}</span>
          <span><i className="fa-regular fa-comment" /> {formatCount(counts.comment)}</span>
          <span><i className="fa-solid fa-share-nodes" /> {formatCount(counts.share)}</span>
        </div>

        <div className="sw-wall-actions">
        <button
          type="button"
          className={"sw-wall-btn" + (liked ? " is-active" : "")}
          onClick={async (e) => {
            e.stopPropagation();
            if (!authed) {
              requestAuth(t('post.signInToLike'));
              return;
            }
            trackEvent("post_like", { post_id: postId, post_title: title?.slice(0, 100), post_category: cat });
            const res = await togglePostLike(postId, !liked);
            if (res?.ok) {
              setLiked(!!res.liked);
              if (res?.counts) {
                setCounts({
                  like: res.counts.like_count,
                  comment: res.counts.comment_count,
                  share: res.counts.share_count,
                });
              }
            }
          }}
        >
          <i className="fa-regular fa-heart" /> {t('post.like')}
        </button>
        <button
          type="button"
          className="sw-wall-btn"
          onClick={(e) => {
            e.stopPropagation();
            if (!authed) {
              requestAuth(t('post.signInToComment'));
              return;
            }
            trackEvent("post_comment", { post_id: postId, post_title: title?.slice(0, 100), post_category: cat });
            if (onSelect) onSelect(post);
          }}
        >
          <i className="fa-regular fa-comment" /> {t('post.comment')}
        </button>
        <button
          type="button"
          className="sw-wall-btn"
          onClick={async (e) => {
            e.stopPropagation();
            const shareUrl = `${window.location.origin}/p/${postId}`;
            trackEvent("post_share", { post_id: postId, post_title: title?.slice(0, 100), post_category: cat });
            try {
              if (navigator.share) {
                await navigator.share({ title: title || "SocioWire", url: shareUrl });
              } else if (navigator.clipboard) {
                await navigator.clipboard.writeText(shareUrl);
              }
            } catch {}
            const res = await recordPostShare(postId);
            if (res?.counts) {
              setCounts({
                like: res.counts.like_count,
                comment: res.counts.comment_count,
                share: res.counts.share_count,
              });
            }
          }}
        >
          <i className="fa-solid fa-share-nodes" /> {t('post.share')}
        </button>

        {isAuthor ? (
          <>
            <button
              type="button"
              className={"sw-wall-btn" + (showPrivacy ? " is-active" : "")}
              onClick={(e) => {
                e.stopPropagation();
                setShowPrivacy((prev) => !prev);
                setShowEditDelete(false);
              }}
            >
              <i className="fa-solid fa-lock" /> {t('post.visibility')}
            </button>
            <button
              type="button"
              className={"sw-wall-btn" + (showEditDelete ? " is-active" : "")}
              onClick={(e) => {
                e.stopPropagation();
                setShowEditDelete((prev) => !prev);
                setShowPrivacy(false);
                if (!showEditDelete) {
                  setEditTitle(post?.title || "");
                  setEditSnippet(post?.snippet || "");
                }
              }}
            >
              <i className="fa-solid fa-ellipsis" />
            </button>
          </>
        ) : null}
        </div>
      </div>

      {isAuthor && showPrivacy ? (
        <div className="sw-wall-privacy" onClick={(e) => e.stopPropagation()}>
          <div className="sw-wall-privacy-row">
            <label>{t('common.post')}</label>
            <select
              value={postVisibility}
              onChange={(e) => {
                const next = e.target.value;
                setPostVisibility(next);
                if (next !== "group") setPostGroupId("");
                if (next !== "custom") setPostUsers("");
              }}
            >
              <option value="public">{t('post.public')}</option>
              <option value="friends">{t('post.friendsOnly')}</option>
              <option value="private">{t('post.private')}</option>
              <option value="group">{t('post.group')}</option>
              <option value="custom">{t('post.custom')}</option>
            </select>
          </div>
          {postVisibility === "group" ? (
            <input
              className="sw-wall-privacy-input"
              placeholder={t('post.groupId')}
              value={postGroupId}
              onChange={(e) => setPostGroupId(e.target.value)}
            />
          ) : null}
          {postVisibility === "custom" ? (
            <input
              className="sw-wall-privacy-input"
              placeholder={t('post.usernamesComma')}
              value={postUsers}
              onChange={(e) => setPostUsers(e.target.value)}
            />
          ) : null}
          <label className="sw-wall-privacy-check">
            <input
              type="checkbox"
              checked={applyToImages}
              onChange={(e) => setApplyToImages(e.target.checked)}
            />
            {t('post.applyToImages')}
          </label>
          {privacyError ? <div className="sw-wall-privacy-error">{privacyError}</div> : null}
          <button
            type="button"
            className="sw-wall-btn"
            disabled={privacySaving}
            onClick={async () => {
              setPrivacyError("");
              setPrivacySaving(true);
              try {
                const payload = {
                  visibility: postVisibility,
                  group_id: postGroupId.trim(),
                  users: postUsers
                    .split(",")
                    .map((u) => u.trim())
                    .filter(Boolean),
                };
                if (applyToImages) {
                  payload.image_visibility = postVisibility;
                  payload.image_group_id = postGroupId.trim();
                  payload.image_users = payload.users;
                }
                await updatePostVisibility(postId, payload, token);
                setPrivacySaving(false);
              } catch (err) {
                setPrivacyError(t('post.visibilityError'));
                setPrivacySaving(false);
              }
            }}
          >
            {privacySaving ? t('post.saving') : t('common.save')}
          </button>
        </div>
      ) : null}

      {isAuthor && showEditDelete ? (
        <div className="sw-wall-edit-menu" onClick={(e) => e.stopPropagation()}>
          {!isEditing && !showDeleteConfirm ? (
            <>
              <button
                type="button"
                className="sw-wall-btn"
                onClick={() => setIsEditing(true)}
              >
                <i className="fa-solid fa-pen" /> {t('common.edit')}
              </button>
              <button
                type="button"
                className="sw-wall-btn sw-wall-btn-danger"
                onClick={() => setShowDeleteConfirm(true)}
              >
                <i className="fa-solid fa-trash" /> {t('common.delete')}
              </button>
            </>
          ) : null}

          {isEditing ? (
            <div className="sw-wall-edit-form">
              <input
                type="text"
                className="sw-wall-edit-input"
                placeholder={t('post.title')}
                value={editTitle}
                onChange={(e) => setEditTitle(e.target.value)}
              />
              <textarea
                className="sw-wall-edit-textarea"
                placeholder={t('post.description')}
                value={editSnippet}
                onChange={(e) => setEditSnippet(e.target.value)}
                rows={3}
              />
              <div className="sw-wall-edit-actions">
                <button
                  type="button"
                  className="sw-wall-btn"
                  disabled={editSaving}
                  onClick={async () => {
                    setEditSaving(true);
                    const res = await editPost(postId, {
                      title: editTitle.trim(),
                      snippet: editSnippet.trim(),
                    }, token);
                    setEditSaving(false);
                    if (res?.ok) {
                      setIsEditing(false);
                      setShowEditDelete(false);
                      if (onPostUpdated) onPostUpdated(res);
                    }
                  }}
                >
                  {editSaving ? t('post.saving') : t('common.save')}
                </button>
                <button
                  type="button"
                  className="sw-wall-btn"
                  onClick={() => setIsEditing(false)}
                >
                  {t('common.cancel')}
                </button>
              </div>
            </div>
          ) : null}

          {showDeleteConfirm ? (
            <div className="sw-wall-delete-confirm">
              <p>{t('post.deletePost')}</p>
              <div className="sw-wall-edit-actions">
                <button
                  type="button"
                  className="sw-wall-btn sw-wall-btn-danger"
                  disabled={deleting}
                  onClick={async () => {
                    setDeleting(true);
                    const res = await deletePost(postId, token);
                    setDeleting(false);
                    if (res?.ok) {
                      setShowDeleteConfirm(false);
                      setShowEditDelete(false);
                      if (onPostDeleted) onPostDeleted(postId);
                    }
                  }}
                >
                  {deleting ? t('post.deleting') : t('common.delete')}
                </button>
                <button
                  type="button"
                  className="sw-wall-btn"
                  onClick={() => setShowDeleteConfirm(false)}
                >
                  {t('common.cancel')}
                </button>
              </div>
            </div>
          ) : null}
        </div>
      ) : null}
    </article>
  );
}
