import { NextRequest, NextResponse } from 'next/server'
import crypto from 'crypto'
import { requireStaffPermission } from '@/lib/auth-helpers'
import { prisma } from '@/lib/prisma'
import { StaffRole } from '@prisma/client'
import { getAssignableRoles } from '@/lib/services/permission-service'
import { emailService } from '@/lib/services/email-service'

interface InviteStaffRequest {
  email: string
  role: StaffRole
}

/**
 * POST /api/v1/admin/staff/invite
 * Send a staff invitation
 * Requires: staff:invite permission
 */
export async function POST(request: NextRequest) {
  try {
    const session = await requireStaffPermission('staff:invite')
    const body: InviteStaffRequest = await request.json()

    // Validate required fields
    if (!body.email) {
      return NextResponse.json(
        { error: 'Email is required' },
        { status: 400 }
      )
    }

    if (!body.role) {
      return NextResponse.json(
        { error: 'Role is required' },
        { status: 400 }
      )
    }

    // Validate email format
    const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
    if (!emailRegex.test(body.email)) {
      return NextResponse.json(
        { error: 'Invalid email format' },
        { status: 400 }
      )
    }

    // Validate role can be assigned
    const assignableRoles = getAssignableRoles(session.user.role)
    if (!assignableRoles.includes(body.role)) {
      return NextResponse.json(
        { error: 'Cannot invite staff with this role' },
        { status: 403 }
      )
    }

    // Check if email already exists as staff
    const existingStaff = await prisma.staff.findUnique({
      where: { email: body.email },
    })

    if (existingStaff) {
      return NextResponse.json(
        { error: 'A staff member with this email already exists' },
        { status: 409 }
      )
    }

    // Check if pending invitation exists
    const existingInvite = await prisma.staffInvitation.findUnique({
      where: { email: body.email },
    })

    if (existingInvite) {
      return NextResponse.json(
        { error: 'A pending invitation for this email already exists' },
        { status: 409 }
      )
    }

    // Generate secure token
    const token = crypto.randomBytes(32).toString('hex')

    // Create invitation with 7-day expiry
    const expiresAt = new Date()
    expiresAt.setDate(expiresAt.getDate() + 7)

    const invitation = await prisma.staffInvitation.create({
      data: {
        email: body.email,
        role: body.role,
        token,
        expiresAt,
        invitedBy: session.user.id,
      },
      select: {
        id: true,
        email: true,
        role: true,
        expiresAt: true,
        createdAt: true,
      },
    })

    // Get the inviter's name for the response
    const inviter = await prisma.staff.findUnique({
      where: { id: session.user.id },
      select: { name: true, email: true },
    })

    const baseUrl = process.env.NEXTAUTH_URL || 'http://localhost:3000'
    const inviteUrl = `${baseUrl}/invite/${token}`

    // Send invitation email
    let emailSent = false
    let emailError: string | undefined

    const isEmailConfigured = await emailService.isConfigured()
    if (isEmailConfigured) {
      const inviterName = inviter?.name || inviter?.email || 'A team member'
      const roleDisplay = body.role.charAt(0) + body.role.slice(1).toLowerCase()

      const emailResult = await emailService.sendEmail({
        to: body.email,
        subject: `You've been invited to join LetsBe Hub`,
        html: `
          <div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;">
            <div style="background-color: #667eea; padding: 30px; text-align: center;">
              <h1 style="color: #ffffff; margin: 0; font-size: 28px;">LetsBe Hub</h1>
            </div>
            <div style="padding: 40px 30px; background-color: #f9f9f9;">
              <h2 style="color: #333333; margin-top: 0;">You're Invited!</h2>
              <p style="color: #666666; line-height: 1.6; font-size: 16px;">
                ${inviterName} has invited you to join <strong>LetsBe Hub</strong> as a <strong>${roleDisplay}</strong>.
              </p>
              <p style="color: #666666; line-height: 1.6; font-size: 16px;">
                Click the button below to create your account and get started.
              </p>
              <table role="presentation" cellspacing="0" cellpadding="0" border="0" align="center" style="margin: 30px auto;">
                <tr>
                  <td style="border-radius: 6px; background-color: #667eea;">
                    <a href="${inviteUrl}" target="_blank" style="background-color: #667eea; border: 15px solid #667eea; font-family: Arial, sans-serif; font-size: 16px; line-height: 1.1; text-align: center; text-decoration: none; display: block; border-radius: 6px; font-weight: bold;">
                      <span style="color: #ffffff;">Accept Invitation</span>
                    </a>
                  </td>
                </tr>
              </table>
              <p style="color: #999999; font-size: 14px; margin-top: 30px;">
                Or copy and paste this link into your browser:
              </p>
              <p style="color: #667eea; font-size: 14px; word-break: break-all;">
                <a href="${inviteUrl}" style="color: #667eea;">${inviteUrl}</a>
              </p>
              <hr style="border: none; border-top: 1px solid #dddddd; margin: 30px 0;" />
              <p style="color: #999999; font-size: 12px;">
                This invitation expires in 7 days. If you didn't expect this invitation, you can safely ignore this email.
              </p>
            </div>
            <div style="padding: 20px; background-color: #333333; text-align: center;">
              <p style="color: #999999; margin: 0; font-size: 12px;">
                LetsBe Hub - Infrastructure Management Platform
              </p>
            </div>
          </div>
        `,
        text: `You've been invited to join LetsBe Hub!\n\n${inviterName} has invited you to join LetsBe Hub as a ${roleDisplay}.\n\nClick here to accept: ${inviteUrl}\n\nThis invitation expires in 7 days.`,
      })

      emailSent = emailResult.success
      emailError = emailResult.error
    }

    return NextResponse.json(
      {
        ...invitation,
        invitedBy: inviter,
        inviteUrl, // Always include URL so it can be copied manually if email fails
        emailSent,
        emailError,
        message: emailSent
          ? 'Invitation sent successfully'
          : isEmailConfigured
            ? 'Invitation created but email failed to send'
            : 'Invitation created (email not configured)',
      },
      { status: 201 }
    )
  } catch (error) {
    if (typeof error === 'object' && error !== null && 'status' in error) {
      const err = error as { status: number; message: string }
      return NextResponse.json({ error: err.message }, { status: err.status })
    }
    console.error('Error creating invitation:', error)
    return NextResponse.json(
      { error: 'Failed to create invitation' },
      { status: 500 }
    )
  }
}
