import { NextRequest, NextResponse } from 'next/server';
import { and, asc, eq, inArray, isNull } from 'drizzle-orm';
import { crmRoleProfiles, memberships, msOptions } from '@/db/schema';
import { db } from '@/lib/db';
import { AuthError } from '@/lib/auth/session';
import { requireUserManagementAccess } from '../_lib';

export async function GET(request: NextRequest) {
  try {
    const { isSuperAdmin, manageableOrganizationIds } = await requireUserManagementAccess();
    const requestedOrganizationIds = request.nextUrl.searchParams
      .get('organizationIds')
      ?.split(',')
      .map((value) => value.trim())
      .filter(Boolean) ?? [];
    const organizationIds = requestedOrganizationIds.length
      ? requestedOrganizationIds
      : manageableOrganizationIds;

    if (
      !isSuperAdmin &&
      organizationIds.some((organizationId) => !manageableOrganizationIds.includes(organizationId))
    ) {
      return NextResponse.json({ message: 'Forbidden' }, { status: 403 });
    }

    const [roleProfiles, branches, productTypes] = await Promise.all([
      db
        .select({
          organizationId: crmRoleProfiles.organizationId,
          id: crmRoleProfiles.id,
          code: crmRoleProfiles.code,
          name: crmRoleProfiles.name
        })
        .from(crmRoleProfiles)
        .where(
          and(
            inArray(crmRoleProfiles.organizationId, organizationIds),
            eq(crmRoleProfiles.isActive, true),
            isNull(crmRoleProfiles.deletedAt)
          )
        )
        .orderBy(asc(crmRoleProfiles.name)),
      db
        .select({
          organizationId: msOptions.organizationId,
          id: msOptions.id,
          code: msOptions.code,
          label: msOptions.label
        })
        .from(msOptions)
        .where(
          and(
            inArray(msOptions.organizationId, organizationIds),
            eq(msOptions.category, 'crm_branch'),
            eq(msOptions.isActive, true),
            isNull(msOptions.deletedAt)
          )
        )
        .orderBy(asc(msOptions.label)),
      db
        .select({
          organizationId: msOptions.organizationId,
          id: msOptions.id,
          code: msOptions.code,
          label: msOptions.label
        })
        .from(msOptions)
        .where(
          and(
            inArray(msOptions.organizationId, organizationIds),
            eq(msOptions.category, 'crm_product_type'),
            eq(msOptions.isActive, true),
            isNull(msOptions.deletedAt)
          )
        )
        .orderBy(asc(msOptions.label))
    ]);

    const membershipsByOrganization = await db
      .select({
        organizationId: memberships.organizationId,
        userId: memberships.userId
      })
      .from(memberships)
      .where(inArray(memberships.organizationId, organizationIds));

    return NextResponse.json({
      success: true,
      roleProfiles,
      branches,
      productTypes,
      organizationUserIds: membershipsByOrganization
    });
  } catch (error) {
    if (error instanceof AuthError) {
      return NextResponse.json({ message: error.message }, { status: error.status });
    }

    return NextResponse.json(
      { message: 'Unable to load CRM role assignment reference data' },
      { status: 500 }
    );
  }
}
