import { listMagicDevices } from "../../db/devices";
import { listProtectedDevices } from "../../db/protectedDevices";
import { usePrisma } from "../../utils/prisma";
import { requireUser } from "../../utils/auth";

/**
 * GET /api/magic/devices
 *
 * Vereinigt drei Quellen f\u00fcr "registriertes Ger\u00e4t":
 * - "magic"      \u2192 UserDevice mit magicEnrolledAt (Magic-Mac-App)
 * - "locked"     \u2192 UserDevice mit boundToPlan (Native-App Device-Lock, z.B. iPhone/iPad)
 * - "protected"  \u2192 ProtectedDevice (alter Native-App DNS-Schutz-Flow)
 *
 * Dedupe: ProtectedDevice wird unterdr\u00fcckt wenn bereits ein UserDevice
 * mit \u00e4hnlichem Namen + gleicher Plattform existiert (verhindert MacBook-Doppel).
 */
export default defineEventHandler(async (event) => {
  const user = await requireUser(event);
  const db = usePrisma();

  const [magic, lockedDevices, protectedDevices] = await Promise.all([
    listMagicDevices(user.id),
    db.userDevice.findMany({
      where: {
        userId: user.id,
        // Alle Native-App-Geräte des Users \u2014 KEINE magic-only Rows
        // (die kommen über `magic`). Lock-Status ist egal: free/legend, alle
        // Native-App-Devices sollen im Hub erscheinen.
        magicEnrolledAt: null,
      },
      orderBy: [{ lastSeenAt: "desc" }, { createdAt: "desc" }],
      select: {
        id: true,
        deviceId: true,
        platform: true,
        model: true,
        name: true,
        osVersion: true,
        mdmId: true,
        lastSeenAt: true,
        releaseRequestedAt: true,
      },
    }),
    listProtectedDevices(user.id),
  ]);

  const now = new Date();
  const magicItems = magic.map((d) => {
    let releaseAvailableAt: string | null = null;
    if (d.releaseRequestedAt) {
      releaseAvailableAt = new Date(
        d.releaseRequestedAt.getTime() + 24 * 60 * 60 * 1000,
      ).toISOString();
    }

    const inCooldown = d.magicCooldownUntil && d.magicCooldownUntil > now;
    const status = d.magicRevokedAt
      ? "revoked"
      : inCooldown
        ? "cooldown"
        : d.magicEnrolledAt
          ? "active"
          : "pending";

    return {
      source: "magic" as const,
      deviceId: d.deviceId,
      hostname: d.hostname ?? "Unbenanntes Ger\u00e4t",
      model: d.model,
      osVersion: d.osVersion,
      magicEnrolledAt: d.magicEnrolledAt?.toISOString() ?? null,
      releaseRequestedAt: d.releaseRequestedAt?.toISOString() ?? null,
      releaseAvailableAt,
      cooldownUntil: d.magicCooldownUntil?.toISOString() ?? null,
      status,
      lastSeenAt: d.lastSeenAt?.toISOString() ?? null,
      mdmId: d.mdmId,
    };
  });

  const lockedItems = lockedDevices.map((d) => {
    let releaseAvailableAt: string | null = null;
    if (d.releaseRequestedAt) {
      releaseAvailableAt = new Date(
        d.releaseRequestedAt.getTime() + 24 * 60 * 60 * 1000,
      ).toISOString();
    }
    return {
      source: "locked" as const,
      deviceId: d.deviceId,
      hostname: d.name ?? d.model ?? prettyPlatform(d.platform),
      model: d.model,
      osVersion: d.osVersion,
      magicEnrolledAt: d.lastSeenAt.toISOString(),
      releaseRequestedAt: d.releaseRequestedAt?.toISOString() ?? null,
      releaseAvailableAt,
      status: "active" as const,
      lastSeenAt: d.lastSeenAt?.toISOString() ?? null,
      cooldownUntil: null,
      mdmId: d.mdmId,
    };
  });

  // Dedupe Helper \u2014 normalisiere platform + name f\u00fcr Vergleich
  const norm = (s: string | null | undefined) =>
    (s ?? "").toLowerCase().replace(/[^a-z0-9]/g, "");
  const platformKey = (p: string | null | undefined) => {
    const n = norm(p);
    if (n.startsWith("mac") || n === "darwin") return "mac";
    if (n.startsWith("ios") || n.startsWith("ipad") || n.startsWith("iphone"))
      return "ios";
    if (n.startsWith("android")) return "android";
    if (n.startsWith("windows") || n === "win") return "win";
    return n;
  };

  const alreadyListed = [...magicItems, ...lockedItems].map((d) => ({
    pk: platformKey(d.model ?? d.hostname),
    nameNorm: norm(d.hostname),
  }));

  const protectedItems = protectedDevices
    .filter((pd) => {
      const pk = platformKey(pd.platform);
      const labelNorm = norm(pd.label);
      const dup = alreadyListed.some((u) => {
        if (u.pk !== pk) return false;
        if (!u.nameNorm || !labelNorm) return u.pk === pk;
        return (
          u.nameNorm.includes(labelNorm) || labelNorm.includes(u.nameNorm)
        );
      });
      return !dup;
    })
    .map((d) => ({
      source: "protected" as const,
      deviceId: d.id,
      hostname: d.label,
      model: d.platform,
      osVersion: null as string | null,
      magicEnrolledAt: (d.installedAt ?? d.createdAt).toISOString(),
      releaseRequestedAt: null as string | null,
      releaseAvailableAt: null as string | null,
      status: "active" as const,
      lastSeenAt: null,
      cooldownUntil: null,
    }));

  return {
    success: true,
    data: [...magicItems, ...lockedItems, ...protectedItems],
  };
});

function prettyPlatform(p: string): string {
  switch (p.toLowerCase()) {
    case "ios":
      return "iPhone / iPad";
    case "android":
      return "Android-Ger\u00e4t";
    case "mac":
    case "macos":
    case "darwin":
      return "Mac";
    default:
      return p;
  }
}
