import 'server-only';

import { buildCsvCommitPlan } from './csv/commit-builder';
import { buildImportReport, createImportError, type ImportReport } from './csv/import-report';
import { CsvCommitExecutionError, executeCsvCommitPlan } from './csv/upsert-executor';
import { previewSetupCsvImport } from './csv-preview.service';
import type { CsvPreviewFileInput } from './csv/types';

export interface CommitSetupCsvImportInput {
  files: CsvPreviewFileInput[];
  previewHash: string;
  dryRun?: boolean;
  actorId: string;
}

export async function commitSetupCsvImport(input: CommitSetupCsvImportInput): Promise<ImportReport> {
  const preview = await previewSetupCsvImport(input.files);
  const plan = buildCsvCommitPlan(preview);

  if (!input.previewHash) {
    return buildImportReport({
      previewHash: preview.previewHash,
      committedHash: plan.committedHash,
      dryRun: Boolean(input.dryRun),
      files: [
        {
          fileName: '__request__',
          template: 'setup-csv-commit',
          status: 'FAIL',
          imported: 0,
          updated: 0,
          skipped: 0,
          errors: [
            createImportError({
              file: '__request__',
              row: 1,
              column: 'previewHash',
              code: 'PREVIEW_HASH_REQUIRED',
              message: 'previewHash is required before committing CSV import.',
              suggestedFix: 'Call /api/setup/import/preview and submit the returned previewHash.'
            })
          ],
          warnings: [],
          rows: []
        }
      ]
    });
  }

  if (preview.previewHash !== input.previewHash) {
    return buildImportReport({
      previewHash: preview.previewHash,
      committedHash: plan.committedHash,
      dryRun: Boolean(input.dryRun),
      files: [
        {
          fileName: '__request__',
          template: 'setup-csv-commit',
          status: 'FAIL',
          imported: 0,
          updated: 0,
          skipped: 0,
          errors: [
            createImportError({
              file: '__request__',
              row: 1,
              column: 'previewHash',
              code: 'PREVIEW_HASH_MISMATCH',
              message: 'Submitted previewHash does not match the uploaded CSV files.',
              suggestedFix: 'Re-run preview for the exact files being committed and retry with the new previewHash.'
            })
          ],
          warnings: [],
          rows: []
        }
      ]
    });
  }

  if (preview.summary.error > 0) {
    return buildImportReport({
      previewHash: preview.previewHash,
      committedHash: plan.committedHash,
      dryRun: Boolean(input.dryRun),
      files: preview.files.map((file) => ({
        fileName: file.fileName,
        template: file.template,
        status: 'FAIL',
        imported: 0,
        updated: 0,
        skipped: 0,
        errors: file.errors,
        warnings: file.warnings,
        rows: file.rows.map((row) => ({
          row: row.row,
          action: row.action === 'error' ? 'error' : 'skip',
          businessKey: row.key,
          message: row.action === 'error' ? 'Preview row has blocking errors.' : 'Commit blocked because preview contains errors.',
          warnings: row.warnings,
          errors: row.errors
        }))
      }))
    });
  }

  let files;
  try {
    files = await executeCsvCommitPlan(plan, {
      actorId: input.actorId,
      dryRun: Boolean(input.dryRun)
    });
  } catch (error) {
    if (error instanceof CsvCommitExecutionError) {
      return buildImportReport({
        previewHash: preview.previewHash,
        committedHash: plan.committedHash,
        dryRun: Boolean(input.dryRun),
        files: error.files
      });
    }

    throw error;
  }

  return buildImportReport({
    previewHash: preview.previewHash,
    committedHash: plan.committedHash,
    dryRun: Boolean(input.dryRun),
    files
  });
}
