import type { Document } from "dbtype";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card.tsx";
import TagBadge from "@/components/gallery/TagBadge.tsx";
import { Fragment, useLayoutEffect, useRef, useState } from "react";
import { LazyImage } from "./LazyImage.tsx";
import StyledLink from "./StyledLink.tsx";
import React from "react";

function clipTagsWhenOverflow(tags: string[], limit: number) {
    let l = 0;
    for (let i = 0; i < tags.length; i++) {
        l += tags[i].length;
        if (l > limit) {
            return tags.slice(0, i);
        }
        l += 1; // for space
    }
    return tags;
}

function GalleryCardImpl({
    doc: x
}: { doc: Document; }) {
    const ref = useRef<HTMLUListElement>(null);
    const [clipCharCount, setClipCharCount] = useState(200);
    const isDeleted = x.deleted_at !== null;

    const artists = x.tags.filter(x => x.startsWith("artist:")).map(x => x.replace("artist:", ""));
    const groups = x.tags.filter(x => x.startsWith("group:")).map(x => x.replace("group:", ""));

    const originalTags = x.tags.filter(x => !x.startsWith("artist:") && !x.startsWith("group:"));
    const clippedTags = clipTagsWhenOverflow(originalTags, clipCharCount);

    useLayoutEffect(() => {
        const listener = () => {
            if (ref.current) {
                const { width } = ref.current.getBoundingClientRect();
                const charWidth = 7; // rough estimate
                const newClipCharCount = Math.floor(width / charWidth) * 3;
                setClipCharCount(newClipCharCount);
            }
        };
        listener();
        window.addEventListener("resize", listener);
        return () => {
            window.removeEventListener("resize", listener);
        };
    }, []);

    return <Card className="flex h-[200px]">
        {isDeleted ? <div className="bg-primary border flex items-center justify-center h-[200px] w-[142px] rounded-xl">
            <span className="text-primary-foreground text-lg font-bold">Deleted</span>
        </div> : <div className="rounded-xl overflow-hidden h-[200px] w-[142px] flex-none bg-[#272733] flex items-center justify-center">
            <LazyImage src={`/api/doc/${x.id}/comic/thumbnail`}
                alt={x.title}
                className="max-h-full max-w-full object-cover object-center"
            />
        </div>
        }
        <div className="flex-1 flex flex-col">
            <CardHeader className="flex-none">
                <CardTitle>
                    <StyledLink className="line-clamp-2" to={`/doc/${x.id}`}>
                        {x.title}
                    </StyledLink>
                </CardTitle>
                <CardDescription>
                    {artists.map((x, i) => <Fragment key={`artist:${x}`}>
                        <StyledLink to={`/search?allow_tag=artist:${x}`}>{x}</StyledLink>
                        {i + 1 < artists.length && <span className="opacity-50">, </span>}
                    </Fragment>)}
                    {groups.length > 0 && <span key={"sep"}>{" | "}</span>}
                    {groups.map((x, i) => <Fragment key={`group:${x}`}>
                        <StyledLink to={`/search?allow_tag=group:${x}`}>{x}</StyledLink>
                        {i + 1 < groups.length && <span className="opacity-50">, </span>}
                    </Fragment>
                    )}
                </CardDescription>
            </CardHeader>
            <CardContent className="flex-1 overflow-hidden">
                <ul ref={ref} className="flex flex-wrap gap-2 items-baseline content-start">
                    {clippedTags.map(tag => <TagBadge key={tag} tagname={tag} className="" />)}
                    {clippedTags.length < originalTags.length && <TagBadge key={"..."} tagname="..." className="inline-block" disabled />}
                </ul>
            </CardContent>
        </div>
    </Card>;
}

export const GalleryCard = React.memo(GalleryCardImpl);