import { createTransport } from 'nodemailer';
import { createRouter } from '../../create-router';
import { readServerSettings, writeServerSettings } from 'officerdb';
import { getTransport } from 'emailer';

type SmtpConfig = {
  provider: 'resend' | 'smtp' | 'mailhog';
  apiKey?: string;
  host?: string;
  port?: number;
  username?: string;
  password?: string;
  secure?: boolean;
  fromName: string;
  fromEmail: string;
};

function maskSecret(value: string | undefined): string | undefined {
  if (!value || value.length < 8) return value ? '****' : undefined;
  return value.slice(0, 4) + '****' + value.slice(-4);
}

function serializeConfig(smtp: SmtpConfig) {
  return {
    provider: smtp.provider,
    apiKey: maskSecret(smtp.apiKey),
    host: smtp.host,
    port: smtp.port,
    username: smtp.username,
    password: maskSecret(smtp.password),
    secure: smtp.secure,
    fromName: smtp.fromName,
    fromEmail: smtp.fromEmail,
  };
}

function buildTransportUrl(config: SmtpConfig): string {
  if (config.provider === 'mailhog') {
    return `smtp://${config.host ?? 'localhost'}:${config.port ?? 1025}`;
  }
  const auth = config.username
    ? `${encodeURIComponent(config.username)}:${encodeURIComponent(config.password ?? '')}@`
    : '';
  const protocol = config.secure ? 'smtps' : 'smtp';
  return `${protocol}://${auth}${config.host}:${config.port ?? 587}`;
}

export const smtpRouter = createRouter();

smtpRouter.get('/', async (ctx) => {
  const settings = await readServerSettings();
  const smtp: SmtpConfig | undefined = settings.smtp as SmtpConfig | undefined;
  if (smtp) return ctx.json(serializeConfig(smtp));
  return ctx.json(null);
});

smtpRouter.put('/', async (ctx) => {
  const body = await ctx.req.json<SmtpConfig>();
  const settings = await readServerSettings();

  const existing: SmtpConfig | undefined = settings.smtp as SmtpConfig | undefined;
  if (existing) {
    if (body.apiKey && body.apiKey.includes('****')) body.apiKey = existing.apiKey;
    if (body.password && body.password.includes('****')) body.password = existing.password;
  }

  settings.smtp = body;
  await writeServerSettings(settings);
  return ctx.json({ success: true });
});

smtpRouter.post('/test-connection', async (ctx) => {
  try {
    const result = await getTransport();

    if (result.type === 'resend') {
      const res = await fetch('https://api.resend.com/domains', {
        headers: { Authorization: `Bearer ${result.apiKey}` },
      });
      if (!res.ok) {
        const err = await res.json();
        throw new Error(err.message ?? `Resend API error: ${res.status}`);
      }
      return ctx.json({ success: true });
    }

    await result.transport.verify();
    return ctx.json({ success: true });
  } catch (err) {
    const message = err instanceof Error ? err.message : 'Unknown error';
    return ctx.json({ error: message }, 500);
  }
});

smtpRouter.post('/test', async (ctx) => {
  const body = await ctx.req.json<SmtpConfig & { to: string }>();
  if (!body.to) return ctx.json({ error: 'Recipient address required' }, 400);

  // Resolve masked secrets from saved config
  const settings = await readServerSettings();
  const saved: SmtpConfig | undefined = settings.smtp as SmtpConfig | undefined;
  if (saved) {
    if (body.apiKey?.includes('****')) body.apiKey = saved.apiKey;
    if (body.password?.includes('****')) body.password = saved.password;
  }

  const from = `${body.fromName} <${body.fromEmail}>`;
  const testHtml =
    '<h2>Officer Test Email</h2><p>If you received this, your email configuration is working correctly.</p>';

  try {
    if (body.provider === 'resend') {
      const res = await fetch('https://api.resend.com/emails', {
        method: 'POST',
        headers: {
          Authorization: `Bearer ${body.apiKey}`,
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({ from, to: body.to, subject: 'officer.dev Test Email', html: testHtml }),
      });
      if (!res.ok) {
        const err = await res.json();
        throw new Error(err.message ?? `Resend API error: ${res.status}`);
      }
      return ctx.json({ success: true });
    }

    const url = buildTransportUrl(body);
    const transport = createTransport(url);
    await transport.sendMail({ from, to: body.to, subject: 'officer.dev Test Email', html: testHtml });
    return ctx.json({ success: true });
  } catch (err) {
    const message = err instanceof Error ? err.message : 'Unknown error';
    return ctx.json({ error: message }, 500);
  }
});
