import { NextRequest, NextResponse } from 'next/server';
import { db, schema } from '@/lib/db';
import { eq } from 'drizzle-orm';
import bcrypt from 'bcrypt';
import { rateLimit } from '@/lib/rate-limit';
import { signupSchema } from '@/lib/validators';
import { generateAccessToken, generateRefreshToken } from '@/lib/tokens';
import { getMaxUsersForPackage, type PackageTier, initialLicenseCreditsForPackage } from '@/lib/companies';
import { ACCESS_TOKEN_MAX_AGE_SECONDS, BCRYPT_ROUNDS, REFRESH_TOKEN_MAX_AGE_SECONDS } from '@/lib/constants';

export async function POST(request: NextRequest) {
  try {
    // Rate limit: 3 signups per 60s per IP
    const ip = request.headers.get('x-forwarded-for')?.split(',')[0]?.trim() || 'unknown';
    const rl = rateLimit(`signup:${ip}`, { limit: 3, windowSeconds: 60 });
    if (!rl.allowed) {
      return NextResponse.json(
        { error: 'Troppi tentativi. Riprova tra un minuto.' },
        { status: 429, headers: { 'Retry-After': String(Math.ceil((rl.resetAt - Date.now()) / 1000)) } }
      );
    }

    const body = await request.json();
    const parsed = signupSchema.safeParse(body);
    if (!parsed.success) {
      return NextResponse.json({ error: parsed.error.issues[0]?.message ?? 'Input non valido' }, { status: 400 });
    }
    const { email, password, name, createCompany, companyName, companyPackage } = parsed.data;

    // Check if user already exists
    const existingUser = await db.query.users.findFirst({
      where: eq(schema.users.email, email)
    });

    if (existingUser) {
      return NextResponse.json({ error: 'Un utente con questa email esiste già' }, { status: 400 });
    }

    // Hash password
    const hashedPassword = await bcrypt.hash(password, BCRYPT_ROUNDS);

    let companyId: string | null = null;
    let isOwner = false;

    // If createCompany mode, create company first (user will be owner)
    if (createCompany) {
      const pkg = companyPackage || 'starter';
      const maxUsers = getMaxUsersForPackage(pkg as PackageTier);
      
      companyId = crypto.randomUUID();
      isOwner = true;

      // Create company first (we'll update ownerId after user creation)
      await db.insert(schema.companies).values({
        id: companyId,
        name: companyName || `${name || email.split('@')[0]}'s Company`,
        package: pkg,
        maxUsers,
        ownerId: 'temp', // Will update after user creation
        financialData: {},
        paymentMethod: null,
        licenseCreditsRemaining: initialLicenseCreditsForPackage(pkg),
      });
    }

    // Create user
    const userId = crypto.randomUUID();
    const [user] = await db.insert(schema.users).values({
      id: userId,
      email,
      name: name || email.split('@')[0],
      companyId,
      isOwner,
      emailVerified: true
    }).returning();

    // If we created a company, update the ownerId now that user exists
    if (companyId && isOwner) {
      await db
        .update(schema.companies)
        .set({ ownerId: userId, updatedAt: new Date() })
        .where(eq(schema.companies.id, companyId));
    }

    // Create account with password
    await db.insert(schema.accounts).values({
      id: crypto.randomUUID(),
      userId,
      accountId: email,
      providerId: 'credential',
      password: hashedPassword
    });

    // Generate refresh token and session
    const { refreshToken, sessionId } = await generateRefreshToken(
      userId,
      request.headers.get('x-forwarded-for') || undefined,
      request.headers.get('user-agent') || undefined
    );

    // Generate access token
    const accessToken = generateAccessToken({
      userId: user.id,
      email: user.email,
      role: user.role,
      sessionId,
    });

    // Set HttpOnly cookies
    const response = NextResponse.json({
      success: true,
      user: { 
        id: user.id, 
        email: user.email, 
        name: user.name, 
        role: user.role,
        companyId: user.companyId,
        isOwner: user.isOwner,
      },
      company: companyId ? {
        id: companyId,
        name: companyName || `${name || email.split('@')[0]}'s Company`,
      } : null,
      message: companyId 
        ? 'Account and company created successfully. You are now the owner.' 
        : 'Account created successfully. Please create or join a company to continue.',
    });

    // Access token cookie (short-lived)
    response.cookies.set('scriba.access_token', accessToken, {
      httpOnly: true,
      secure: process.env.NODE_ENV === 'production',
      sameSite: 'lax',
      path: '/',
      maxAge: ACCESS_TOKEN_MAX_AGE_SECONDS,
    });

    // Refresh token cookie (long-lived)
    response.cookies.set('scriba.refresh_token', refreshToken, {
      httpOnly: true,
      secure: process.env.NODE_ENV === 'production',
      sameSite: 'lax',
      path: '/',
      maxAge: REFRESH_TOKEN_MAX_AGE_SECONDS,
    });

    return response;
  } catch (error) {
    console.error('Sign-up error:', error);
    return NextResponse.json({ error: 'Registrazione fallita. Riprova.' }, { status: 500 });
  }
}
