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 Papa from 'papaparse';
const COLUMN_HEADERS = {
    identifier: 'Identifier',
    title: 'Title',
    description: 'Description',
    state: 'State',
    priority: 'Priority',
    labels: 'Labels',
    dueDate: 'Due Date',
    startDate: 'Start Date',
    estimate: 'Estimate',
    assignees: 'Assignees',
};
let ExportWorkItemsCsvUseCase = class ExportWorkItemsCsvUseCase {
    workItemRepo;
    cycleRepo;
    stateRepo;
    labelRepo;
    constructor(workItemRepo, cycleRepo, stateRepo, labelRepo) {
        this.workItemRepo = workItemRepo;
        this.cycleRepo = cycleRepo;
        this.stateRepo = stateRepo;
        this.labelRepo = labelRepo;
    }
    async execute(input) {
        let items = await this.workItemRepo.listByProject(input.projectId);
        if (input.cycleId) {
            const cycleItemIds = new Set(await this.cycleRepo.getWorkItemIds(input.cycleId));
            items = items.filter((i) => cycleItemIds.has(i.id));
        }
        const stateMap = await this.buildStateMap(input.projectId);
        const labelMap = await this.buildLabelMap(input.projectId);
        const needLabels = input.columns.includes('labels');
        const rows = [];
        for (const item of items) {
            const labelNames = needLabels ? await this.resolveLabels(item.id, labelMap) : [];
            rows.push(this.buildRow(item, input.columns, stateMap, labelNames));
        }
        const headers = input.columns.map((c) => COLUMN_HEADERS[c]);
        const csv = Papa.unparse({ fields: headers, data: rows });
        return { ok: true, csv, itemCount: items.length };
    }
    async buildStateMap(projectId) {
        const states = await this.stateRepo.listByProject(projectId);
        return new Map(states.map((s) => [s.id, s]));
    }
    async buildLabelMap(projectId) {
        const labels = await this.labelRepo.listByProject(projectId);
        return new Map(labels.map((l) => [l.id, l]));
    }
    async resolveLabels(workItemId, labelMap) {
        const labelIds = await this.workItemRepo.getLabels(workItemId);
        return labelIds.map((id) => labelMap.get(id)?.name ?? id);
    }
    buildRow(item, columns, stateMap, labelNames) {
        return columns.map((col) => {
            switch (col) {
                case 'identifier':
                    return `${item.identifierPrefix}-${item.sequenceId}`;
                case 'title':
                    return item.title;
                case 'description':
                    return item.description ?? '';
                case 'state':
                    return stateMap.get(item.stateId)?.name ?? item.stateId;
                case 'priority':
                    return item.priority;
                case 'labels':
                    return labelNames.join(', ');
                case 'dueDate':
                    return item.dueDate ? new Date(item.dueDate).toISOString().split('T')[0] : '';
                case 'startDate':
                    return item.startDate ? new Date(item.startDate).toISOString().split('T')[0] : '';
                case 'estimate':
                    return item.estimateValue ?? '';
                case 'assignees':
                    return '';
                default:
                    return '';
            }
        });
    }
};
ExportWorkItemsCsvUseCase = __decorate([
    injectable(),
    __param(0, inject('IWorkItemRepository')),
    __param(1, inject('ICycleRepository')),
    __param(2, inject('IWorkItemStateRepository')),
    __param(3, inject('ILabelRepository')),
    __metadata("design:paramtypes", [Object, Object, Object, Object])
], ExportWorkItemsCsvUseCase);
export { ExportWorkItemsCsvUseCase };
