/**
 * Organization Stripe Keys Validation API
 *
 * POST /api/settings/stripe-keys/validate - Validate Stripe keys without saving
 *
 * Only accessible to organization owners/admins (authenticated users).
 */

import { NextRequest, NextResponse } from "next/server";
import { auth } from "@/lib/auth";
import { stripeKeysService } from "@/lib/services/stripe-keys.service";
import { prisma } from "@/lib/db";
import { logger } from "@/lib/logger";
import { z } from "zod";

/**
 * Helper to check if user can manage Stripe settings
 */
async function canManageStripe(userId: string): Promise<boolean> {
  // Check if user owns an organization
  const ownedOrg = await prisma.organizations.findUnique({
    where: { ownerId: userId },
    select: { id: true },
  });

  if (ownedOrg) {
    return true;
  }

  // Check if user is an admin member of an organization
  const membership = await prisma.organization_members.findFirst({
    where: {
      userId,
      role: { in: ["OWNER", "ADMIN"] },
    },
    select: { organizationId: true },
  });

  return !!membership;
}

// Validation schema
const validateKeysSchema = z.object({
  secretKey: z
    .string()
    .min(10, "Secret key is required")
    .refine(
      (key) => key.startsWith("sk_test_") || key.startsWith("sk_live_"),
      "Secret key must start with sk_test_ or sk_live_",
    ),
  publishableKey: z
    .string()
    .min(10, "Publishable key is required")
    .refine(
      (key) => key.startsWith("pk_test_") || key.startsWith("pk_live_"),
      "Publishable key must start with pk_test_ or pk_live_",
    ),
});

/**
 * POST /api/settings/stripe-keys/validate
 * Validate Stripe keys without saving
 */
export async function POST(request: NextRequest) {
  try {
    // Authenticate user
    const session = await auth();
    if (!session?.user?.id) {
      return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
    }

    // Check permissions
    const hasPermission = await canManageStripe(session.user.id);
    if (!hasPermission) {
      return NextResponse.json(
        {
          valid: false,
          error:
            "Only organization owners and admins can validate payment settings.",
        },
        { status: 403 },
      );
    }

    const body = await request.json();
    const validationResult = validateKeysSchema.safeParse(body);

    if (!validationResult.success) {
      return NextResponse.json(
        {
          valid: false,
          error: "Invalid request: " + validationResult.error.errors[0].message,
        },
        { status: 400 },
      );
    }

    const { secretKey, publishableKey } = validationResult.data;

    // Validate that key modes match (test/live)
    const secretMode = secretKey.startsWith("sk_test_") ? "test" : "live";
    const publishableMode = publishableKey.startsWith("pk_test_")
      ? "test"
      : "live";

    if (secretMode !== publishableMode) {
      return NextResponse.json({
        valid: false,
        mode: secretMode,
        error:
          "Key mode mismatch: secret key and publishable key must both be test or both be live",
      });
    }

    // Validate keys with Stripe API
    const validation = await stripeKeysService.validateKeys(
      secretKey,
      publishableKey,
    );

    if (!validation.valid) {
      logger.warn("Stripe key validation failed", {
        userId: session.user.id,
        error: validation.error,
      });

      return NextResponse.json({
        valid: false,
        mode: validation.mode,
        error: validation.error || "Invalid Stripe keys",
      });
    }

    logger.info("Stripe keys validated successfully by org admin", {
      userId: session.user.id,
      mode: validation.mode,
      accountName: validation.accountName,
    });

    return NextResponse.json({
      valid: true,
      mode: validation.mode,
      accountName: validation.accountName,
    });
  } catch (error) {
    logger.error("Failed to validate Stripe keys", { error });
    return NextResponse.json(
      {
        valid: false,
        error:
          error instanceof Error
            ? error.message
            : "Failed to validate Stripe keys",
      },
      { status: 500 },
    );
  }
}
