var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
    return function (target, key) { decorator(target, key, paramIndex); }
};
import { injectable, inject } from 'tsyringe';
import { randomUUID } from 'node:crypto';
import Papa from 'papaparse';
let ImportWorkItemsCsvUseCase = class ImportWorkItemsCsvUseCase {
    projectRepo;
    workItemRepo;
    stateRepo;
    activityRepo;
    constructor(projectRepo, workItemRepo, stateRepo, activityRepo) {
        this.projectRepo = projectRepo;
        this.workItemRepo = workItemRepo;
        this.stateRepo = stateRepo;
        this.activityRepo = activityRepo;
    }
    async execute(input) {
        const project = await this.projectRepo.findById(input.projectId);
        if (!project) {
            return { ok: false, error: `Project not found: "${input.projectId}"` };
        }
        const parsed = Papa.parse(input.csvContent, { header: false, skipEmptyLines: true });
        let rows = parsed.data;
        if (rows.length === 0) {
            return { ok: true, createdCount: 0, errors: [] };
        }
        const skipHeader = input.skipHeaderRow ?? true;
        if (skipHeader) {
            rows = rows.slice(1);
        }
        if (rows.length === 0) {
            return { ok: true, createdCount: 0, errors: [] };
        }
        const states = await this.stateRepo.listByProject(input.projectId);
        const stateNameMap = new Map(states.map((s) => [s.name.toLowerCase(), s]));
        const defaultState = states.find((s) => s.isDefault) ?? states[0];
        let createdCount = 0;
        const errors = [];
        for (let i = 0; i < rows.length; i++) {
            const row = rows[i];
            const rowNumber = skipHeader ? i + 2 : i + 1; // 1-indexed, accounting for header skip
            try {
                const mapped = this.mapRow(row, input.fieldMapping);
                const title = mapped.title?.trim();
                if (!title) {
                    errors.push({ rowNumber, error: 'Missing required field: title', value: mapped.title });
                    continue;
                }
                const stateId = this.resolveStateId(mapped.state, stateNameMap, defaultState);
                const sequenceId = await this.projectRepo.incrementWorkItemCounter(input.projectId);
                const now = new Date();
                const workItem = {
                    id: randomUUID(),
                    projectId: input.projectId,
                    sequenceId,
                    identifierPrefix: project.identifierPrefix,
                    title,
                    description: mapped.description,
                    stateId,
                    priority: mapped.priority ?? 'None',
                    sortOrder: 0,
                    startDate: mapped.startDate ? this.parseDate(mapped.startDate) : undefined,
                    dueDate: mapped.dueDate ? this.parseDate(mapped.dueDate) : undefined,
                    estimateValue: mapped.estimateValue,
                    createdAt: now,
                    updatedAt: now,
                };
                await this.workItemRepo.create(workItem);
                await this.activityRepo.create({
                    id: randomUUID(),
                    workItemId: workItem.id,
                    fieldName: 'created',
                    newValue: `Imported: ${title}`,
                    actorId: 'csv-import',
                    createdAt: now,
                    updatedAt: now,
                });
                createdCount++;
            }
            catch (error) {
                const message = error instanceof Error ? error.message : String(error);
                errors.push({ rowNumber, error: message });
            }
        }
        return { ok: true, createdCount, errors };
    }
    mapRow(row, mapping) {
        const result = {};
        for (const [colIndex, fieldName] of Object.entries(mapping)) {
            const idx = Number(colIndex);
            result[fieldName] = row[idx]?.trim() || undefined;
        }
        return result;
    }
    resolveStateId(stateName, stateNameMap, defaultState) {
        if (stateName) {
            const matched = stateNameMap.get(stateName.toLowerCase());
            if (matched)
                return matched.id;
        }
        return defaultState?.id ?? '';
    }
    parseDate(value) {
        const date = new Date(value);
        return isNaN(date.getTime()) ? undefined : date;
    }
};
ImportWorkItemsCsvUseCase = __decorate([
    injectable(),
    __param(0, inject('IPmProjectRepository')),
    __param(1, inject('IWorkItemRepository')),
    __param(2, inject('IWorkItemStateRepository')),
    __param(3, inject('IActivityLogRepository')),
    __metadata("design:paramtypes", [Object, Object, Object, Object])
], ImportWorkItemsCsvUseCase);
export { ImportWorkItemsCsvUseCase };
