import {
    GripVertical,
    LayoutTemplate,
    RotateCcw,
    Settings2,
    Sparkles,
} from "lucide-react";
import { useMemo, useState, type DragEvent } from "react";
import { Button } from "@/components/ui/button";
import { Checkbox } from "@/components/ui/checkbox";
import { Label } from "@/components/ui/label";
import {
    Sheet,
    SheetContent,
    SheetDescription,
    SheetHeader,
    SheetTitle,
    SheetTrigger,
} from "@/components/ui/sheet";
import { cn } from "@/lib/utils";

export type WidgetSetting = {
    id: string;
    label: string;
    description?: string;
};

export type WorkspacePreset = {
    id: string;
    label: string;
    description?: string;
    order: string[];
};

type Props = {
    settings: WidgetSetting[];
    value: Record<string, boolean>;
    order?: string[];
    presets?: WorkspacePreset[];
    activePresetId?: string;
    onChange: (id: string, visible: boolean) => void;
    onOrderChange?: (order: string[]) => void;
    onPresetChange?: (preset: WorkspacePreset) => void;
    onReset?: () => void;
    label?: string;
    className?: string;
};

const normalizeOrder = (settings: WidgetSetting[], order?: string[]) => {
    const known = new Set(settings.map((item) => item.id));
    const next = (order ?? []).filter((id, index, list) => {
        return known.has(id) && list.indexOf(id) === index;
    });

    settings.forEach((item) => {
        if (!next.includes(item.id)) next.push(item.id);
    });

    return next;
};

export default function AnalysisWidgetSettings({
    settings,
    value,
    order,
    presets = [],
    activePresetId,
    onChange,
    onOrderChange,
    onPresetChange,
    onReset,
    label = "Customize workspace",
    className,
}: Props) {
    const [draggedId, setDraggedId] = useState<string | null>(null);

    const orderedIds = useMemo(
        () => normalizeOrder(settings, order),
        [settings, order],
    );

    const orderedSettings = orderedIds
        .map((id) => settings.find((item) => item.id === id))
        .filter((item): item is WidgetSetting => Boolean(item));

    const moveWidget = (sourceId: string, targetId: string) => {
        if (sourceId === targetId || !onOrderChange) return;

        const next = [...orderedIds];
        const sourceIndex = next.indexOf(sourceId);
        const targetIndex = next.indexOf(targetId);
        if (sourceIndex < 0 || targetIndex < 0) return;

        next.splice(sourceIndex, 1);
        next.splice(targetIndex, 0, sourceId);
        onOrderChange(next);
    };

    const handleDrop = (event: DragEvent<HTMLDivElement>, targetId: string) => {
        event.preventDefault();
        if (draggedId) moveWidget(draggedId, targetId);
        setDraggedId(null);
    };

    return (
        <Sheet>
            <SheetTrigger asChild>
                <Button
                    type="button"
                    variant="outline"
                    size="sm"
                    className={cn(
                        "h-9 rounded-xl border-border/70 bg-background/70 px-3 text-xs font-semibold shadow-sm",
                        className,
                    )}
                >
                    <Settings2 className="size-3.5" />
                    {label}
                </Button>
            </SheetTrigger>

            <SheetContent
                side="right"
                className="w-full border-l-border/70 bg-background/95 sm:max-w-md"
            >
                <SheetHeader>
                    <div className="flex items-center gap-2">
                        <span className="flex size-8 items-center justify-center rounded-xl border border-primary/20 bg-primary/10 text-primary">
                            <LayoutTemplate className="size-4" />
                        </span>
                        <div>
                            <SheetTitle>Workspace layout</SheetTitle>
                            <SheetDescription>
                                Tampilkan, sembunyikan, dan urutkan modul sesuai cara
                                Anda membaca market.
                            </SheetDescription>
                        </div>
                    </div>
                </SheetHeader>

                {presets.length > 0 && onPresetChange && (
                    <div className="mt-6">
                        <div className="mb-2 flex items-center gap-2 px-1">
                            <Sparkles className="size-3.5 text-primary" />
                            <p className="text-[11px] font-bold uppercase tracking-[0.16em] text-muted-foreground">
                                Presets
                            </p>
                        </div>

                        <div className="grid gap-2 sm:grid-cols-3">
                            {presets.map((preset) => (
                                <button
                                    key={preset.id}
                                    type="button"
                                    onClick={() => onPresetChange(preset)}
                                    className={cn(
                                        "rounded-2xl border px-3 py-3 text-left transition-all",
                                        activePresetId === preset.id
                                            ? "border-primary/40 bg-primary/10 shadow-sm"
                                            : "border-border/60 bg-muted/10 hover:border-primary/20 hover:bg-muted/30",
                                    )}
                                    aria-pressed={activePresetId === preset.id}
                                >
                                    <span className="block text-xs font-bold text-foreground">
                                        {preset.label}
                                    </span>
                                    {preset.description && (
                                        <span className="mt-1 block text-[10px] leading-4 text-muted-foreground">
                                            {preset.description}
                                        </span>
                                    )}
                                </button>
                            ))}
                        </div>
                    </div>
                )}

                <div className="mt-6">
                    <div className="mb-2 flex items-center justify-between px-1">
                        <p className="text-[11px] font-bold uppercase tracking-[0.16em] text-muted-foreground">
                            Modules
                        </p>
                        {onOrderChange && (
                            <span className="text-[10px] text-muted-foreground">
                                Drag to reorder
                            </span>
                        )}
                    </div>

                    <div className="space-y-2">
                        {orderedSettings.map((item, index) => (
                            <div
                                key={item.id}
                                draggable={Boolean(onOrderChange)}
                                onDragStart={() => setDraggedId(item.id)}
                                onDragEnd={() => setDraggedId(null)}
                                onDragOver={(event) => {
                                    if (onOrderChange) event.preventDefault();
                                }}
                                onDrop={(event) => handleDrop(event, item.id)}
                                className={cn(
                                    "flex items-start gap-3 rounded-2xl border border-border/60 bg-card p-3.5 transition-all",
                                    draggedId === item.id &&
                                        "scale-[0.99] border-primary/30 bg-primary/5 opacity-60",
                                )}
                            >
                                {onOrderChange && (
                                    <span
                                        className="mt-0.5 flex size-7 shrink-0 cursor-grab items-center justify-center rounded-lg border border-border/60 bg-muted/30 text-muted-foreground active:cursor-grabbing"
                                        title="Drag to reorder"
                                        aria-label={`Reorder ${item.label}`}
                                    >
                                        <GripVertical className="size-3.5" />
                                    </span>
                                )}

                                <Checkbox
                                    id={`workspace-widget-${item.id}`}
                                    checked={value[item.id] !== false}
                                    onCheckedChange={(checked) =>
                                        onChange(item.id, checked === true)
                                    }
                                    className="mt-1"
                                />

                                <div className="min-w-0 flex-1">
                                    <div className="flex items-center justify-between gap-2">
                                        <Label
                                            htmlFor={`workspace-widget-${item.id}`}
                                            className="cursor-pointer text-sm font-semibold"
                                        >
                                            {item.label}
                                        </Label>
                                        <span className="text-[10px] font-bold tabular-nums text-muted-foreground">
                                            {String(index + 1).padStart(2, "0")}
                                        </span>
                                    </div>
                                    {item.description && (
                                        <p className="mt-0.5 text-xs leading-5 text-muted-foreground">
                                            {item.description}
                                        </p>
                                    )}
                                </div>
                            </div>
                        ))}
                    </div>
                </div>

                {onReset && (
                    <Button
                        type="button"
                        variant="ghost"
                        className="mt-5 w-full rounded-xl text-xs"
                        onClick={onReset}
                    >
                        <RotateCcw className="size-3.5" />
                        Reset workspace
                    </Button>
                )}
            </SheetContent>
        </Sheet>
    );
}
