import {ExportImportTarget, StoreExporter} from "./Exporters";
import {ExportableDataFormat, ExportableDataFormatPreset, ExportableDataFormatServer} from "./AppImporter";
import {GroveExporter} from "./GroveExporter";
import {NodesStore} from "../store";
import {Testable} from "../Testable";
import {Testables} from "../testables";
import {currentPreloadedDynamicData} from "./ComponentExporterImporter";
import {Grove} from "../Grove";
import {atomsStore, ModelAtom} from "../atoms";

export class AppExporter implements StoreExporter<ExportableDataFormat> {
    constructor(
        private store: NodesStore,
        private groveExporter: GroveExporter
    ) {}

    export(target: ExportImportTarget): ExportableDataFormat {
        const preconditionsGroup = this.store.preconditionsID ? new Testable(
            new Testables(this.store),
            this.store.preconditionsID
        ) : undefined

        const predatesGroup = this.store.predatesID ? new Testable(
            new Testables(this.store),
            this.store.predatesID
        ) : undefined
        // can you see the pattern above?


        const exportedAppData =  {
            version: 1,
            grove: this.groveExporter.exportAsData(target),
            preconditions: preconditionsGroup?.exists() ? preconditionsGroup.export(target) : undefined,
            predates: predatesGroup?.exists() ? predatesGroup.export(target) : undefined,
        } as ExportableDataFormatPreset | ExportableDataFormatServer;

        if (target === 'server') {
            (exportedAppData as ExportableDataFormatServer).preloadedData = currentPreloadedDynamicData.items;
            (exportedAppData as ExportableDataFormatServer).testablePartialRelations = this.getTestablePartialRelations();
            (exportedAppData as ExportableDataFormatServer).autoApply = this.store.autoApply? 'yes' : 'no';
            (exportedAppData as ExportableDataFormatServer).model = atomsStore.get(ModelAtom);
        }

        // reset dynamic testables store after export
        // we do this because dynamic testables are only relevant during this export operation
        // for example, the user might remove components after this and then export again
        // in that case, we don't want the removed components to be part of the new export
        currentPreloadedDynamicData.reset()

        return exportedAppData
    }

    private getTestablePartialRelations() : ExportableDataFormatServer['testablePartialRelations'] {
        const {testables} = Grove.fromState(this.store, true)

        const partialRelations = testables.getPartialRelations()

        return partialRelations.map(relation => ({
            ...relation,
            data: testables.getNode(relation.id)!
        }))
    }
}