"use client";

import { useRef, useState, lazy } from "react";
import {
  parseEmbedPlayerFromUrl,
  getPlayerAspect,
  type EmbedPlayerParams,
} from "../utils/embed-player";
import { BlueskyRichText } from "./BlueskyRichText";
import type { BlueskyPost } from "../utils/bluesky";
import * as feedDefs from "@/lib/lexicons/app/bsky/feed/defs";
import * as feedPost from "@/lib/lexicons/app/bsky/feed/post";
import * as embedImages from "@/lib/lexicons/app/bsky/embed/images";
import * as embedExternal from "@/lib/lexicons/app/bsky/embed/external";
import * as embedVideo from "@/lib/lexicons/app/bsky/embed/video";
import * as embedRecord from "@/lib/lexicons/app/bsky/embed/record";
import * as embedRecordWithMedia from "@/lib/lexicons/app/bsky/embed/recordWithMedia";
import "./BlueskyPostEmbed.css";

const BlueskyVideoPlayer = lazy(() =>
  import("./BlueskyVideoPlayer").then((m) => ({ default: m.BlueskyVideoPlayer })),
);

interface BlueskyPostEmbedProps {
  post: BlueskyPost;
  onDelete?: () => void;
}

export function BlueskyPostEmbed({ post, onDelete }: BlueskyPostEmbedProps) {
  const record = post.post.record as feedPost.Main;
  const author = post.post.author;
  const postUrl = `https://bsky.app/profile/${author.handle}/post/${post.post.uri.split("/").pop()}`;

  const timestamp = new Date(post.post.indexedAt);
  const now = new Date();
  const diffMs = now.getTime() - timestamp.getTime();
  const diffMins = Math.floor(diffMs / 60000);
  const diffHours = Math.floor(diffMs / 3600000);
  const diffDays = Math.floor(diffMs / 86400000);

  let timeAgo = "";
  if (diffMins < 60) timeAgo = `${diffMins}m ago`;
  else if (diffHours < 24) timeAgo = `${diffHours}h ago`;
  else timeAgo = `${diffDays}d ago`;

  const embedContent = (
    <div className="BlueskyPostEmbed">
      {/* Author */}
      <div className="BlueskyPostEmbed-author">
        {author.avatar ? (
          <img
            src={author.avatar}
            alt={`${author.displayName}'s avatar`}
            className="BlueskyPostEmbed-avatar"
          />
        ) : (
          <div className="BlueskyPostEmbed-avatar BlueskyPostEmbed-avatar--empty" />
        )}
        <div className="BlueskyPostEmbed-authorInfo">
          <div className="BlueskyPostEmbed-authorName">{author.displayName || author.handle}</div>
          <div className="BlueskyPostEmbed-authorHandle">@{author.handle}</div>
        </div>
      </div>

      {/* Post content */}
      <div className="BlueskyPostEmbed-content">
        <p className="BlueskyPostEmbed-text">
          <BlueskyRichText record={record} />
        </p>

        {/* Embeds (images, links, videos, etc) */}
        {post.post.embed && <BlueskyEmbedContent embed={post.post.embed} />}
      </div>

      {/* Footer */}
      <div className="BlueskyPostEmbed-footer">
        <span className="BlueskyPostEmbed-time">{timeAgo}</span>
        <a
          href={postUrl}
          target="_blank"
          rel="noopener noreferrer"
          className="BlueskyPostEmbed-externalLink"
        >
          view on bluesky →
        </a>
      </div>
    </div>
  );

  if (onDelete) {
    return (
      <div className="BlueskyPostEmbed-container">
        {embedContent}
        <button
          onClick={(e) => {
            e.preventDefault();
            e.stopPropagation();
            onDelete();
          }}
          className="BlueskyPostEmbed-deleteButton"
          title="remove link"
        >
          ×
        </button>
      </div>
    );
  }

  return embedContent;
}

function BlueskyEmbedContent({ embed }: { embed: feedDefs.PostView["embed"] }) {
  if (!embed) return null;

  // Case 1: Images
  if (embedImages.view.$check(embed)) {
    return <BlueskyImageEmbed images={embed.images} />;
  }

  // Case 2: External link
  if (embedExternal.view.$check(embed)) {
    return <BlueskyExternalEmbed external={embed.external} />;
  }

  // Case 3: Video
  if (embedVideo.view.$check(embed)) {
    return <BlueskyVideoEmbed video={embed} />;
  }

  // Case 4: Quote post (record embed)
  if (embedRecord.view.$check(embed)) {
    return <BlueskyRecordEmbed record={embed.record} nested />;
  }

  // Case 5: Quote post with media (recordWithMedia embed)
  if (embedRecordWithMedia.view.$check(embed)) {
    return (
      <div className="BlueskyPostEmbed-recordWithMedia">
        {/* Render the media first */}
        <BlueskyEmbedContent embed={embed.media} />
        {/* Then render the quoted record */}
        <BlueskyRecordEmbed record={embed.record.record} nested />
      </div>
    );
  }

  return null;
}

function BlueskyImageEmbed({
  images,
  compact,
}: {
  images: embedImages.ViewImage[];
  compact?: boolean;
}) {
  // Compact mode: show small thumbnail for quoted posts
  if (compact) {
    return (
      <div className="BlueskyPostEmbed-compactMedia">
        <img
          src={images[0].thumb}
          alt={images[0].alt || ""}
          className="BlueskyPostEmbed-compactImage"
        />
      </div>
    );
  }

  if (images.length === 1) {
    return (
      <div className="BlueskyPostEmbed-images">
        <img
          src={images[0].fullsize}
          alt={images[0].alt || ""}
          className="BlueskyPostEmbed-image--single"
        />
      </div>
    );
  }

  if (images.length === 2) {
    return (
      <div className="BlueskyPostEmbed-images BlueskyPostEmbed-images--2">
        {images.map((image, i) => (
          <img
            key={i}
            src={image.fullsize}
            alt={image.alt || ""}
            className="BlueskyPostEmbed-image"
          />
        ))}
      </div>
    );
  }

  if (images.length === 3) {
    return (
      <div className="BlueskyPostEmbed-images BlueskyPostEmbed-images--3">
        <img
          src={images[0].fullsize}
          alt={images[0].alt || ""}
          className="BlueskyPostEmbed-image BlueskyPostEmbed-image--large"
        />
        <div className="BlueskyPostEmbed-imageColumn">
          {images.slice(1).map((image, i) => (
            <img
              key={i}
              src={image.fullsize}
              alt={image.alt || ""}
              className="BlueskyPostEmbed-image"
            />
          ))}
        </div>
      </div>
    );
  }

  if (images.length === 4) {
    return (
      <div className="BlueskyPostEmbed-images BlueskyPostEmbed-images--4">
        {images.map((image, i) => (
          <img
            key={i}
            src={image.fullsize}
            alt={image.alt || ""}
            className="BlueskyPostEmbed-image"
          />
        ))}
      </div>
    );
  }

  return null;
}

function BlueskyExternalEmbed({ external }: { external: embedExternal.ViewExternal }) {
  // Check if this is a special embed (YouTube, Spotify, GIF, etc.)
  const embedParams = parseEmbedPlayerFromUrl(external.uri);

  if (embedParams) {
    // GIF embeds
    if (embedParams.isGif) {
      return (
        <BlueskyGifEmbed
          gif={{
            playerUri: embedParams.playerUri,
            thumbUri: external.thumb || embedParams.playerUri,
            dimensions: embedParams.dimensions,
          }}
          alt={external.title}
        />
      );
    }

    // Video/audio player embeds (YouTube, Spotify, etc.)
    return (
      <BlueskyPlayerEmbed params={embedParams} thumb={external.thumb} title={external.title} />
    );
  }

  // Regular external link
  const toNiceDomain = (url: string) => {
    try {
      const urlObj = new URL(url);
      return urlObj.host;
    } catch {
      return url;
    }
  };

  return (
    <a
      href={external.uri}
      target="_blank"
      rel="noopener noreferrer"
      className="BlueskyPostEmbed-external"
    >
      {external.thumb && (
        <img src={external.thumb} alt={external.title} className="BlueskyPostEmbed-externalThumb" />
      )}
      <div className="BlueskyPostEmbed-externalInfo">
        <div className="BlueskyPostEmbed-externalDomain">{toNiceDomain(external.uri)}</div>
        <div className="BlueskyPostEmbed-externalTitle">{external.title}</div>
        {external.description && (
          <div className="BlueskyPostEmbed-externalDesc">{external.description}</div>
        )}
      </div>
    </a>
  );
}

function BlueskyPlayerEmbed({
  params,
  thumb,
  title,
}: {
  params: EmbedPlayerParams;
  thumb?: string;
  title: string;
}) {
  const aspect = getPlayerAspect({ type: params.type, hasThumb: !!thumb, width: 600 });

  // Apple Music needs special iframe attributes
  const isAppleMusic = params.source === "appleMusic";

  return (
    <div
      className="BlueskyPostEmbed-player"
      style={aspect.aspectRatio ? { aspectRatio: aspect.aspectRatio } : { height: aspect.height }}
    >
      <iframe
        src={params.playerUri}
        className="BlueskyPostEmbed-playerIframe"
        allow={
          isAppleMusic
            ? "autoplay *; encrypted-media *; fullscreen *; clipboard-write"
            : "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
        }
        sandbox={
          isAppleMusic
            ? "allow-forms allow-popups allow-same-origin allow-scripts allow-storage-access-by-user-activation allow-top-navigation-by-user-activation"
            : undefined
        }
        allowFullScreen
        title={title}
      />
    </div>
  );
}

interface GifInfo {
  playerUri: string;
  thumbUri: string;
  dimensions?: { width: number; height: number };
}

function BlueskyGifEmbed({ gif, alt }: { gif: GifInfo; alt: string }) {
  const [isPlaying, setIsPlaying] = useState(true);
  const videoRef = useRef<HTMLVideoElement>(null);

  const aspectRatio = gif.dimensions ? gif.dimensions.width / gif.dimensions.height : 16 / 9;

  const togglePlay = () => {
    if (videoRef.current) {
      if (isPlaying) {
        videoRef.current.pause();
      } else {
        videoRef.current.play();
      }
      setIsPlaying(!isPlaying);
    }
  };

  // Check if it's a video format (mp4/webm) or image format
  const isVideo = gif.playerUri.endsWith(".mp4") || gif.playerUri.endsWith(".webm");

  if (isVideo) {
    return (
      <div className="BlueskyPostEmbed-gif" style={{ aspectRatio }} onClick={togglePlay}>
        <video
          ref={videoRef}
          src={gif.playerUri}
          poster={gif.thumbUri}
          autoPlay
          loop
          muted
          playsInline
          className="BlueskyPostEmbed-gifVideo"
        />
        {!isPlaying && (
          <div className="BlueskyPostEmbed-gifPlayOverlay">
            <div className="BlueskyPostEmbed-gifPlayButton">▶</div>
          </div>
        )}
        <div className="BlueskyPostEmbed-gifLabel">GIF</div>
      </div>
    );
  }

  // For image-based GIFs (giphy webp/gif)
  return (
    <div className="BlueskyPostEmbed-gif" style={{ aspectRatio }}>
      <img src={gif.playerUri} alt={alt} className="BlueskyPostEmbed-gifImage" />
      <div className="BlueskyPostEmbed-gifLabel">GIF</div>
    </div>
  );
}

function BlueskyVideoEmbed({ video }: { video: embedVideo.View }) {
  return <BlueskyVideoPlayer video={video} />;
}

// Compact video thumbnail for quoted posts
function BlueskyCompactVideo({ video }: { video: embedVideo.View }) {
  return (
    <div className="BlueskyPostEmbed-compactMedia">
      {video.thumbnail ? (
        <img src={video.thumbnail} alt="" className="BlueskyPostEmbed-compactImage" />
      ) : (
        <div className="BlueskyPostEmbed-compactImage BlueskyPostEmbed-compactImage--empty" />
      )}
      <div className="BlueskyPostEmbed-compactPlayIcon">▶</div>
    </div>
  );
}

// Compact external link thumbnail for quoted posts
function BlueskyCompactExternal({ external }: { external: embedExternal.ViewExternal }) {
  if (!external.thumb) return null;
  return (
    <div className="BlueskyPostEmbed-compactMedia">
      <img src={external.thumb} alt="" className="BlueskyPostEmbed-compactImage" />
    </div>
  );
}

// Static embed for inside quotes - compact thumbnails
function BlueskyQuoteEmbed({ embed }: { embed: unknown }) {
  // Images as compact thumbnails
  if (embedImages.view.$check(embed)) {
    return <BlueskyImageEmbed images={embed.images} compact />;
  }
  // Videos as compact thumbnail
  if (embedVideo.view.$check(embed)) {
    return <BlueskyCompactVideo video={embed} />;
  }
  // External links as compact thumbnail
  if (embedExternal.view.$check(embed)) {
    return <BlueskyCompactExternal external={embed.external} />;
  }
  // Render nested quotes without "view on bluesky" link
  if (embedRecord.view.$check(embed)) {
    return <BlueskyRecordEmbed record={embed.record} nested />;
  }
  return null;
}

// Record embed union type
type RecordEmbedUnion = embedRecord.View["record"];

function BlueskyRecordEmbed({ record, nested }: { record: RecordEmbedUnion; nested?: boolean }) {
  // Handle blocked post
  if (embedRecord.viewBlocked.$check(record)) {
    return (
      <div className="BlueskyPostEmbed-quote BlueskyPostEmbed-quote--blocked">
        <div className="BlueskyPostEmbed-quoteMessage">post from blocked account</div>
      </div>
    );
  }

  // Handle not found post
  if (embedRecord.viewNotFound.$check(record)) {
    return (
      <div className="BlueskyPostEmbed-quote BlueskyPostEmbed-quote--notFound">
        <div className="BlueskyPostEmbed-quoteMessage">post not found</div>
      </div>
    );
  }

  // Handle detached post
  if (embedRecord.viewDetached.$check(record)) {
    return (
      <div className="BlueskyPostEmbed-quote BlueskyPostEmbed-quote--detached">
        <div className="BlueskyPostEmbed-quoteMessage">post has been removed</div>
      </div>
    );
  }

  // Handle feed generator
  if (feedDefs.generatorView.$check(record)) {
    return (
      <a
        href={`https://bsky.app/profile/${record.creator.handle}/feed/${record.uri.split("/").pop()}`}
        target="_blank"
        rel="noopener noreferrer"
        className="BlueskyPostEmbed-quote BlueskyPostEmbed-quote--feed"
      >
        <div className="BlueskyPostEmbed-quoteHeader">
          {record.avatar && (
            <img src={record.avatar} alt="" className="BlueskyPostEmbed-quoteAvatar" />
          )}
          <div className="BlueskyPostEmbed-quoteMeta">
            <div className="BlueskyPostEmbed-quoteName">{record.displayName}</div>
            <div className="BlueskyPostEmbed-quoteType">Feed by @{record.creator.handle}</div>
          </div>
        </div>
        {record.description && (
          <div className="BlueskyPostEmbed-quoteDescription">{record.description}</div>
        )}
      </a>
    );
  }

  // Handle list
  if ("purpose" in record && "name" in record) {
    // This is a ListView
    const listRecord = record as {
      uri: string;
      name: string;
      purpose: string;
      avatar?: string;
      description?: string;
      creator: { handle: string };
    };
    return (
      <a
        href={`https://bsky.app/profile/${listRecord.creator.handle}/lists/${listRecord.uri.split("/").pop()}`}
        target="_blank"
        rel="noopener noreferrer"
        className="BlueskyPostEmbed-quote BlueskyPostEmbed-quote--list"
      >
        <div className="BlueskyPostEmbed-quoteHeader">
          {listRecord.avatar && (
            <img src={listRecord.avatar} alt="" className="BlueskyPostEmbed-quoteAvatar" />
          )}
          <div className="BlueskyPostEmbed-quoteMeta">
            <div className="BlueskyPostEmbed-quoteName">{listRecord.name}</div>
            <div className="BlueskyPostEmbed-quoteType">List by @{listRecord.creator.handle}</div>
          </div>
        </div>
        {listRecord.description && (
          <div className="BlueskyPostEmbed-quoteDescription">{listRecord.description}</div>
        )}
      </a>
    );
  }

  // Handle regular post (viewRecord)
  if (embedRecord.viewRecord.$check(record)) {
    const author = record.author;
    const postUrl = `https://bsky.app/profile/${author.handle}/post/${record.uri.split("/").pop()}`;

    // The value contains the post record
    const postRecord = record.value as feedPost.Main | undefined;
    const text = postRecord?.text || "";

    // Check if there's media in the nested embeds
    const hasMedia = record.embeds?.some(
      (e) =>
        embedImages.view.$check(e) || embedVideo.view.$check(e) || embedExternal.view.$check(e),
    );

    return (
      <div className="BlueskyPostEmbed-quote">
        <div className="BlueskyPostEmbed-quoteHeader">
          {author.avatar ? (
            <img src={author.avatar} alt="" className="BlueskyPostEmbed-quoteAvatar" />
          ) : (
            <div className="BlueskyPostEmbed-quoteAvatar BlueskyPostEmbed-quoteAvatar--empty" />
          )}
          <div className="BlueskyPostEmbed-quoteMeta">
            <span className="BlueskyPostEmbed-quoteName">
              {author.displayName || author.handle}
            </span>
            <span className="BlueskyPostEmbed-quoteHandle">@{author.handle}</span>
          </div>
        </div>
        {hasMedia && text ? (
          <div className="BlueskyPostEmbed-quoteContent">
            <div className="BlueskyPostEmbed-quoteMedia">
              {record.embeds?.map((nestedEmbed, index) => (
                <BlueskyQuoteEmbed key={index} embed={nestedEmbed} />
              ))}
            </div>
            <div className="BlueskyPostEmbed-quoteText">{text}</div>
          </div>
        ) : (
          text && <div className="BlueskyPostEmbed-quoteText">{text}</div>
        )}
        {!nested && (
          <a
            href={postUrl}
            target="_blank"
            rel="noopener noreferrer"
            className="BlueskyPostEmbed-quoteViewLink"
          >
            view on bluesky →
          </a>
        )}
      </div>
    );
  }

  // Fallback for unknown record types (labeler, starter pack, etc.)
  return (
    <div className="BlueskyPostEmbed-quote BlueskyPostEmbed-quote--unknown">
      <div className="BlueskyPostEmbed-quoteMessage">embedded content</div>
    </div>
  );
}
