/**
 * Admin Users API
 * List, search, and create users
 */

import { NextRequest, NextResponse } from 'next/server';
import { PrismaClient } from '@prisma/client';
import { AuthMiddleware } from '@/lib/auth';
import bcrypt from 'bcryptjs';

const prisma = new PrismaClient();

/**
 * GET /api/admin/users
 * List all users with filtering, searching, and pagination
 *
 * Query params:
 *   search   - Search by email, firstName, lastName
 *   role     - Filter by role (USER, ADMIN)
 *   status   - Filter by status (active, banned, all)
 *   tier     - Filter by subscription tier
 *   sort     - Sort field (createdAt, lastLoginAt, email)
 *   order    - Sort order (asc, desc)
 *   page     - Page number (default: 1)
 *   limit    - Items per page (default: 50, max: 100)
 */
export async function GET(request: NextRequest) {
  try {
    const authResponse = await AuthMiddleware.requireRole(request, 'ADMIN');
    if (authResponse) return authResponse;

    const searchParams = request.nextUrl.searchParams;
    const search = searchParams.get('search') || '';
    const role = searchParams.get('role') || '';
    const status = searchParams.get('status') || 'all';
    const tier = searchParams.get('tier') || '';
    const sort = searchParams.get('sort') || 'createdAt';
    const order = searchParams.get('order') || 'desc';
    const page = Math.max(1, parseInt(searchParams.get('page') || '1'));
    const limit = Math.min(100, Math.max(1, parseInt(searchParams.get('limit') || '50')));

    // Build where clause
    const where: any = {};

    if (search) {
      where.OR = [
        { email: { contains: search } },
        { firstName: { contains: search } },
        { lastName: { contains: search } },
      ];
    }

    if (role) {
      where.role = role;
    }

    if (status === 'active') {
      where.isActive = true;
      where.isBanned = false;
    } else if (status === 'banned') {
      where.isBanned = true;
    } else if (status === 'inactive') {
      where.isActive = false;
    }

    if (tier) {
      where.subscriptionTier = tier;
    }

    // Build orderBy
    const validSortFields = ['createdAt', 'lastLoginAt', 'email', 'firstName', 'totalLogins'];
    const sortField = validSortFields.includes(sort) ? sort : 'createdAt';
    const orderBy = { [sortField]: order === 'asc' ? 'asc' : 'desc' };

    // Get total count
    const total = await prisma.user.count({ where });

    // Get users with stats
    const users = await prisma.user.findMany({
      where,
      orderBy,
      skip: (page - 1) * limit,
      take: limit,
      select: {
        id: true,
        email: true,
        firstName: true,
        lastName: true,
        avatar: true,
        role: true,
        subscriptionTier: true,
        emailVerified: true,
        isActive: true,
        isBanned: true,
        bannedAt: true,
        lastLoginAt: true,
        totalLogins: true,
        createdAt: true,
        affiliateCode: true,
        _count: {
          select: {
            strategies: true,
            conversations: true,
          }
        }
      }
    });

    // Get backtest counts for each user
    const userIds = users.map(u => u.id);
    const backtestCounts = await prisma.backtestResult.groupBy({
      by: ['userId'],
      where: { userId: { in: userIds } },
      _count: { id: true }
    });

    const backtestMap = new Map(backtestCounts.map(b => [b.userId, b._count.id]));

    // Enrich users with backtest counts
    const enrichedUsers = users.map(user => ({
      ...user,
      backtestCount: backtestMap.get(user.id) || 0,
      strategyCount: user._count.strategies,
      conversationCount: user._count.conversations,
    }));

    // Get aggregate stats
    const stats = await prisma.user.aggregate({
      _count: { id: true },
    });

    const activeCount = await prisma.user.count({ where: { isActive: true, isBanned: false } });
    const bannedCount = await prisma.user.count({ where: { isBanned: true } });
    const adminCount = await prisma.user.count({ where: { role: 'ADMIN' } });

    return NextResponse.json({
      users: enrichedUsers,
      pagination: {
        page,
        limit,
        total,
        totalPages: Math.ceil(total / limit),
      },
      stats: {
        total: stats._count.id,
        active: activeCount,
        banned: bannedCount,
        admins: adminCount,
      }
    });
  } catch (error: any) {
    console.error('[AdminUsersAPI] Error:', error);
    return NextResponse.json({ error: error.message || 'Internal error' }, { status: 500 });
  }
}

/**
 * POST /api/admin/users
 * Create a new user (admin-created account)
 *
 * Body: { email, password, firstName?, lastName?, role?, subscriptionTier? }
 */
export async function POST(request: NextRequest) {
  try {
    const authResponse = await AuthMiddleware.requireRole(request, 'ADMIN');
    if (authResponse) return authResponse;

    const body = await request.json();
    const { email, password, firstName, lastName, role, subscriptionTier } = body;

    if (!email || !password) {
      return NextResponse.json({ error: 'Email and password are required' }, { status: 400 });
    }

    // Check if user already exists
    const existing = await prisma.user.findUnique({ where: { email } });
    if (existing) {
      return NextResponse.json({ error: 'User with this email already exists' }, { status: 409 });
    }

    // Hash password
    const passwordHash = await bcrypt.hash(password, 10);

    // Create user
    const user = await prisma.user.create({
      data: {
        email,
        passwordHash,
        firstName: firstName || null,
        lastName: lastName || null,
        role: role || 'USER',
        subscriptionTier: subscriptionTier || 'FREE',
        emailVerified: true, // Admin-created accounts are pre-verified
        isActive: true,
      },
      select: {
        id: true,
        email: true,
        firstName: true,
        lastName: true,
        role: true,
        subscriptionTier: true,
        createdAt: true,
      }
    });

    return NextResponse.json({ success: true, user });
  } catch (error: any) {
    console.error('[AdminUsersAPI] Create error:', error);
    return NextResponse.json({ error: error.message || 'Internal error' }, { status: 500 });
  }
}
