import { NextResponse } from 'next/server';
import fs from 'fs';
import path from 'path';
import { getDatasetsRoot } from '@/server/settings';

const sanitizeSegment = (value: string): string => {
  if (!value || typeof value !== 'string') {
    return '';
  }
  return value
    .toLowerCase()
    .replace(/[^a-z0-9]+/g, '_')
    .replace(/^_+|_+$/g, '');
};

const ensureDirectory = (dirPath: string) => {
  if (!fs.existsSync(dirPath)) {
    fs.mkdirSync(dirPath, { recursive: true });
  }
};

const resolveDatasetName = (rootPath: string, desiredName: string, namespace?: string | null) => {
  const baseName = sanitizeSegment(desiredName) || 'dataset';
  const namespaceSuffix = sanitizeSegment(namespace || '');

  const datasetExists = (candidate: string) => fs.existsSync(path.join(rootPath, candidate));

  if (!datasetExists(baseName)) {
    return { name: baseName, path: path.join(rootPath, baseName) };
  }

  if (namespaceSuffix) {
    let candidate = sanitizeSegment(`${baseName}_${namespaceSuffix}`) || `${baseName}_${namespaceSuffix}`;
    let attempts = 0;
    while (datasetExists(candidate)) {
      attempts += 1;
      if (attempts > 50) {
        throw new Error('Unable to allocate unique dataset name');
      }
      candidate = sanitizeSegment(`${candidate}_${namespaceSuffix}`) || `${candidate}_${namespaceSuffix}`;
    }
    return { name: candidate, path: path.join(rootPath, candidate) };
  }

  let counter = 2;
  while (counter < 1000) {
    const candidate = sanitizeSegment(`${baseName}_${counter}`) || `${baseName}_${counter}`;
    if (!datasetExists(candidate)) {
      return { name: candidate, path: path.join(rootPath, candidate) };
    }
    counter += 1;
  }

  throw new Error('Unable to allocate unique dataset name');
};

export async function POST(request: Request) {
  try {
    const body = await request.json();
    const { name, namespace } = body ?? {};

    if (!name || typeof name !== 'string') {
      throw new Error('Dataset name is required');
    }

    const datasetsPath = await getDatasetsRoot();
    const { name: resolvedName, path: datasetPath } = resolveDatasetName(
      datasetsPath,
      name,
      typeof namespace === 'string' ? namespace : null,
    );

    ensureDirectory(datasetPath);

    return NextResponse.json({
      success: true,
      name: resolvedName,
      path: datasetPath,
    });
  } catch (error: any) {
    console.error('Dataset create error:', error);
    return NextResponse.json({ error: error?.message || 'Failed to create dataset' }, { status: 500 });
  }
}
