﻿import { NextRequest, NextResponse } from 'next/server';
import { prisma } from '@/lib/prisma';
import bcrypt from 'bcryptjs';
import crypto from 'crypto';
import { sendActivationEmail } from '@/lib/emailservice.cjs';

interface PrismaError extends Error {
  code?: string;
  meta?: {
    target?: string;
  };
}

export async function POST(request: NextRequest) {
  try {
    const body = await request.json();
    const {
      fullName,
      email,
      phone,
      gender,
      dept,
      position,
      joinDate,
      salary,
      employmentType,
      createdByName,
      dob,
      nationalId,
      kraPin
    } = body;
    
    console.log('Creating employee for email:', email, 'Department:', dept);
    
    // Validate required fields
    const missingFields = [];
    if (!fullName) missingFields.push('fullName');
    if (!email) missingFields.push('email');
    if (!dept) missingFields.push('dept');
    if (!position) missingFields.push('position');
    if (!joinDate) missingFields.push('joinDate');
    
    if (missingFields.length > 0) {
      return NextResponse.json(
        { 
          error: `❌ Missing required fields: ${missingFields.join(', ')}`,
          missingFields,
          code: 'MISSING_FIELDS'
        },
        { status: 400 }
      );
    }
    
    // CHECK FOR DUPLICATE EMAIL IN USER TABLE
    const existingUser = await prisma.user.findFirst({
      where: { email }
    });

    if (existingUser) {
      return NextResponse.json(
        { 
          error: `❌ Email "${email}" is already registered in the system.`,
          conflict: 'user',
          existingData: {
            email: existingUser.email,
            name: existingUser.name,
            role: existingUser.role,
            status: existingUser.status
          },
          suggestion: 'Please use a different email address or contact the HR administrator.',
          code: 'DUPLICATE_EMAIL_USER'
        },
        { status: 409 }
      );
    }

    // CHECK FOR DUPLICATE EMAIL IN EMPLOYEE TABLE
    const existingEmployee = await prisma.employee.findFirst({
      where: { email }
    });

    if (existingEmployee) {
      return NextResponse.json(
        { 
          error: `❌ Email "${email}" is already registered as an employee.`,
          conflict: 'employee',
          existingData: {
            employeeNumber: existingEmployee.employeeNumber,
            fullName: existingEmployee.fullName,
            email: existingEmployee.email,
            dept: existingEmployee.dept,
            position: existingEmployee.position,
            status: existingEmployee.isActive ? 'Active' : 'Inactive'
          },
          suggestion: 'Please use a different email address.',
          code: 'DUPLICATE_EMAIL_EMPLOYEE'
        },
        { status: 409 }
      );
    }

    // CHECK FOR DUPLICATE NATIONAL ID (if provided)
    if (nationalId && nationalId.trim() !== '') {
      const existingNationalId = await prisma.employee.findFirst({
        where: { nationalId }
      });
      if (existingNationalId) {
        return NextResponse.json(
          { 
            error: `❌ National ID "${nationalId}" is already registered.`,
            conflict: 'nationalId',
            existingData: {
              employeeNumber: existingNationalId.employeeNumber,
              fullName: existingNationalId.fullName,
              nationalId: existingNationalId.nationalId
            },
            suggestion: 'Please verify the National ID or use a different one.',
            code: 'DUPLICATE_NATIONAL_ID'
          },
          { status: 409 }
        );
      }
    }

    // CHECK FOR DUPLICATE KRA PIN (if provided)
    if (kraPin && kraPin.trim() !== '') {
      const existingKraPin = await prisma.employee.findFirst({
        where: { kraPin }
      });
      if (existingKraPin) {
        return NextResponse.json(
          { 
            error: `❌ KRA PIN "${kraPin}" is already registered.`,
            conflict: 'kraPin',
            existingData: {
              employeeNumber: existingKraPin.employeeNumber,
              fullName: existingKraPin.fullName,
              kraPin: existingKraPin.kraPin
            },
            suggestion: 'Please verify the KRA PIN or use a different one.',
            code: 'DUPLICATE_KRA_PIN'
          },
          { status: 409 }
        );
      }
    }
    
    const isIntern = employmentType === 'Intern';
    const prefix = isIntern ? 'INT' : 'UF';
    
    // Generate next employee number
    const lastEmployee = await prisma.employee.findFirst({
      where: { employeeNumber: { startsWith: prefix } },
      orderBy: { employeeNumber: 'desc' }
    });
    
    let nextNum = 1;
    if (lastEmployee) {
      const num = parseInt(lastEmployee.employeeNumber.replace(prefix, ''));
      if (!isNaN(num)) {
        nextNum = num + 1;
      }
    }
    
    const empNumber = `${prefix}${nextNum.toString().padStart(3, '0')}`;
    const username = empNumber.toLowerCase();
    const tempPassword = `${username}@${new Date().getFullYear()}`;
    const hashedPassword = await bcrypt.hash(tempPassword, 10);
    const salaryNum = salary ? parseFloat(salary) : null;
    
    // Split full name
    const nameParts = fullName.trim().split(' ');
    const firstName = nameParts[0];
    const lastName = nameParts.slice(1).join(' ') || '';
    
    // Create employee
    const employee = await prisma.employee.create({
      data: {
        employeeNumber: empNumber,
        firstName,
        lastName,
        fullName,
        email,
        phone: phone || null,
        dob: dob ? new Date(dob) : null,
        gender: gender || 'Male',
        employmentType: employmentType || 'Permanent',
        dept,
        position,
        joinDate: new Date(joinDate),
        salary: salaryNum,
        nationalId: nationalId || null,
        kraPin: kraPin || null,
        isIntern,
        isActive: true,
      },
    });
    
    console.log('✅ Employee created:', employee.email, 'Department:', employee.dept, 'Type:', isIntern ? 'Intern' : 'Employee');
    
    // Generate activation token
    const activationToken = crypto.randomBytes(32).toString('hex');
    const tokenExpiry = new Date();
    tokenExpiry.setHours(tokenExpiry.getHours() + 24);
    
    // Create user account
    const user = await prisma.user.create({
      data: {
        username,
        passwordHash: hashedPassword,
        email,
        name: fullName,
        role: isIntern ? 'intern' : 'employee',
        employeeId: employee.employeeNumber,
        dept,
        position,
        isFirstLogin: true,
        isActive: true,
        isIntern,
        status: 'PENDING_ACTIVATION',
        activationToken,
        tokenExpiry,
        isEmailVerified: false,
      },
    });
    
    console.log('✅ User created:', user.email, 'Role:', user.role, 'Status:', user.status);
    
    // Send activation email
    console.log('📧 Sending activation email to:', email);
    const emailResult = await sendActivationEmail(email, fullName, activationToken);
    console.log('📧 Email result:', emailResult);
    
    // Extract email success status safely
    const emailSent = emailResult && emailResult.success === true;
    const emailErrorMsg = emailResult && emailResult.error ? emailResult.error : null;
    
    // Return success response with credentials and email status
    return NextResponse.json({
      success: true,
      message: `Employee ${fullName} created successfully! ${emailSent ? 'Activation email sent!' : 'Please manually send activation link.'}`,
      empNumber: employee.employeeNumber,
      username: username,
      tempPassword: tempPassword,
      email: email,
      fullName: fullName,
      emailSent: emailSent,
      emailError: emailErrorMsg,
      requiresActivation: true,
      employee: {
        id: employee.id,
        employeeNumber: employee.employeeNumber,
        fullName: employee.fullName,
        email: employee.email,
        dept: employee.dept,
        position: employee.position,
      },
      user: {
        id: user.id,
        username: user.username,
        email: user.email,
        role: user.role,
      },
      credentials: {
        username,
        tempPassword,
        empNumber,
      },
      department: dept,
      role: user.role,
      loginUrl: `${process.env.FRONTEND_URL || 'http://localhost:3000'}/login`,
    });
    
  } catch (err: unknown) {
    console.error('❌ Error creating employee with user:', err);
    
    const error = err as PrismaError;
    
    // Handle Prisma unique constraint errors
    if (error.code === 'P2002') {
      const target = error.meta?.target;
      let message = '❌ Duplicate entry. ';
      
      if (target === 'email') {
        message = `❌ Email is already registered. Please use a different email address.`;
      } else if (target === 'nationalId') {
        message = `❌ National ID is already registered. Please use a different National ID.`;
      } else if (target === 'kraPin') {
        message = `❌ KRA PIN is already registered. Please use a different KRA PIN.`;
      } else if (target === 'employeeNumber') {
        message = '❌ Employee number conflict. Please try again.';
      } else {
        message = `❌ Duplicate entry for ${target}. Please check your data.`;
      }
      
      return NextResponse.json(
        { 
          error: message,
          code: error.code,
          field: target,
          suggestion: 'Please verify the information and try again.'
        },
        { status: 409 }
      );
    }
    
    // Handle other errors
    return NextResponse.json(
      { 
        error: error instanceof Error ? error.message : '❌ Failed to create employee',
        code: error.code || 'UNKNOWN_ERROR',
        suggestion: 'Please check the server logs for more details.'
      },
      { status: 500 }
    );
  }
}