import { NextRequest, NextResponse } from 'next/server';
import { db, schema } from '@/lib/db';
import { eq, desc, sql, inArray } from 'drizzle-orm';
import { getSession } from '@/lib/auth';
import { createCompanySchema } from '@/lib/validators';
import { getMaxUsersForPackage, countCompanyConversions, getEffectiveMaxConversions, initialLicenseCreditsForPackage } from '@/lib/companies';
import type { PackageTier } from '@/lib/companies';

/**
 * GET /api/admin/companies
 * List all companies (admin only)
 */
export async function GET(request: NextRequest) {
  try {
    const accessToken = request.cookies.get('scriba.access_token')?.value;
    const session = await getSession(accessToken);

    if (!session) {
      return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
    }

    // Check if user is admin
    const currentUser = await db.query.users.findFirst({
      where: eq(schema.users.id, session.user.id)
    });

    if (!currentUser || currentUser.role !== 'admin') {
      return NextResponse.json({ error: 'Forbidden - Admin access required' }, { status: 403 });
    }

    // Get all companies with user count
    const companies = await db.query.companies.findMany({
      orderBy: [desc(schema.companies.createdAt)],
    });

    // Get user counts for each company
    const companiesWithCounts = await Promise.all(
      companies.map(async (company) => {
        const userCountResult = await db
          .select({ count: sql<number>`count(*)` })
          .from(schema.users)
          .where(eq(schema.users.companyId, company.id));
        
        const owner = await db.query.users.findFirst({
          where: eq(schema.users.id, company.ownerId),
          columns: { id: true, email: true, name: true },
        });
        const conversionCount = await countCompanyConversions(company.id);
        const maxConversions = getEffectiveMaxConversions(company);
        const companyUsers = await db.query.users.findMany({
          columns: { id: true },
          where: eq(schema.users.companyId, company.id),
        });

        const userIds = companyUsers.map((u) => u.id);
        let liveTokensConsumed = 0;
        if (userIds.length > 0) {
          const tokenUsage = await db
            .select({
              total: sql<number>`COALESCE(SUM(${schema.projects.tokensUsed}), 0)`,
            })
            .from(schema.projects)
            .where(inArray(schema.projects.userId, userIds));
          liveTokensConsumed = tokenUsage[0]?.total ?? 0;
        }

        return {
          ...company,
          // CRM should display real-time company usage (spent), not billing-cycle carryover.
          freeTokensConsumed: liveTokensConsumed,
          userCount: userCountResult[0]?.count || 0,
          conversionCount,
          maxConversions,
          owner: owner || null,
        };
      })
    );

    return NextResponse.json({ companies: companiesWithCounts });
  } catch (error) {
    console.error('Error fetching companies:', error);
    return NextResponse.json({ error: 'Failed to fetch companies' }, { status: 500 });
  }
}

/**
 * POST /api/admin/companies
 * Create a new company (admin only)
 * This creates the company but does NOT create an owner yet
 * Owner must be created separately via POST /api/admin/companies/[id]/owner
 */
export async function POST(request: NextRequest) {
  try {
    const accessToken = request.cookies.get('scriba.access_token')?.value;
    const session = await getSession(accessToken);

    if (!session) {
      return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
    }

    // Check if user is admin
    const currentUser = await db.query.users.findFirst({
      where: eq(schema.users.id, session.user.id)
    });

    if (!currentUser || currentUser.role !== 'admin') {
      return NextResponse.json({ error: 'Forbidden - Admin access required' }, { status: 403 });
    }

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

    if (!parsed.success) {
      return NextResponse.json(
        { error: parsed.error.issues[0]?.message ?? 'Invalid input' },
        { status: 400 }
      );
    }

    const { name, package: packageTier, financialData } = parsed.data;
    const pkg = packageTier || 'starter';
    const maxUsers = getMaxUsersForPackage(pkg as PackageTier);

    // Create company without an owner initially (ownerId will be set when owner is created)
    const companyId = crypto.randomUUID();
    const [company] = await db.insert(schema.companies).values({
      id: companyId,
      name,
      package: pkg,
      maxUsers,
      ownerId: 'pending', // Will be updated when owner is created
      financialData: financialData || {},
      licenseCreditsRemaining: initialLicenseCreditsForPackage(pkg),
    }).returning();

    return NextResponse.json({
      success: true,
      company: {
        id: company.id,
        name: company.name,
        package: company.package,
        maxUsers: company.maxUsers,
        ownerId: null, // No owner yet
        createdAt: company.createdAt,
      },
      message: 'Company created successfully. Now create an owner for this company.',
    }, { status: 201 });

  } catch (error) {
    console.error('Error creating company:', error);
    return NextResponse.json({ error: 'Failed to create company' }, { status: 500 });
  }
}
