/**
 * POST /api/demo-token
 *
 * Password-protected endpoint for sales to generate 60-day
 * enterprise trial tokens for prospects.
 */

import type { Context } from "hono";
import type { Env } from "../env.d";
import { signLicenseToken } from "../lib/sign-token";
import { sendEmail } from "../lib/send-email";
import { demoEmail } from "../templates/license-email";

const EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;

interface DemoTokenRequest {
  prospect_name: string;
  prospect_email?: string;
  password: string;
}

function slugify(name: string): string {
  return name
    .toLowerCase()
    .trim()
    .replace(/[^a-z0-9]+/g, "-")
    .replace(/^-|-$/g, "");
}

export async function handleDemoToken(c: Context): Promise<Response> {
  const env = c.env as Env;

  let body: DemoTokenRequest;
  try {
    body = await c.req.json();
  } catch {
    return c.json({ error: "Invalid JSON body" }, 400);
  }

  // Validate required fields
  if (!body.prospect_name?.trim()) {
    return c.json({ error: "prospect_name is required" }, 400);
  }
  if (!body.password) {
    return c.json({ error: "password is required" }, 400);
  }

  // Auth check — constant-time comparison to prevent timing attacks
  const pwBytes = new TextEncoder().encode(body.password);
  const expectedBytes = new TextEncoder().encode(env.DEMO_PASSWORD);
  if (
    pwBytes.byteLength !== expectedBytes.byteLength ||
    !crypto.subtle.timingSafeEqual(pwBytes, expectedBytes)
  ) {
    return c.json({ error: "Invalid password" }, 401);
  }

  // Sign a 60-day enterprise trial token
  const slug = slugify(body.prospect_name);
  if (!slug) {
    return c.json({ error: "prospect_name must contain alphanumeric characters" }, 400);
  }
  const result = await signLicenseToken(
    {
      sub: `demo-${slug}`,
      tier: "enterprise",
      seats: 5,
      days: 60,
    },
    env.SIGNING_PRIVATE_KEY
  );

  // Optionally email the token to the prospect
  let emailed = false;
  if (body.prospect_email?.trim() && !EMAIL_RE.test(body.prospect_email.trim())) {
    return c.json({ error: "Invalid email address" }, 400);
  }
  if (body.prospect_email?.trim() && env.RESEND_API_KEY) {
    try {
      await sendEmail(
        {
          to: body.prospect_email.trim(),
          subject: "Your StyloBridge Enterprise Trial (60 days)",
          html: demoEmail({
            prospectName: body.prospect_name.trim(),
            token: result.token,
            expires: new Date(result.expires).toLocaleDateString("en-US", {
              year: "numeric",
              month: "long",
              day: "numeric",
            }),
          }),
        },
        env.RESEND_API_KEY
      );
      emailed = true;
    } catch (err) {
      // Token was generated successfully — don't fail the whole request
      console.error("Failed to send demo email:", err);
    }
  }

  return c.json({
    token: result.token,
    expires: result.expires,
    sub: `demo-${slug}`,
    emailed,
  });
}
