import { Trophy } from "lucide-react";
import type { CategoryPoint, SalesPoint, TrendPoint } from "@/types/dashboard";
import { money } from "@/lib/dashboard";

export function MiniTrend({ data }: { data: TrendPoint[] }) {
    const values = data.map((item) => item.value);
    const max = Math.max(...values, 1);
    const min = Math.min(...values, 0);
    const width = 700;
    const height = 220;
    const paddingX = 28;
    const paddingY = 28;
    const range = Math.max(max - min, 1);
    const points = data.map((item, index) => {
        const x =
            paddingX +
            (index * (width - paddingX * 2)) / Math.max(data.length - 1, 1);
        const y =
            height -
            paddingY -
            ((item.value - min) / range) * (height - paddingY * 2);
        return { x, y };
    });
    const line = points.map((point) => `${point.x},${point.y}`).join(" ");
    const area = `${paddingX},${height - paddingY} ${line} ${width - paddingX},${height - paddingY}`;

    return (
        <div className="relative mt-2 w-full overflow-hidden">
            <svg
                viewBox={`0 0 ${width} ${height}`}
                className="h-56 w-full overflow-visible"
                role="img"
                aria-label="Grafik penjualan periode terpilih"
            >
                <defs>
                    <linearGradient id="sales-area" x1="0" x2="0" y1="0" y2="1">
                        <stop
                            offset="0%"
                            stopColor="#6366f1"
                            stopOpacity="0.35"
                        />
                        <stop
                            offset="100%"
                            stopColor="#6366f1"
                            stopOpacity="0"
                        />
                    </linearGradient>
                    <linearGradient
                        id="line-gradient"
                        x1="0"
                        x2="1"
                        y1="0"
                        y2="0"
                    >
                        <stop offset="0%" stopColor="#6366f1" />
                        <stop offset="100%" stopColor="#3b82f6" />
                    </linearGradient>
                </defs>
                {[0, 1, 2, 3].map((row) => {
                    const y = paddingY + (row * (height - paddingY * 2)) / 3;
                    return (
                        <line
                            key={row}
                            x1={paddingX}
                            x2={width - paddingX}
                            y1={y}
                            y2={y}
                            stroke="currentColor"
                            className="text-slate-200/60 dark:text-slate-800/80"
                            strokeDasharray="4 4"
                        />
                    );
                })}
                <polygon points={area} fill="url(#sales-area)" />
                <polyline
                    points={line}
                    fill="none"
                    stroke="url(#line-gradient)"
                    strokeWidth="3.5"
                    strokeLinecap="round"
                    strokeLinejoin="round"
                />
                {points.map((point, index) => (
                    <g key={data[index].label} className="group cursor-pointer">
                        <circle
                            cx={point.x}
                            cy={point.y}
                            r="6"
                            className="fill-white stroke-indigo-600 transition-all duration-200 group-hover:r-8 dark:fill-slate-900 dark:stroke-indigo-400"
                            strokeWidth="3"
                        />
                        <text
                            x={point.x}
                            y={height - 4}
                            textAnchor="middle"
                            className="fill-slate-400 text-[11px] font-semibold tracking-tight"
                        >
                            {data[index].label}
                        </text>
                    </g>
                ))}
            </svg>
        </div>
    );
}

export function DonutChart({
    data,
    total,
}: {
    data: CategoryPoint[];
    total: number;
}) {
    const palette = ["#6366f1", "#10b981", "#f59e0b", "#8b5cf6", "#64748b"];
    const sum =
        data.reduce((acc, item) => acc + Number(item.value || 0), 0) || 1;
    let cursor = 0;
    const stops = data.map((item, index) => {
        const start = cursor;
        cursor += (Number(item.value || 0) / sum) * 360;
        return `${palette[index % palette.length]} ${start}deg ${cursor}deg`;
    });

    return (
        <div className="flex h-56 w-full items-center justify-center gap-6">
            <div
                className="relative size-36 shrink-0 rounded-full shadow-lg sm:size-40 transition-transform hover:scale-105"
                style={{ background: `conic-gradient(${stops.join(", ")})` }}
            >
                <div className="absolute inset-4 flex flex-col items-center justify-center rounded-full bg-white shadow-inner dark:bg-slate-900">
                    <span className="text-[10px] font-bold uppercase tracking-widest text-slate-400">
                        Total
                    </span>
                    <strong className="mt-0.5 max-w-28 truncate text-xs font-black tracking-tight text-slate-900 dark:text-slate-100">
                        {money(total)}
                    </strong>
                </div>
            </div>
            <div className="min-w-0 flex-1 space-y-2.5">
                {data.map((item, index) => (
                    <div
                        key={item.name}
                        className="flex items-center gap-2 text-xs"
                    >
                        <span
                            className="size-3 shrink-0 rounded-md shadow-xs"
                            style={{
                                backgroundColor:
                                    palette[index % palette.length],
                            }}
                        />
                        <span className="min-w-0 flex-1 truncate font-medium text-slate-600 dark:text-slate-400">
                            {item.name}
                        </span>
                        <strong className="font-bold text-slate-900 dark:text-slate-100">
                            {Math.round((Number(item.value || 0) / sum) * 100)}%
                        </strong>
                    </div>
                ))}
            </div>
        </div>
    );
}

export function Leaderboard({ data }: { data: SalesPoint[] }) {
    const badgeColors = [
        "bg-amber-500 text-white shadow-md shadow-amber-500/20 border-amber-400",
        "bg-slate-400 text-white shadow-md shadow-slate-400/20 border-slate-300",
        "bg-amber-700 text-white shadow-md shadow-amber-700/20 border-amber-600",
    ];

    return (
        <div className="h-56 space-y-2.5 overflow-y-auto pr-1">
            {data.slice(0, 5).map((sales, index) => (
                <div
                    key={sales.id || index}
                    className="flex items-center justify-between rounded-xl border border-slate-200/60 bg-slate-50/60 p-2.5 transition-all hover:border-slate-300 hover:bg-white hover:shadow-xs dark:border-slate-800/80 dark:bg-slate-800/30 dark:hover:border-slate-700 dark:hover:bg-slate-800/80"
                >
                    <div className="flex items-center gap-3">
                        <div
                            className={`flex size-8 shrink-0 items-center justify-center rounded-lg border text-xs font-black ${
                                badgeColors[index] ||
                                "border-slate-200 bg-white text-slate-600 dark:border-slate-800 dark:bg-slate-900 dark:text-slate-400"
                            }`}
                        >
                            {index === 0 ? (
                                <Trophy className="size-4 text-white" />
                            ) : (
                                index + 1
                            )}
                        </div>
                        <div className="min-w-0">
                            <p className="truncate text-xs font-bold text-slate-900 dark:text-slate-100">
                                {sales.name}
                            </p>
                            <p className="text-[10px] font-medium text-slate-400">
                                {sales.visits} Kunjungan
                            </p>
                        </div>
                    </div>
                    <div className="text-right">
                        <p className="text-xs font-black tracking-tight text-slate-900 dark:text-slate-100">
                            {money(sales.sales)}
                        </p>
                        <p className="text-[10px] font-semibold text-emerald-600 dark:text-emerald-400">
                            {sales.performance}% relatif
                        </p>
                    </div>
                </div>
            ))}
        </div>
    );
}
