import { NextResponse } from 'next/server';
import { z } from 'zod';
import { withErrorHandler } from '@server/middleware/withErrorHandler';
import { withAuth, AuthedRequest } from '@server/middleware/withAuth';
import { ForbiddenError, ValidationError } from '@server/errors';
import { initDatabase } from '@server/db/init';
import { getPlatformSetting, setPlatformSetting, setPlatformSmtp, getPlatformSmtp } from '@server/services/email/platform-settings';
import { sendRaw } from '@server/services/email/transport';
import { renderTemplate } from '@server/services/email/render';

function requireAdmin(req: AuthedRequest) {
  if (req.session.role !== 'superadmin' && req.session.role !== 'support') {
    throw new ForbiddenError();
  }
}

export const GET = withErrorHandler(
  withAuth(async (req: AuthedRequest) => {
    requireAdmin(req);
    await initDatabase();
    const cfg = await getPlatformSetting<Record<string, unknown>>('smtp_config', {});
    const adminBrandName = await getPlatformSetting<string>('admin_brand_name', 'diploy');
    const adminBrandUrl = await getPlatformSetting<string>('admin_brand_url', 'https://diploy.in');
    const adminBrandLogoUrl = await getPlatformSetting<string>('admin_brand_logo_url', '');
    return NextResponse.json({
      smtp: {
        host: cfg.host ?? '',
        port: cfg.port ?? 587,
        user: cfg.user ?? '',
        from: cfg.from ?? '',
        secure: cfg.secure ?? false,
        passSet: !!cfg.passEnc,
      },
      adminBrand: { name: adminBrandName, url: adminBrandUrl, logoUrl: adminBrandLogoUrl },
    });
  })
);

const smtpSchema = z.object({
  host: z.string().min(1),
  port: z.coerce.number().int().min(1).max(65535),
  user: z.string().min(1),
  pass: z.string().optional().default(''),
  from: z.string().min(1),
  secure: z.boolean().optional(),
  adminBrandName: z.string().min(1).optional(),
  adminBrandUrl: z.string().url().optional().or(z.literal('')),
  adminBrandLogoUrl: z.string().url().optional().or(z.literal('')),
});

export const POST = withErrorHandler(
  withAuth(async (req: AuthedRequest) => {
    requireAdmin(req);
    await initDatabase();
    let body: Awaited<ReturnType<typeof req.json>>;
    try {
      body = await req.json();
    } catch {
      throw new ValidationError('Request body must be valid JSON');
    }
    const parsed = smtpSchema.safeParse(body);
    if (!parsed.success) throw new ValidationError(parsed.error.issues[0]?.message || 'Invalid input');
    const { adminBrandName, adminBrandUrl, adminBrandLogoUrl, ...smtp } = parsed.data;

    await setPlatformSmtp({ host: smtp.host, port: smtp.port, user: smtp.user, pass: smtp.pass, from: smtp.from, secure: smtp.secure }, req.session.userId);
    if (adminBrandName !== undefined) await setPlatformSetting('admin_brand_name', adminBrandName, req.session.userId);
    if (adminBrandUrl !== undefined) await setPlatformSetting('admin_brand_url', adminBrandUrl || '', req.session.userId);
    if (adminBrandLogoUrl !== undefined) await setPlatformSetting('admin_brand_logo_url', adminBrandLogoUrl || '', req.session.userId);

    return NextResponse.json({ ok: true });
  })
);

const testSchema = z.object({ to: z.string().email() });

export const PUT = withErrorHandler(
  withAuth(async (req: AuthedRequest) => {
    requireAdmin(req);
    await initDatabase();
    let body: Awaited<ReturnType<typeof req.json>>;
    try {
      body = await req.json();
    } catch {
      throw new ValidationError('Request body must be valid JSON');
    }
    const parsed = testSchema.safeParse(body);
    if (!parsed.success) throw new ValidationError('Invalid recipient');

    const cfg = await getPlatformSmtp();
    if (!cfg) throw new ValidationError('SMTP not configured yet');

    const rendered = await renderTemplate('signup_otp', { name: 'Test', code: '000000' });
    const result = await sendRaw(parsed.data.to, `[Test] ${rendered.subject}`, rendered.html, null, null);
    if (!result) throw new ValidationError('Send failed — check SMTP host/credentials');
    return NextResponse.json({ ok: true });
  })
);
