import {
  fetchPostByUrl,
  type BlueskyPost,
  type BlueskyFacet,
} from "@/lib/bluesky";

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

function renderText(text: string, facets?: BlueskyFacet[]): React.ReactNode {
  if (!facets || facets.length === 0) return text;

  const bytes = new TextEncoder().encode(text);
  const decoder = new TextDecoder();
  const sorted = [...facets].sort(
    (a, b) => a.index.byteStart - b.index.byteStart
  );

  const parts: React.ReactNode[] = [];
  let cursor = 0;

  for (let i = 0; i < sorted.length; i++) {
    const facet = sorted[i];
    const { byteStart, byteEnd } = facet.index;
    if (byteStart > cursor) {
      parts.push(decoder.decode(bytes.slice(cursor, byteStart)));
    }
    const slice = decoder.decode(bytes.slice(byteStart, byteEnd));
    const link = facet.features.find(
      (f) => f.$type === "app.bsky.richtext.facet#link"
    );
    const mention = facet.features.find(
      (f) => f.$type === "app.bsky.richtext.facet#mention"
    );
    if (link?.uri) {
      parts.push(
        <a
          key={`f-${i}`}
          href={link.uri}
          target="_blank"
          rel="noopener noreferrer"
          className="text-sky-600 hover:underline dark:text-sky-400"
        >
          {slice}
        </a>
      );
    } else if (mention?.did) {
      const handle = slice.startsWith("@") ? slice.slice(1) : slice;
      parts.push(
        <a
          key={`f-${i}`}
          href={`https://bsky.app/profile/${handle}`}
          target="_blank"
          rel="noopener noreferrer"
          className="text-sky-600 hover:underline dark:text-sky-400"
        >
          {slice}
        </a>
      );
    } else {
      parts.push(slice);
    }
    cursor = byteEnd;
  }
  if (cursor < bytes.length) {
    parts.push(decoder.decode(bytes.slice(cursor)));
  }
  return parts;
}

function FallbackLink({ url }: { url: string }) {
  return (
    <a
      href={url}
      target="_blank"
      rel="noopener noreferrer"
      className="text-sky-600 hover:underline dark:text-sky-400"
    >
      {url}
    </a>
  );
}

interface BlueskyPostCardProps {
  post: BlueskyPost | null;
  url: string;
}

export function BlueskyPostCard({ post, url }: BlueskyPostCardProps) {
  if (!post) return <FallbackLink url={url} />;

  const { author, record } = post;
  return (
    <a
      href={url}
      target="_blank"
      rel="noopener noreferrer"
      className="not-prose my-6 block overflow-hidden rounded-2xl border border-neutral-200 bg-white p-5 no-underline shadow-sm transition-shadow hover:shadow-md dark:border-neutral-800 dark:bg-neutral-900"
    >
      <div className="flex items-start gap-3">
        {author.avatar ? (
          // eslint-disable-next-line @next/next/no-img-element
          <img
            src={author.avatar}
            alt={author.displayName ?? author.handle}
            width={48}
            height={48}
            className="size-12 flex-shrink-0 rounded-full object-cover"
          />
        ) : (
          <div className="flex size-12 flex-shrink-0 items-center justify-center rounded-full bg-neutral-100 text-lg font-semibold text-neutral-500 dark:bg-neutral-800">
            {(author.displayName ?? author.handle).charAt(0).toUpperCase()}
          </div>
        )}
        <div className="min-w-0 flex-1">
          <div className="truncate font-semibold leading-tight text-neutral-900 dark:text-neutral-100">
            {author.displayName ?? author.handle}
          </div>
          <div className="truncate text-sm text-neutral-500 dark:text-neutral-400">
            @{author.handle}
          </div>
        </div>
        <svg
          viewBox="0 0 600 530"
          aria-hidden="true"
          className="size-5 flex-shrink-0 text-sky-500"
          fill="currentColor"
        >
          <path d="M135.72 44.03C202.216 93.951 273.74 195.17 300 249.49c26.262-54.316 97.782-155.54 164.28-205.46C512.26 8.009 590-19.474 590 69.20c0 17.7-10.148 148.78-16.1 170.07-20.69 74-96.14 92.88-163.20 81.42 117.25 19.95 147.13 86.07 82.71 152.18C370.94 598.51 314.93 462.46 300 416.81c-14.93 45.65-70.94 181.7-193.41 56.06C42.171 406.76 72.05 340.64 189.30 320.69c-67.06 11.46-142.51-7.42-163.20-81.42C20.148 217.98 10 86.9 10 69.20c0-88.674 77.74-61.191 125.72-25.17z" />
        </svg>
      </div>
      <div className="mt-3 whitespace-pre-wrap text-[15px] leading-relaxed text-neutral-800 dark:text-neutral-200">
        {renderText(record.text, record.facets)}
      </div>
      <div className="mt-4 border-t border-neutral-100 pt-3 text-[13px] text-neutral-500 dark:border-neutral-800 dark:text-neutral-400">
        {formatDate(record.createdAt)} · Bluesky
      </div>
    </a>
  );
}

export default async function BlueskyEmbed({ url }: { url: string }) {
  const post = await fetchPostByUrl(url);
  return <BlueskyPostCard post={post} url={url} />;
}
