/**
 * Organization Role API
 * GET   - Fetch current user's organization role
 * PATCH - Update a member's role (OWNER only)
 * DELETE - Remove a member from the organization (OWNER only)
 *
 * All data access goes through Convex. No Prisma fallback.
 */

import { NextRequest, NextResponse } from "next/server";
import { auth } from "@/lib/auth";
import { logger } from "@/lib/logger";
import { getAuthenticatedEmail } from "@/lib/utils/auth-helpers.util";
import { convexQuery, convexMutation } from "@/lib/convex-client";
import { validateCSRFToken } from "@/lib/csrf";
import { updateMemberRoleSchema, removeMemberSchema } from "@/lib/validators/api-schemas";

export async function GET(request: NextRequest) {
  try {
    const userEmail = await getAuthenticatedEmail(request, auth);
    if (!userEmail) {
      return NextResponse.json(
        { success: false, error: "Unauthorized" },
        { status: 401 },
      );
    }

    // Find user by email in Convex
    const convexUser = await convexQuery<Record<string, unknown>>(
      "auth/queries:getUserByEmail",
      { email: userEmail.toLowerCase() },
    );

    if (!convexUser) {
      return NextResponse.json(
        { success: false, error: "User not found" },
        { status: 404 },
      );
    }

    const userId =
      (convexUser.prismaId as string) ||
      (convexUser.appUserId as string) ||
      (convexUser._id as string);

    // Check organization membership via Convex
    const orgState = await convexQuery<Record<string, unknown>>(
      "organizations/queries:getOrganizationStateByUserId",
      { userId },
    ).catch(() => null);

    if (!orgState) {
      return NextResponse.json({
        success: true,
        role: null,
        organizationId: null,
        allowedTabs: null,
        isSoloOwner: true,
      });
    }

    const userRole = orgState.userRole as string | undefined;
    const organization = orgState.organization as
      | Record<string, unknown>
      | undefined;

    if (!userRole || !organization) {
      return NextResponse.json({
        success: true,
        role: null,
        organizationId: null,
        allowedTabs: null,
        isSoloOwner: true,
      });
    }

    const { STAFF_ALLOWED_TABS, ADMIN_ALLOWED_TABS, OWNER_ALLOWED_TABS } =
      await import("@/lib/types/organization.types");

    const allowedTabs =
      userRole === "OWNER"
        ? OWNER_ALLOWED_TABS
        : userRole === "ADMIN"
          ? ADMIN_ALLOWED_TABS
          : STAFF_ALLOWED_TABS;

    const organizationId =
      (organization._id as string) || (organization.id as string);

    return NextResponse.json({
      success: true,
      role: userRole,
      organizationId,
      allowedTabs,
      isSoloOwner: false,
    });
  } catch (error: unknown) {
    logger.error(
      "[Organization Role API] Failed to fetch role",
      error instanceof Error ? error : new Error(String(error)),
    );

    return NextResponse.json(
      { success: false, error: "Failed to fetch organization role" },
      { status: 500 },
    );
  }
}

/**
 * PATCH /api/organization/role
 * Update a member's role. Only OWNER can do this.
 * Body: { targetUserId: string, newRole: "ADMIN" | "STAFF" }
 */
export async function PATCH(request: NextRequest) {
  try {
    if (!validateCSRFToken(request)) {
      return NextResponse.json(
        { success: false, error: "Invalid CSRF token" },
        { status: 403 },
      );
    }

    const userEmail = await getAuthenticatedEmail(request, auth);
    if (!userEmail) {
      return NextResponse.json(
        { success: false, error: "Unauthorized" },
        { status: 401 },
      );
    }

    const convexUser = await convexQuery<Record<string, unknown>>(
      "auth/queries:getUserByEmail",
      { email: userEmail.toLowerCase() },
    );
    if (!convexUser) {
      return NextResponse.json(
        { success: false, error: "User not found" },
        { status: 404 },
      );
    }

    const userId =
      (convexUser.prismaId as string) ||
      (convexUser.appUserId as string) ||
      (convexUser._id as string);

    // Get caller's org state to verify they're OWNER
    const orgState = await convexQuery<Record<string, unknown>>(
      "organizations/queries:getOrganizationStateByUserId",
      { userId },
    ).catch(() => null);

    if (!orgState || orgState.userRole !== "OWNER") {
      return NextResponse.json(
        { success: false, error: "Only the organization owner can change roles" },
        { status: 403 },
      );
    }

    const organization = orgState.organization as Record<string, unknown>;
    const organizationId =
      (organization._id as string) || (organization.id as string);

    const body = await request.json();
    const parsed = updateMemberRoleSchema.safeParse(body);

    if (!parsed.success) {
      return NextResponse.json(
        { success: false, error: parsed.error.errors.map(e => e.message).join(", ") },
        { status: 400 },
      );
    }

    const { targetUserId, newRole } = parsed.data;

    await convexMutation("organizations/mutations:updateMemberRole", {
      organizationId,
      userId: targetUserId,
      newRole,
    });

    return NextResponse.json({ success: true, newRole });
  } catch (error: unknown) {
    logger.error(
      "[Organization Role API] Failed to update role",
      error instanceof Error ? error : new Error(String(error)),
    );
    return NextResponse.json(
      { success: false, error: "Failed to update member role" },
      { status: 500 },
    );
  }
}

/**
 * DELETE /api/organization/role
 * Remove a member from the organization. Only OWNER can do this.
 * Body: { targetUserId: string }
 */
export async function DELETE(request: NextRequest) {
  try {
    if (!validateCSRFToken(request)) {
      return NextResponse.json(
        { success: false, error: "Invalid CSRF token" },
        { status: 403 },
      );
    }

    const userEmail = await getAuthenticatedEmail(request, auth);
    if (!userEmail) {
      return NextResponse.json(
        { success: false, error: "Unauthorized" },
        { status: 401 },
      );
    }

    const convexUser = await convexQuery<Record<string, unknown>>(
      "auth/queries:getUserByEmail",
      { email: userEmail.toLowerCase() },
    );
    if (!convexUser) {
      return NextResponse.json(
        { success: false, error: "User not found" },
        { status: 404 },
      );
    }

    const userId =
      (convexUser.prismaId as string) ||
      (convexUser.appUserId as string) ||
      (convexUser._id as string);

    const orgState = await convexQuery<Record<string, unknown>>(
      "organizations/queries:getOrganizationStateByUserId",
      { userId },
    ).catch(() => null);

    if (!orgState || orgState.userRole !== "OWNER") {
      return NextResponse.json(
        { success: false, error: "Only the organization owner can remove members" },
        { status: 403 },
      );
    }

    const organization = orgState.organization as Record<string, unknown>;
    const organizationId =
      (organization._id as string) || (organization.id as string);

    const body = await request.json();
    const parsed = removeMemberSchema.safeParse(body);

    if (!parsed.success) {
      return NextResponse.json(
        { success: false, error: parsed.error.errors.map(e => e.message).join(", ") },
        { status: 400 },
      );
    }

    const { targetUserId } = parsed.data;

    await convexMutation("organizations/mutations:removeMember", {
      organizationId,
      userId: targetUserId,
    });

    return NextResponse.json({ success: true });
  } catch (error: unknown) {
    logger.error(
      "[Organization Role API] Failed to remove member",
      error instanceof Error ? error : new Error(String(error)),
    );
    return NextResponse.json(
      { success: false, error: "Failed to remove member" },
      { status: 500 },
    );
  }
}
