import React, { useEffect, useRef, useState } from "react";
import type { Bucket } from "@/lib/client/buckets";

type BucketCardProps = {
    bucket: Bucket;
    icon?: string | null;
    openEdit: (bucketId: number) => void;
    limit: number;
    usageLabel: string;
};

const TAG_GAP_PX = 8;
const TAG_CLASS = "shrink-0 rounded-full border border-accent-weak bg-accent-soft px-2 py-0.5 text-[11px]";
const TAG_MORE_CLASS = "shrink-0 rounded-full border border-accent-weak bg-panel px-2 py-0.5 text-[11px] text-soft";

function BucketTagsRow({ tags }: { tags: string[] }) {
    const containerRef = useRef<HTMLDivElement | null>(null);
    const moreRef = useRef<HTMLSpanElement | null>(null);
    const tagRefs = useRef<(HTMLSpanElement | null)[]>([]);
    const [visibleCount, setVisibleCount] = useState(tags.length);

    useEffect(() => {
        tagRefs.current = tagRefs.current.slice(0, tags.length);
        setVisibleCount(tags.length);
    }, [tags]);

    useEffect(() => {
        if (!tags.length) return;

        function recomputeVisibleCount() {
            const containerWidth = containerRef.current?.clientWidth ?? 0;
            const widths = tags.map((_, index) => tagRefs.current[index]?.offsetWidth ?? 0);
            const moreProbe = moreRef.current;

            if (!containerWidth || !moreProbe || widths.some(width => !width)) {
                setVisibleCount(tags.length);
                return;
            }

            const totalTagsWidth = widths.reduce((sum, width) => sum + width, 0) + TAG_GAP_PX * Math.max(widths.length - 1, 0);
            if (totalTagsWidth <= containerWidth) {
                setVisibleCount(tags.length);
                return;
            }

            let nextVisibleCount = 0;
            let usedWidth = 0;

            for (let index = 0; index < widths.length; index += 1) {
                usedWidth += index === 0 ? widths[index] : TAG_GAP_PX + widths[index];
                const remaining = widths.length - (index + 1);
                if (remaining <= 0) {
                    nextVisibleCount = widths.length;
                    break;
                }

                moreProbe.textContent = `${remaining} more...`;
                const moreWidth = moreProbe.offsetWidth;
                const totalWithMore = usedWidth + TAG_GAP_PX + moreWidth;
                if (totalWithMore <= containerWidth) nextVisibleCount = index + 1;
                else break;
            }

            setVisibleCount(nextVisibleCount);
        }

        recomputeVisibleCount();

        if (typeof ResizeObserver !== "undefined") {
            const observer = new ResizeObserver(recomputeVisibleCount);
            if (containerRef.current) observer.observe(containerRef.current);
            return () => observer.disconnect();
        }

        window.addEventListener("resize", recomputeVisibleCount);
        return () => window.removeEventListener("resize", recomputeVisibleCount);
    }, [tags]);

    if (!tags.length) {
        return <span className="text-[11px] text-soft">No tags</span>;
    }

    const visibleTags = tags.slice(0, visibleCount);
    const hasOverflow = visibleCount < tags.length;
    const remainingCount = tags.length - visibleCount;

    return (
        <div className="relative w-full">
            <div ref={containerRef} className="flex min-w-0 items-center gap-2 overflow-hidden whitespace-nowrap">
                {visibleTags.map((tag, index) => (
                    <span key={`${tag}-${index}`} className={TAG_CLASS}>
                        #{tag}
                    </span>
                ))}
                {hasOverflow ? <span className={TAG_MORE_CLASS}>{remainingCount} more...</span> : null}
            </div>
            <div className="pointer-events-none absolute left-0 top-0 -z-10 opacity-0" aria-hidden="true">
                {tags.map((tag, index) => (
                    <span
                        key={`${tag}-${index}`}
                        ref={element => {
                            tagRefs.current[index] = element;
                        }}
                        className={`${TAG_CLASS} inline-block`}
                    >
                        #{tag}
                    </span>
                ))}
                <span ref={moreRef} className={`${TAG_MORE_CLASS} inline-block`}>
                    {tags.length} more...
                </span>
            </div>
        </div>
    );
}

export function BucketCard({
    bucket,
    icon,
    openEdit,
    limit,
    usageLabel,
}: BucketCardProps) {
    const spent = bucket.totalUsage || 0;
    const rawPercent = limit > 0 ? (spent / limit) * 100 : 0;
    const progressPercent = Math.max(0, Math.min(100, rawPercent));
    const progressColor = rawPercent > 100 ? "#ef4444" : rawPercent >= 80 ? "#facc15" : "#4ade80";
    const ringTrackColor = "rgba(148, 163, 184, 0.25)";

    return (
        <div
            className="w-full cursor-pointer rounded-lg border border-accent-weak bg-panel px-3 py-3 transition hover:border-accent"
            onClick={() => openEdit(bucket.id)}
        >
            <div className="flex items-start justify-between gap-3">
                <div className="flex min-w-0 items-start gap-3">
                    {limit > 0 ? (
                        <div className="relative h-11 w-11 shrink-0">
                            <div
                                className="absolute inset-0 rounded-full"
                                style={{
                                    background: `conic-gradient(${progressColor} 0% ${progressPercent}%, ${ringTrackColor} ${progressPercent}% 100%)`,
                                }}
                            />
                            <div className="absolute inset-[5px] flex items-center justify-center rounded-full border border-accent-weak bg-surface text-lg">
                                {icon || "?"}
                            </div>
                        </div>
                    ) : (
                        <div className="flex h-11 w-11 shrink-0 items-center justify-center rounded-full border border-accent-weak bg-surface text-lg">
                            {icon || "?"}
                        </div>
                    )}

                    <div className="min-w-0">
                        <div className="truncate text-sm font-semibold">{bucket.name}</div>
                        {bucket.description ? (
                            <div className="text-xs text-soft">
                                {bucket.description}
                            </div>
                        ) : null}
                    </div>
                </div>
            </div>

            <div className="mt-2 space-y-2 text-xs text-soft">
                {limit > 0 ? <div>{usageLabel}</div> : null}
                <div className="flex min-w-0 items-center">
                    <BucketTagsRow tags={bucket.tags || []} />
                </div>
            </div>
        </div>
    );
}

export default React.memo(BucketCard, (prev, next) => (
    prev.bucket === next.bucket
    && prev.icon === next.icon
    && prev.limit === next.limit
    && prev.usageLabel === next.usageLabel
));
