import type { CSSProperties } from "react";
import Image from "next/image";
import { Copy, ImageIcon, LockKeyhole } from "lucide-react";

import { CharacterAvatar } from "@/app/_components";
import type { PrivateAlbum } from "@/data/schemas/private-zone";
import { isPrivateAlbumLocked } from "@/lib/private-zone/private_album";

import {
  getPrivateAlbumDisplayImages,
  getPrivateAlbumGridLayout,
  PRIVATE_ALBUM_GRID_LIMIT,
} from "../private-album-images";

import styles from "../private-zone-screen.module.css";

export interface PrivateAlbumCardProps {
  album: PrivateAlbum;
  displayName: string;
  avatarUrl: string;
  index: number;
  isUnlocking: boolean;
  onOpenGallery: (imageIndex: number) => void;
  onUnlock: () => void;
}

export function PrivateAlbumCard({
  album,
  displayName,
  avatarUrl,
  index,
  isUnlocking,
  onOpenGallery,
  onUnlock,
}: PrivateAlbumCardProps) {
  const isLocked = isPrivateAlbumLocked(album);
  const firstImage = album.images[0];
  const firstImageUrl = firstImage?.url || null;
  const photoCount = album.imageCount || album.images.length;
  const displayImages = getPrivateAlbumDisplayImages(album);
  const previewImages = displayImages.slice(0, PRIVATE_ALBUM_GRID_LIMIT);
  const gridLayout = getPrivateAlbumGridLayout(previewImages.length);
  const overflowCount = Math.max(
    0,
    displayImages.length - PRIVATE_ALBUM_GRID_LIMIT,
  );
  const gridLayoutClassName =
    gridLayout === "single"
      ? styles.mediaGridSingle
      : gridLayout === "double"
        ? styles.mediaGridDouble
        : styles.mediaGridTriple;

  return (
    <article
      className={styles.postCard}
      style={{ "--reveal-index": index } as CSSProperties}
    >
      <header className={styles.postHeader}>
        <div className={styles.postAuthor}>
          <CharacterAvatar
            src={avatarUrl}
            alt=""
            size={38}
            imageSize={38}
            className={styles.postAvatar}
          />
          <div>
            <p className={styles.authorName}>{displayName}</p>
            <p className={styles.authorSubline}>
              {album.title || "Private album"}
            </p>
          </div>
        </div>
        <time className={styles.postTime}>
          {formatAlbumTime(album.publishedAt)}
        </time>
      </header>

      {isLocked ? (
        <div className={styles.lockedPreview}>
          <div className={styles.lockedPreviewBackdrop} aria-hidden="true">
            {firstImageUrl ? (
              <Image
                src={firstImageUrl}
                alt=""
                fill
                sizes="(max-width: 540px) calc(100vw - 36px), 484px"
                className={styles.lockedCoverImage}
              />
            ) : null}
            <span className={styles.lockedPreviewScrim} />
          </div>
          <div className={styles.lockedPreviewPanel}>
            <span className={styles.lockedCollectionIcon} aria-hidden="true">
              <Copy size={17} strokeWidth={2} />
            </span>

            <div
              className={styles.lockedPreviewAvatarFrame}
              role="img"
              aria-label={`${displayName} locked collection`}
            >
              <CharacterAvatar
                src={avatarUrl}
                alt=""
                size="100%"
                imageSize={72}
                className={styles.lockedPreviewAvatar}
              />
              <span className={styles.lockedAvatarBadge} aria-hidden="true">
                <LockKeyhole size={15} strokeWidth={2.2} />
              </span>
            </div>

            <div className={styles.lockedPreviewContent}>
              <strong className={styles.lockedPreviewTitle}>Unlock to view</strong>
              <span className={styles.lockedImageCount}>
                <ImageIcon size={19} strokeWidth={1.9} aria-hidden="true" />
                {photoCount} {photoCount === 1 ? "Image" : "Images"}
              </span>
              <button
                type="button"
                data-analytics-key="private_album.unlock"
                data-analytics-label="Unlock private album"
                className={styles.lockedPreviewCta}
                disabled={isUnlocking}
                onClick={onUnlock}
                aria-label={`View locked collection with ${photoCount} ${photoCount === 1 ? "image" : "images"} from ${displayName}`}
              >
                {isUnlocking ? "Opening..." : "View collection"}
              </button>
            </div>
          </div>
        </div>
      ) : previewImages.length > 0 ? (
        <div
          className={`${styles.mediaGrid} ${gridLayoutClassName}`}
          data-grid-layout={gridLayout}
          data-image-count={displayImages.length}
        >
          {previewImages.map((image, imagePosition) => (
            <button
              type="button"
              key={`${image.sourceIndex}:${image.url}`}
              data-analytics-key="private_album.open_gallery"
              data-analytics-label="Open private album gallery"
              data-image-index={image.sourceIndex}
              className={styles.mediaGridItem}
              onClick={() => onOpenGallery(image.sourceIndex)}
              aria-label={`Open photo ${imagePosition + 1} of ${displayImages.length} from ${displayName}`}
            >
              <Image
                src={image.url}
                alt=""
                fill
                sizes={getGridImageSizes(gridLayout)}
                className={styles.mediaGridImage}
              />
              {imagePosition === PRIVATE_ALBUM_GRID_LIMIT - 1 &&
              overflowCount > 0 ? (
                <span className={styles.mediaGridOverflow} aria-hidden="true">
                  +{overflowCount}
                </span>
              ) : null}
            </button>
          ))}
        </div>
      ) : (
        <div
          className={styles.emptyMediaCover}
          role="img"
          aria-label="No private album photo available"
        >
          <ImageIcon size={32} aria-hidden="true" />
          <span>No photo available</span>
        </div>
      )}

      {album.content ? <p className={styles.postText}>{album.content}</p> : null}
    </article>
  );
}

function getGridImageSizes(layout: string): string {
  if (layout === "single") return "(max-width: 540px) 68vw, 280px";
  if (layout === "double") return "(max-width: 540px) 34vw, 154px";
  return "(max-width: 540px) 29vw, 150px";
}

function formatAlbumTime(value: string | null): string {
  if (!value) return "";
  const date = new Date(value);
  if (Number.isNaN(date.getTime())) return "";
  return date.toLocaleDateString(undefined, {
    month: "short",
    day: "numeric",
  });
}
