import { createHash } from 'node:crypto';
import type {
  CsvPreviewFileResult,
  CsvPreviewResult,
  CsvPreviewRow,
  CsvPreviewStatus
} from './types';

export function resolveRowStatus(row: CsvPreviewRow): CsvPreviewStatus {
  if (row.errors.length > 0) return 'FAIL';
  if (row.warnings.length > 0) return 'WARNING';
  return 'PASS';
}

export function buildFileResult(input: {
  fileName: string;
  template: string;
  importOrder: number;
  rows: CsvPreviewRow[];
}): CsvPreviewFileResult {
  const errors = input.rows.flatMap((row) => row.errors);
  const warnings = input.rows.flatMap((row) => row.warnings);
  const status: CsvPreviewStatus = errors.length > 0 ? 'FAIL' : warnings.length > 0 ? 'WARNING' : 'PASS';

  return {
    fileName: input.fileName,
    template: input.template,
    importOrder: input.importOrder,
    status,
    summary: {
      rows: input.rows.length,
      valid: input.rows.filter((row) => row.status === 'PASS').length,
      warning: input.rows.filter((row) => row.status === 'WARNING').length,
      error: input.rows.filter((row) => row.status === 'FAIL').length,
      create: input.rows.filter((row) => row.action === 'create').length,
      update: input.rows.filter((row) => row.action === 'update').length,
      skip: input.rows.filter((row) => row.action === 'skip').length
    },
    rows: input.rows,
    errors,
    warnings
  };
}

export function buildPreviewResult(files: CsvPreviewFileResult[]): CsvPreviewResult {
  const summary = files.reduce(
    (accumulator, file) => ({
      files: accumulator.files + 1,
      rows: accumulator.rows + file.summary.rows,
      valid: accumulator.valid + file.summary.valid,
      warning: accumulator.warning + file.summary.warning,
      error: accumulator.error + file.summary.error,
      create: accumulator.create + file.summary.create,
      update: accumulator.update + file.summary.update,
      skip: accumulator.skip + file.summary.skip
    }),
    { files: 0, rows: 0, valid: 0, warning: 0, error: 0, create: 0, update: 0, skip: 0 }
  );

  const generatedAt = new Date().toISOString();
  const previewHash = createHash('sha256')
    .update(
      JSON.stringify({
        files: files.map((file) => ({
          fileName: file.fileName,
          template: file.template,
          importOrder: file.importOrder,
          rows: file.rows.map((row) => ({
            row: row.row,
            key: row.key,
            values: row.values,
            status: row.status,
            action: row.action,
            errors: row.errors.map((error) => error.code),
            warnings: row.warnings.map((warning) => warning.code)
          }))
        }))
      })
    )
    .digest('hex');

  return { summary, files, generatedAt, previewHash };
}
