import { eq, inArray } from 'drizzle-orm';
import { NextRequest, NextResponse } from 'next/server';
import { memberships, organizations, users } from '@/db/schema';
import { getDefaultPermissions } from '@/lib/auth/rbac';
import { AuthError, requireSession, requireSystemRole } from '@/lib/auth/session';
import { db } from '@/lib/db';

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

export async function GET(request: NextRequest) {
  try {
    const session = await requireSession();
    const scope = request.nextUrl.searchParams.get('scope');

    if (session.user.systemRole === 'super_admin') {
      const rows = await db.select().from(organizations);

      return NextResponse.json({
        organizations: rows.map((organization) => ({
          id: organization.id,
          name: organization.name,
          slug: organization.slug,
          plan: organization.plan,
          imageUrl: organization.imageUrl,
          role: 'admin',
          businessRole: 'sales_manager',
          canManageUsers: true
        }))
      });
    }

    const membershipRows = await db.query.memberships.findMany({
      where: eq(memberships.userId, session.user.id)
    });

    const filteredMemberships =
      scope === 'manageable'
        ? membershipRows.filter((membership) => membership.role === 'admin')
        : membershipRows;

    if (!filteredMemberships.length) {
      return NextResponse.json({ organizations: [] });
    }

    const organizationRows = await db
      .select()
      .from(organizations)
      .where(
        inArray(
          organizations.id,
          filteredMemberships.map((membership) => membership.organizationId)
        )
      );

    const membershipMap = new Map(
      filteredMemberships.map((membership) => [membership.organizationId, membership])
    );

    return NextResponse.json({
      organizations: organizationRows.map((organization) => {
        const membership = membershipMap.get(organization.id);

        return {
          id: organization.id,
          name: organization.name,
          slug: organization.slug,
          plan: organization.plan,
          imageUrl: organization.imageUrl,
          role: membership?.role ?? 'user',
          businessRole: membership?.businessRole ?? 'sales_support',
          canManageUsers: membership?.role === 'admin'
        };
      })
    });
  } catch (error) {
    if (error instanceof AuthError) {
      return NextResponse.json({ message: error.message }, { status: error.status });
    }

    return NextResponse.json({ message: 'Unable to load organizations' }, { status: 500 });
  }
}

export async function POST(request: NextRequest) {
  try {
    const session = await requireSystemRole('super_admin');
    const body = (await request.json()) as { name?: string };
    const name = body.name?.trim();

    if (!name) {
      return NextResponse.json({ message: 'Workspace name is required' }, { status: 400 });
    }

    const organizationId = crypto.randomUUID();
    const baseSlug = slugifyWorkspaceName(name);
    const slug = `${baseSlug || 'workspace'}-${organizationId.slice(0, 6)}`;

    await db.insert(organizations).values({
      id: organizationId,
      name,
      slug,
      plan: 'free',
      createdBy: session.user.id
    });

    await db.insert(memberships).values({
      id: crypto.randomUUID(),
      userId: session.user.id,
      organizationId,
      role: 'admin',
      businessRole: 'sales_manager',
      permissions: getDefaultPermissions('admin', 'sales_manager')
    });

    await db
      .update(users)
      .set({ activeOrganizationId: organizationId })
      .where(eq(users.id, session.user.id));

    return NextResponse.json({
      success: true,
      organizationId
    });
  } catch (error) {
    if (error instanceof AuthError) {
      return NextResponse.json({ message: error.message }, { status: error.status });
    }

    return NextResponse.json({ message: 'Unable to create organization' }, { status: 500 });
  }
}
