import type { GridAsset } from './shared';
import { useState } from 'react';
import { Link, useSearchParams } from 'react-router';
import { CheckCircle2, Circle, Heart, Layers, Play } from 'lucide-react';
import { ASSET_PARAM, formatDuration, thumbUrl } from './shared';

// One tile in the justified grid.
//
// The tile is a real <Link> to `?asset=<id>` — the lightbox is addressable, so a photo can be cmd-clicked
// into a tab, linked to, and closed with the back button. The select checkbox is a sibling <button> layered
// over it, never nested inside the anchor: a button inside an anchor is invalid HTML and swallows the
// keyboard behaviour of both.

type AssetTileProps = {
  asset: GridAsset;
  token: string | null;
  width: number;
  height: number;
  selected: boolean;
  /** True once anything is selected — the checkbox stops being hover-only and the click selects, not opens. */
  selecting: boolean;
  onToggle: (id: string, ev: React.MouseEvent) => void;
};

export const AssetTile = ({ asset, token, width, height, selected, selecting, onToggle }: AssetTileProps) => {
  const [params] = useSearchParams();
  const [loaded, setLoaded] = useState(false);
  const duration = formatDuration(asset.duration);

  const href = (() => {
    const next = new URLSearchParams(params);
    next.set(ASSET_PARAM, asset.id);
    return `?${next.toString()}`;
  })();

  const badges = (
    <>
      {asset.isFavorite && <Heart className="absolute bottom-1.5 left-1.5 h-4 w-4 fill-white text-white drop-shadow" />}
      {asset.stackCount > 1 && (
        <span className="absolute right-1.5 top-1.5 flex items-center gap-0.5 rounded bg-black/60 px-1 text-[10px] font-medium text-white">
          <Layers className="h-3 w-3" />
          {asset.stackCount}
        </span>
      )}
      {!asset.isImage && (
        <span className="absolute bottom-1.5 right-1.5 flex items-center gap-1 rounded bg-black/60 px-1.5 py-0.5 text-[10px] font-medium text-white">
          <Play className="h-2.5 w-2.5 fill-white" />
          {duration ?? ''}
        </span>
      )}
    </>
  );

  const inner = (
    <>
      {/* A neutral block until the thumbnail decodes, so the row doesn't flash white on a dark page. */}
      <div className={`absolute inset-0 bg-white/5 transition-opacity ${loaded ? 'opacity-0' : 'opacity-100'}`} />
      <img
        src={thumbUrl(asset.id, token)}
        alt=""
        loading="lazy"
        decoding="async"
        draggable={false}
        onLoad={() => setLoaded(true)}
        className={`h-full w-full object-cover transition-opacity duration-200 ${loaded ? 'opacity-100' : 'opacity-0'}`}
      />
      {badges}
    </>
  );

  return (
    <div className="relative shrink-0 overflow-hidden rounded-sm" style={{ width, height }}>
      {selecting ? (
        // Once a selection exists, a plain click extends it rather than navigating — matching Immich, where
        // you can rubber-band through a month without the lightbox opening on every tile.
        <button
          type="button"
          onClick={(ev) => onToggle(asset.id, ev)}
          className="group absolute inset-0 block h-full w-full cursor-pointer"
        >
          {inner}
        </button>
      ) : (
        <Link to={href} className="group absolute inset-0 block h-full w-full">
          {inner}
        </Link>
      )}

      <button
        type="button"
        onClick={(ev) => onToggle(asset.id, ev)}
        title={selected ? 'Deselect' : 'Select'}
        className={`absolute left-1.5 top-1.5 rounded-full text-white transition-opacity ${
          selected ? 'opacity-100' : 'opacity-0 hover:opacity-100 focus-visible:opacity-100'
        } ${selecting ? 'opacity-100' : ''}`}
      >
        {selected ? (
          <CheckCircle2 className="h-5 w-5 fill-primary text-white" />
        ) : (
          <Circle className="h-5 w-5 drop-shadow" />
        )}
      </button>

      {selected && <span className="pointer-events-none absolute inset-0 rounded-sm ring-2 ring-inset ring-primary" />}
    </div>
  );
};
