import { NextRequest, NextResponse } from "next/server";
import { auth, clerkClient } from "@clerk/nextjs/server";
import { db, users, clients } from "@fitai/database";
import { createUserSchema } from "@/lib/validation/user-schemas";
import { sendWelcomeEmail, sendInvitationEmail } from "@/lib/email";
import {
  successResponse,
  errorResponse,
  unauthorizedResponse,
} from "@/lib/api/responses";
import log from "@/lib/logger";

/**
 * POST /api/users/create
 *
 * Create a new user with support for:
 * - Direct creation (database only, no Clerk account)
 * - Invitation-based creation (sends Clerk invitation email)
 * - Client-specific fields (membership type, status)
 * - Welcome emails for clients
 */
export async function POST(request: NextRequest) {
  try {
    const { userId } = await auth();
    if (!userId) {
      return unauthorizedResponse("Unauthorized");
    }

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

    if (!validationResult.success) {
      return errorResponse("Validation failed", {
        status: 400,
        details: validationResult.error.flatten().fieldErrors as Record<
          string,
          string[]
        >,
      });
    }

    const data = validationResult.data;

    // Note: Email is required in current schema
    // TODO: Add schema migration to make email optional for direct creation
    if (!data.email) {
      return errorResponse("Email is required", { status: 400 });
    }

    // Case 1: Send Clerk Invitation (requires email)
    if (data.sendInvitation && data.email) {
      try {
        const client = await clerkClient();
        const invitation = await client.invitations.createInvitation({
          emailAddress: data.email,
          publicMetadata: {
            role: data.role,
            gymId: data.gymId,
          },
        });

        log.info("Clerk invitation sent", {
          email: data.email,
          role: data.role,
          invitationId: invitation.id,
        });

        // Send custom invitation email (in addition to Clerk's)
        if (invitation.url) {
          await sendInvitationEmail(data.email, data.role, invitation.url);
        }

        return successResponse(
          {
            invitation: {
              id: invitation.id,
              email: invitation.emailAddress,
              status: invitation.status,
            },
          },
          { status: 200 },
        );
      } catch (error: unknown) {
        const errorMessage =
          error instanceof Error ? error.message : "Unknown error";
        log.error("Failed to send Clerk invitation", error);
        return errorResponse(`Failed to send invitation: ${errorMessage}`, {
          status: 500,
        });
      }
    }

    // Case 2: Direct Creation (database only, no Clerk account)
    // This creates a user record that can later be linked when they sign up

    // Generate a temporary user ID (will be replaced when they sign up with Clerk)
    const tempUserId = `temp_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;

    // Insert user into database
    const [newUser] = await db
      .insert(users)
      .values({
        id: tempUserId,
        email: data.email,
        firstName: data.firstName,
        lastName: data.lastName,
        role: data.role,
        phone: data.phone,
        gymId: data.gymId,
      })
      .returning();

    log.info("User created in database", {
      userId: newUser.id,
      role: data.role,
      hasEmail: !!data.email,
    });

    // Case 3: Create client record if role is client
    if (data.role === "client" && data.membershipType) {
      const clientId = `client_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;

      await db.insert(clients).values({
        id: clientId,
        userId: newUser.id,
        membershipType: data.membershipType,
        membershipStatus: data.membershipStatus || "active",
        joinDate: new Date(),
      });

      log.info("Client record created", {
        userId: newUser.id,
        membershipType: data.membershipType,
      });

      // Send welcome email if requested and email provided
      if (data.sendWelcomeEmail && data.email) {
        await sendWelcomeEmail(data.email, data.firstName);
        log.info("Welcome email sent", { email: data.email });
      }
    }

    return successResponse(
      {
        user: {
          id: newUser.id,
          email: newUser.email,
          firstName: newUser.firstName,
          lastName: newUser.lastName,
          role: newUser.role,
        },
      },
      { status: 201 },
    );
  } catch (error) {
    log.error("Failed to create user", error);
    return errorResponse("Failed to create user", { status: 500 });
  }
}
