"use client";

import { useState } from "react";
import { DragDropProvider } from "@dnd-kit/react";
import { useSortable } from "@dnd-kit/react/sortable";
import { move } from "@dnd-kit/helpers";
import type { AppEntry, AppCategory } from "@/lib/types";
import { AppTile } from "./AppTile";

interface AppGridProps {
  apps: AppEntry[];
  order: string[];
  categories: AppCategory[];
  onEditApp: (app: AppEntry) => void;
  onReorder: (order: string[]) => void;
}

function SortableAppTile({
  app,
  index,
  categoryName,
  onEdit,
}: {
  app: AppEntry;
  index: number;
  categoryName?: string;
  onEdit: (app: AppEntry) => void;
}) {
  const { ref, isDragging } = useSortable({
    id: app.id,
    index,
  });

  return (
    <div
      ref={ref}
      className={`transition-opacity ${isDragging ? "opacity-50" : ""}`}
      style={{ touchAction: "none" }}
    >
      <AppTile app={app} categoryName={categoryName} onEdit={onEdit} />
    </div>
  );
}

function sortApps(apps: AppEntry[], order: string[]): AppEntry[] {
  const appMap = new Map(apps.map((a) => [a.id, a]));
  const sorted: AppEntry[] = [];

  // Add apps in order
  for (const id of order) {
    const app = appMap.get(id);
    if (app) {
      sorted.push(app);
      appMap.delete(id);
    }
  }

  // Append remaining apps not in order
  for (const app of appMap.values()) {
    sorted.push(app);
  }

  return sorted;
}

export function AppGrid({
  apps,
  order,
  categories,
  onEditApp,
  onReorder,
}: AppGridProps) {
  const sortedApps = sortApps(apps, order);
  const [items, setItems] = useState<string[]>(() => sortedApps.map((a) => a.id));

  // Keep items in sync when apps/order change externally
  const currentIds = sortedApps.map((a) => a.id);
  const itemsKey = currentIds.join(",");
  const [prevKey, setPrevKey] = useState(itemsKey);
  if (itemsKey !== prevKey) {
    setItems(currentIds);
    setPrevKey(itemsKey);
  }

  const categoryMap = new Map(categories.map((c) => [c.id, c.name]));

  // Build ordered app list from items state (for rendering during drag)
  const appMap = new Map(apps.map((a) => [a.id, a]));
  const orderedApps = items
    .map((id) => appMap.get(id))
    .filter((a): a is AppEntry => a !== undefined);

  return (
    <DragDropProvider
      onDragEnd={(event) => {
        const newItems = move(items, event);
        setItems(newItems);
        onReorder(newItems);
      }}
    >
      <div className="grid grid-cols-2 gap-4 p-4 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 xl:grid-cols-6">
        {orderedApps.map((app, index) => (
          <SortableAppTile
            key={app.id}
            app={app}
            index={index}
            categoryName={categoryMap.get(app.categoryId)}
            onEdit={onEditApp}
          />
        ))}
      </div>
    </DragDropProvider>
  );
}
