import fs from 'fs/promises';
import path from 'path';

const LOGS_PATH = process.env.WAITLIST_LOGS_PATH;

let isInitialized = false;

async function ensureInitialized(): Promise<void> {
  if (isInitialized) return;

  if (!LOGS_PATH) {
    throw new Error('WAITLIST_LOGS_PATH environment variable is not set');
  }

  try {
    await fs.access(LOGS_PATH);
  } catch {
    throw new Error(`Logs directory does not exist: ${LOGS_PATH}`);
  }

  const testFile = path.join(LOGS_PATH, '.write-test');
  try {
    await fs.writeFile(testFile, 'test');
    await fs.unlink(testFile);
  } catch {
    throw new Error(`No write access to logs directory: ${LOGS_PATH}`);
  }

  isInitialized = true;
}

function sanitizeEmail(email: string): string {
  return email
    .toLowerCase()
    .replace(/[^a-z0-9@._-]/g, '_')
    .replace(/@/g, '-at-')
    .substring(0, 50);
}

function getMonth(): string {
  const now = new Date();
  return `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}`;
}

async function getNextIndex(): Promise<string> {
  await ensureInitialized();

  const files = await fs.readdir(LOGS_PATH!);
  const mailFiles = files.filter((f) => f.startsWith('mail-'));

  let maxIndex = 0;
  for (const file of mailFiles) {
    const match = file.match(/^mail-(\d+)-/);
    if (match) {
      maxIndex = Math.max(maxIndex, parseInt(match[1], 10));
    }
  }

  return String(maxIndex + 1).padStart(3, '0');
}

async function findFileByEmail(email: string): Promise<string | null> {
  await ensureInitialized();

  const sanitized = sanitizeEmail(email);
  const files = await fs.readdir(LOGS_PATH!);

  const match = files.find((f) => f.endsWith(`${sanitized}.md`));
  return match ? path.join(LOGS_PATH!, match) : null;
}

export async function storeMail(email: string): Promise<void> {
  await ensureInitialized();

  const index = await getNextIndex();
  const month = getMonth();
  const sanitized = sanitizeEmail(email);
  const filename = `mail-${index}-${month}-${sanitized}.md`;
  const filepath = path.join(LOGS_PATH!, filename);

  const timestamp = new Date().toISOString().replace('T', ' ').substring(0, 19);

  const content = `${email}
${timestamp}
`;

  await fs.writeFile(filepath, content, 'utf-8');
}

export async function updateMail(email: string, data: { selected: string[]; other: string }): Promise<void> {
  await ensureInitialized();

  const filepath = await findFileByEmail(email);

  if (!filepath) {
    await storeMail(email);
    const newFilepath = await findFileByEmail(email);
    if (!newFilepath) throw new Error('Failed to create mail file');
    await appendUseCases(newFilepath, data);
    return;
  }

  await appendUseCases(filepath, data);
}

async function appendUseCases(filepath: string, data: { selected: string[]; other: string }): Promise<void> {
  const existing = await fs.readFile(filepath, 'utf-8');

  let useCasesSection = '\n### Use Cases\n';

  for (const useCase of data.selected) {
    useCasesSection += `- ${useCase}\n`;
  }

  if (data.other) {
    useCasesSection += `- Other: "${data.other}"\n`;
  }

  await fs.writeFile(filepath, existing + useCasesSection, 'utf-8');
}
