import { Injectable, OnModuleInit, OnModuleDestroy, Logger } from '@nestjs/common'
import { ConfigService } from '@nestjs/config'
import * as SMTPServer from 'smtp-server'
import { simpleParser } from 'mailparser'
import { EmailService } from './email.service'

/**
 * Embedded SMTP server that receives forwarded / inbound emails.
 *
 * How attorneys use it:
 *   1. Register their email address in Settings → Email Accounts
 *   2. Configure their email client to BCC or auto-forward client emails
 *      to the SMTP server address (default port 2525, no auth required
 *      on localhost — add IP whitelist for production)
 *
 * The server is intentionally permissive (no auth, accept-all) because it
 * is only meant to be reachable from the internal network / loopback.
 */
@Injectable()
export class SmtpListenerService implements OnModuleInit, OnModuleDestroy {
  private readonly logger = new Logger(SmtpListenerService.name)
  private server: any

  constructor(
    private readonly emailService: EmailService,
    private readonly config: ConfigService,
  ) {}

  onModuleInit() {
    const port = this.config.get<number>('SMTP_PORT', 2525)
    const host = this.config.get<string>('SMTP_HOST', '0.0.0.0')

    this.server = new (SMTPServer as any).SMTPServer({
      // Accept all connections — restrict at network level
      onAuth:     (_auth: any, _session: any, cb: any) => cb(null, { user: _auth.username }),
      authOptional: true,
      disabledCommands: ['STARTTLS'],

      onData: (stream: any, session: any, callback: any) => {
        this.handleIncoming(stream, session)
          .then(() => callback())
          .catch(err => {
            this.logger.error('SMTP onData error', err)
            callback(err)
          })
      },

      logger: false,
    })

    this.server.listen(port, host, () => {
      this.logger.log(`SMTP listener started on ${host}:${port}`)
    })

    this.server.on('error', (err: Error) => {
      this.logger.error('SMTP server error', err.message)
    })
  }

  onModuleDestroy() {
    this.server?.close()
  }

  private async handleIncoming(stream: any, session: any): Promise<void> {
    const parsed = await simpleParser(stream)

    // Determine who forwarded this (the SMTP envelope sender)
    const envelopeFrom: string = session?.envelope?.mailFrom?.address ?? ''

    await this.emailService.ingestInbound(parsed, envelopeFrom)
  }
}
