import { NextRequest, NextResponse } from 'next/server'
import nodemailer from 'nodemailer'
import { checkRateLimit } from '@/lib/rate-limit'

const MAIL_DOMAIN = process.env.POSTE_MAIL_DOMAIN || 'monaco-opc.com'
const SMTP_HOST = process.env.SMTP_HOST || 'localhost'
const SMTP_PORT = parseInt(process.env.SMTP_PORT || '587')
const POSTE_API_URL = process.env.POSTE_API_URL || 'https://mail.monaco-opc.com'
const POSTE_ADMIN_EMAIL = process.env.POSTE_ADMIN_EMAIL || ''
const POSTE_ADMIN_PASSWORD = process.env.POSTE_ADMIN_PASSWORD || ''

const PASSWORD_MIN_LENGTH = 8
const PASSWORD_REGEX = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{8,}$/

function validateNewPassword(password: string): string | null {
  if (password.length < PASSWORD_MIN_LENGTH) {
    return `Password must be at least ${PASSWORD_MIN_LENGTH} characters.`
  }
  if (!PASSWORD_REGEX.test(password)) {
    return 'Password must contain at least one uppercase letter, one lowercase letter, and one number.'
  }
  return null
}

export async function POST(request: NextRequest): Promise<NextResponse> {
  const ip = request.headers.get('x-forwarded-for')?.split(',')[0]?.trim() || 'unknown'
  const rateLimit = checkRateLimit(`email-change:${ip}`, 3, 15 * 60 * 1000)

  if (!rateLimit.success) {
    return NextResponse.json(
      { error: 'Too many attempts. Please try again later.' },
      { status: 429 }
    )
  }

  try {
    const body = await request.json()
    const { email, currentPassword, newPassword } = body as {
      email: string
      currentPassword: string
      newPassword: string
    }

    if (!email || !currentPassword || !newPassword) {
      return NextResponse.json(
        { error: 'All fields are required.' },
        { status: 400 }
      )
    }

    const emailLower = email.toLowerCase().trim()

    if (!emailLower.endsWith(`@${MAIL_DOMAIN}`)) {
      return NextResponse.json(
        { error: `Email must be an @${MAIL_DOMAIN} address.` },
        { status: 400 }
      )
    }

    const passwordError = validateNewPassword(newPassword)
    if (passwordError) {
      return NextResponse.json({ error: passwordError }, { status: 400 })
    }

    if (!POSTE_ADMIN_EMAIL || !POSTE_ADMIN_PASSWORD) {
      console.error('Poste.io admin credentials not configured')
      return NextResponse.json(
        { error: 'Email service is not configured. Contact an administrator.' },
        { status: 503 }
      )
    }

    // Re-verify current credentials via SMTP
    const transporter = nodemailer.createTransport({
      host: SMTP_HOST,
      port: SMTP_PORT,
      secure: SMTP_PORT === 465,
      auth: {
        user: emailLower,
        pass: currentPassword,
      },
      connectionTimeout: 10000,
      greetingTimeout: 10000,
    })

    try {
      await transporter.verify()
    } catch {
      return NextResponse.json(
        { error: 'Current password is incorrect.' },
        { status: 401 }
      )
    } finally {
      transporter.close()
    }

    // Change password via Poste.io Admin API
    const apiUrl = `${POSTE_API_URL}/admin/api/v1/boxes/${encodeURIComponent(emailLower)}`
    const authHeader = 'Basic ' + Buffer.from(`${POSTE_ADMIN_EMAIL}:${POSTE_ADMIN_PASSWORD}`).toString('base64')

    const response = await fetch(apiUrl, {
      method: 'PATCH',
      headers: {
        'Content-Type': 'application/json',
        'Accept': 'application/json',
        'Authorization': authHeader,
      },
      body: JSON.stringify({ passwordPlaintext: newPassword }),
    })

    if (!response.ok) {
      console.error('Poste.io API error:', response.status, await response.text())
      return NextResponse.json(
        { error: 'Failed to change password. Please try again or contact an administrator.' },
        { status: 502 }
      )
    }

    return NextResponse.json({ success: true })
  } catch (err) {
    console.error('Password change error:', err)
    return NextResponse.json(
      { error: 'An unexpected error occurred.' },
      { status: 500 }
    )
  }
}
