import { NextRequest, NextResponse } from 'next/server';
import { db } from '@/lib/db';
import { isValidEmail, isValidPassword, isValidName, isValidPhone, sanitizeString, isValidLength } from '@/lib/validation';
import { checkRateLimit, getRateLimitIdentifier, rateLimitError, RATE_LIMITS } from '@/lib/rate-limit';
import { generateUserToken } from '@/lib/auth';

// Simple demo hashing using base64 (NOT for production - use bcrypt/argon2 in production)
function hashPassword(password: string): string {
  return Buffer.from(password).toString('base64');
}

function verifyPassword(password: string, hash: string): boolean {
  return hashPassword(password) === hash;
}

export async function POST(request: NextRequest) {
  try {
    // Rate limit auth endpoints
    const identifier = `auth:${getRateLimitIdentifier(request)}`;
    const rateLimit = checkRateLimit(identifier, RATE_LIMITS.auth);
    if (!rateLimit.allowed) {
      return rateLimitError(rateLimit.resetTime);
    }

    const body = await request.json();
    const { email, password, name, phone, roles } = body;

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

    // Validate email format
    if (!isValidEmail(email)) {
      return NextResponse.json(
        { error: 'Invalid email format' },
        { status: 400 }
      );
    }

    // Validate password format
    const passwordCheck = isValidPassword(password);
    if (!passwordCheck.valid) {
      return NextResponse.json(
        { error: passwordCheck.errors.join('. ') },
        { status: 400 }
      );
    }

    // Signup: name is provided
    if (name) {
      if (!isValidName(name)) {
        return NextResponse.json(
          { error: 'Name must be between 1 and 100 characters' },
          { status: 400 }
        );
      }

      if (phone && !isValidPhone(phone)) {
        return NextResponse.json(
          { error: 'Invalid phone number format' },
          { status: 400 }
        );
      }

      // Validate roles - only allow specific values
      const validRoles = ['general', 'student', 'landlord', 'seller', 'houseOwner', 'shopOwner'];
      // Handle comma-separated roles (from signup form) or single role
      const roleList = (roles || '').split(',').map((r: string) => r.trim()).filter(Boolean);
      const userRole = roleList.find((r: string) => validRoles.includes(r)) || 'general';

      const existingUser = await db.user.findUnique({ where: { email: sanitizeString(email) } });
      if (existingUser) {
        return NextResponse.json(
          { error: 'Email already registered' },
          { status: 409 }
        );
      }

      const hashedPassword = hashPassword(password);
      const user = await db.user.create({
        data: {
          name: sanitizeString(name),
          email: sanitizeString(email),
          password: hashedPassword,
          phone: phone ? sanitizeString(phone) : null,
          roles: userRole,
        },
      });

      const { password: _password, ...userWithoutPassword } = user;
      const token = generateUserToken({ id: user.id, email: user.email });
      return NextResponse.json(
        { user: userWithoutPassword, token, message: 'Signup successful' },
        { status: 201 }
      );
    }

    // Login: name not provided
    let user = await db.user.findUnique({ where: { email: sanitizeString(email) } });

    // Fallback: case-insensitive email lookup
    if (!user) {
      const allUsers = await db.user.findMany({
        where: { email: { contains: sanitizeString(email).toLowerCase() } },
      });
      user = allUsers.find(u => u.email.toLowerCase() === sanitizeString(email).toLowerCase()) || null;
    }

    if (!user) {
      return NextResponse.json(
        { error: 'Invalid email or password' },
        { status: 401 }
      );
    }

    if (!user.isActive) {
      return NextResponse.json(
        { error: 'Account is deactivated. Please contact support.' },
        { status: 403 }
      );
    }

    if (!verifyPassword(password, user.password)) {
      return NextResponse.json(
        { error: 'Invalid email or password' },
        { status: 401 }
      );
    }

    const { password: _password, ...userWithoutPassword } = user;
    const token = generateUserToken({ id: user.id, email: user.email });
    return NextResponse.json(
      { user: userWithoutPassword, token, message: 'Login successful' },
      { status: 200 }
    );
  } catch (error) {
    console.error('Auth error:', error);
    return NextResponse.json(
      { error: 'Internal server error' },
      { status: 500 }
    );
  }
}
