// DNS profile generator — DoH URL uses per-user subdomain for iOS compatibility
import { randomUUID } from "node:crypto";
import { execSync } from "node:child_process";
import { existsSync, writeFileSync, readFileSync, unlinkSync } from "node:fs";
import { join } from "node:path";
import { tmpdir } from "node:os";
import { getProfile } from "../../db/profile";

/**
 * Generiert ein iOS/macOS .mobileconfig DNS-Profil.
 * 
 * Das Profil zeigt auf unseren eigenen DNS-Server (dns.rebreak.de),
 * der sowohl globale Blocklist als auch User-Custom-Domains blockiert.
 * 
 * Free-User: Nur eigene Custom Domains werden blockiert
 * Pro-User: Globale Blocklist + Custom Domains
 */
export default defineEventHandler(async (event) => {
  const user = await requireUser(event);
  
  // Get user plan
  const profile = await getProfile(user.id);
  const isPro = profile?.plan === "pro" || profile?.plan === "legend";
  
  const profileUUID = randomUUID().toUpperCase();
  const payloadUUID = randomUUID().toUpperCase();

  // DNS Server URL - points to our DNS proxy via per-user subdomain
  // Subdomain carries userId so iOS DoH profile has user context without query params
  // Staging: <uid>.dns-staging.rebreak.org | Prod: <uid>.rebreak.org
  const config = useRuntimeConfig();
  const isStaging = config.public.appUrl.includes("staging");
  const dnsServerUrl = isStaging
    ? `https://${user.id}.dns-staging.rebreak.org/dns-query`
    : `https://${user.id}.rebreak.org/dns-query`;

  // Get counts for description
  const { getActiveBlocklistCount, getUserCustomDomains } = await import("../../db/domains");
  const [globalCount, customDomains] = await Promise.all([
    isPro ? getActiveBlocklistCount() : Promise.resolve(0),
    getUserCustomDomains(user.id),
  ]);
  const customCount = customDomains.length;
  const totalCount = globalCount + customCount;

  const description = isPro
    ? `Aktiviert automatisches Blocking von Glücksspielseiten auf deinem Gerät. ${totalCount.toLocaleString()} Domains werden blockiert.`
    : `Aktiviert automatisches Blocking deiner personalisierten Sperrliste auf deinem Gerät. ${customCount} Domains werden blockiert.`;

  const xml = `<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>PayloadDisplayName</key>
  <string>ReBreak Schutz</string>
  <key>PayloadDescription</key>
  <string>${description}</string>
  <key>PayloadIdentifier</key>
  <string>org.rebreak.protection</string>
  <key>PayloadUUID</key>
  <string>${profileUUID}</string>
  <key>PayloadType</key>
  <string>Configuration</string>
  <key>PayloadVersion</key>
  <integer>1</integer>
  <key>PayloadContent</key>
  <array>
    <dict>
      <key>PayloadDisplayName</key>
      <string>ReBreak Schutz</string>
      <key>PayloadIdentifier</key>
      <string>org.rebreak.protection.payload</string>
      <key>PayloadUUID</key>
      <string>${payloadUUID}</string>
      <key>PayloadType</key>
      <string>com.apple.dnsSettings.managed</string>
      <key>PayloadVersion</key>
      <integer>1</integer>
      <key>DNSSettings</key>
      <dict>
        <key>DNSProtocol</key>
        <string>HTTPS</string>
        <key>ServerURL</key>
        <string>${dnsServerUrl}</string>
      </dict>
    </dict>
  </array>
</dict>
</plist>`;

  setResponseHeaders(event, {
    "Content-Type": "application/x-apple-aspen-config",
    "Content-Disposition":
      'attachment; filename="rebreak-protection.mobileconfig"',
  });

  // Cert base path based on environment
  const certBase = isStaging 
    ? "/etc/letsencrypt/live/staging.rebreak.org"
    : "/etc/letsencrypt/live/rebreak.org";
  const certFile = `${certBase}/cert.pem`;
  const keyFile = `${certBase}/privkey.pem`;
  const chainFile = `${certBase}/chain.pem`;

  if (existsSync(certFile) && existsSync(keyFile)) {
    const id = `${Date.now()}-${Math.random().toString(36).slice(2)}`;
    const tmpIn = join(tmpdir(), `rebreak-profile-${id}.xml`);
    const tmpOut = join(tmpdir(), `rebreak-profile-${id}.der`);
    try {
      writeFileSync(tmpIn, xml, "utf8");
      execSync(
        `openssl smime -sign -signer ${certFile} -inkey ${keyFile}${existsSync(chainFile) ? ` -certfile ${chainFile}` : ""} -nodetach -in ${tmpIn} -out ${tmpOut} -outform DER`,
        { stdio: "pipe", timeout: 5000 },
      );
      const signed = readFileSync(tmpOut);
      return signed;
    } catch {
      // Fallback: unsigniert (funktioniert noch, zeigt nur Warnung in iOS)
    } finally {
      try {
        unlinkSync(tmpIn);
      } catch {
        /* ignore */
      }
      try {
        unlinkSync(tmpOut);
      } catch {
        /* ignore */
      }
    }
  }

  // Unsigned fallback (Entwicklung / Zertifikat nicht verfügbar)
  return xml;
});
