import fs from 'node:fs';
import path from 'node:path';
import { fileURLToPath } from 'node:url';

import express from 'express';
import nodemailer from 'nodemailer';

const DEFAULT_APP_PORT = 8080;
const DEFAULT_API_ONLY_PORT = 3013;
const DEFAULT_CONTACT_EMAIL = 'support@bayarea-cc.com';
const SMTP_HOST = 'email-smtp.us-east-2.amazonaws.com';
const SMTP_PORT = 587;
const REQUIRED_FIELDS = ['name', 'email', 'message'];
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const distDir = path.join(__dirname, 'dist');

function getFlag(name) {
  return process.argv.includes(name);
}

function getOption(name) {
  const entry = process.argv.find((arg) => arg.startsWith(`${name}=`));
  return entry ? entry.slice(name.length + 1) : undefined;
}

function getPort(apiOnly) {
  const portValue = getOption('--port') || process.env.PORT || String(apiOnly ? DEFAULT_API_ONLY_PORT : DEFAULT_APP_PORT);
  const port = Number.parseInt(portValue, 10);

  if (Number.isNaN(port)) {
    throw new Error(`Invalid port value: ${portValue}`);
  }

  return port;
}

function trimField(value) {
  return typeof value === 'string' ? value.trim() : '';
}

function sanitizeHeaderValue(value) {
  return value.replace(/[\r\n]+/g, ' ').trim();
}

function validatePayload(payload) {
  if (!payload || typeof payload !== 'object') {
    return { ok: false, error: 'Invalid request payload.' };
  }

  const data = {
    name: trimField(payload.name).slice(0, 120),
    email: trimField(payload.email).slice(0, 160),
    phone: trimField(payload.phone).slice(0, 80),
    company: trimField(payload.company).slice(0, 120),
    message: trimField(payload.message).slice(0, 4000),
    website: trimField(payload.website).slice(0, 160),
  };

  for (const field of REQUIRED_FIELDS) {
    if (!data[field]) {
      return { ok: false, error: 'Please fill out all required fields.' };
    }
  }

  if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(data.email)) {
    return { ok: false, error: 'Please provide a valid email address.' };
  }

  return { ok: true, data };
}

function createTransporter() {
  const user = process.env.AMAZON_USER;
  const pass = process.env.AMAZON_PASSWORD;

  if (!user || !pass) {
    return null;
  }

  return nodemailer.createTransport({
    host: SMTP_HOST,
    secure: false,
    port: SMTP_PORT,
    auth: {
      user,
      pass,
    },
  });
}

function buildMessageBody(data) {
  return [
    'New website inquiry',
    '',
    `Name: ${data.name}`,
    `Email: ${data.email}`,
    `Phone: ${data.phone || 'Not provided'}`,
    `Company: ${data.company || 'Not provided'}`,
    '',
    'Message:',
    data.message,
  ].join('\n');
}

function resolveRouteIndex(requestPath) {
  const relativePath = requestPath.replace(/^\/+/, '');

  if (!relativePath) {
    return path.join(distDir, 'index.html');
  }

  return path.join(distDir, relativePath, 'index.html');
}

const apiOnly = getFlag('--api-only');
const port = getPort(apiOnly);
const contactToEmail = process.env.CONTACT_TO_EMAIL || DEFAULT_CONTACT_EMAIL;
const contactFromEmail = process.env.CONTACT_FROM_EMAIL || contactToEmail;
const app = express();

app.disable('x-powered-by');
app.use(express.json({ limit: '32kb' }));

app.post('/api/contact', async (req, res) => {
  const validation = validatePayload(req.body);

  if (!validation.ok) {
    return res.status(400).json({ ok: false, error: validation.error });
  }

  const { data } = validation;

  if (data.website) {
    return res.status(400).json({ ok: false, error: 'Invalid submission.' });
  }

  const transporter = createTransporter();

  if (!transporter) {
    return res.status(503).json({
      ok: false,
      error: 'Email service is not configured right now. Please email us directly.',
    });
  }

  try {
    await transporter.sendMail({
      from: contactFromEmail,
      to: contactToEmail,
      replyTo: data.email,
      subject: sanitizeHeaderValue(`Website inquiry from ${data.name}`),
      text: buildMessageBody(data),
    });

    return res.json({ ok: true });
  } catch (error) {
    console.error('Contact form delivery failed.', error);

    return res.status(500).json({
      ok: false,
      error: 'Unable to send your message right now. Please call or email us directly.',
    });
  }
});

if (!apiOnly) {
  app.use(express.static(distDir, { index: 'index.html', redirect: false }));

  app.get(/^(?!\/api\/).*/, (req, res) => {
    const routeIndex = resolveRouteIndex(req.path);
    const fallbackIndex = path.join(distDir, 'index.html');

    if (fs.existsSync(routeIndex)) {
      return res.sendFile(routeIndex);
    }

    return res.sendFile(fallbackIndex);
  });
}

app.listen(port, () => {
  if (!process.env.AMAZON_USER || !process.env.AMAZON_PASSWORD) {
    console.warn('Amazon SES SMTP credentials are missing. /api/contact will return 503 until configured.');
  }

  console.log(`Bay Area IT server listening on port ${port}${apiOnly ? ' (API only)' : ''}.`);
});
