import fs from 'fs';
import path from 'path';

import { resolveGroupIpcPath } from './group-folder.js';
import type { Attachment } from './types.js';

export const ATTACHMENTS_CONTAINER_DIR = '/workspace/attachments';

function sanitizeAttachmentName(name: string): string {
  return path.basename(name || 'attachment').replace(/[^a-zA-Z0-9._-]/g, '-') || 'attachment';
}

function buildStagedFileName(name: string): string {
  const safeName = sanitizeAttachmentName(name);
  return `${Date.now()}-${Math.random().toString(36).slice(2, 8)}-${safeName}`;
}

export function getGroupAttachmentHostDir(groupFolder: string): string {
  return path.join(resolveGroupIpcPath(groupFolder), 'attachments');
}

export function ensureGroupAttachmentHostDir(groupFolder: string): string {
  const dir = getGroupAttachmentHostDir(groupFolder);
  fs.mkdirSync(dir, { recursive: true });
  return dir;
}

export function stageAttachmentsForGroup(
  groupFolder: string,
  attachments?: Attachment[],
): Attachment[] | undefined {
  if (!attachments?.length) return attachments;

  const hostDir = ensureGroupAttachmentHostDir(groupFolder);

  return attachments.map((attachment) => {
    if (!attachment.sourcePath) {
      // No file on disk yet — write base64/text data to the staging dir so the
      // container gets a mountedPath it can reference programmatically.
      if (!attachment.data) return attachment;
      const stagedHostPath = path.join(hostDir, buildStagedFileName(attachment.name || 'attachment'));
      const buffer = attachment.kind === 'text'
        ? Buffer.from(attachment.data, 'utf8')
        : Buffer.from(attachment.data, 'base64');
      fs.writeFileSync(stagedHostPath, buffer);
      return {
        ...attachment,
        mountedPath: path.posix.join(ATTACHMENTS_CONTAINER_DIR, path.basename(stagedHostPath)),
      };
    }

    const existingNormalized = path.resolve(attachment.sourcePath);
    const hostDirNormalized = path.resolve(hostDir);
    let stagedHostPath = existingNormalized;

    if (!existingNormalized.startsWith(`${hostDirNormalized}${path.sep}`)) {
      stagedHostPath = path.join(hostDir, buildStagedFileName(attachment.name));
      fs.copyFileSync(existingNormalized, stagedHostPath);
      cleanupAttachmentFiles([attachment]);
    }

    return {
      ...attachment,
      sourcePath: stagedHostPath,
      mountedPath: path.posix.join(ATTACHMENTS_CONTAINER_DIR, path.basename(stagedHostPath)),
    };
  });
}

export function cleanupAttachmentFiles(attachments?: Attachment[]): void {
  for (const attachment of attachments || []) {
    if (!attachment.sourcePath) continue;

    try {
      const sourcePath = attachment.sourcePath;
      const parentDir = path.dirname(sourcePath);
      const baseDir = path.basename(parentDir);

      if (baseDir.startsWith('nanoclaw-audio-')) {
        fs.rmSync(parentDir, { recursive: true, force: true });
        continue;
      }

      fs.rmSync(sourcePath, { force: true });
    } catch {
      // Ignore attachment temp cleanup failures.
    }
  }
}
