import _ from 'lodash';
import { isFilePending } from 'mem-fs-editor/state';
import chalk from 'chalk';
import BaseApplicationGenerator from '../base-application/index.mjs';
import { GENERATOR_CLIENT, GENERATOR_LANGUAGES, GENERATOR_REACT } from '../generator-list.mjs';
import { writeEntitiesFiles, postWriteEntitiesFiles, cleanupEntitiesFiles } from './entity-files-react.mjs';
import cleanupOldFilesTask from './cleanup.mjs';
import { writeFiles } from './files-react.mjs';
import { prepareEntity } from './application/entities/index.mjs';
import { fieldTypes, clientFrameworkTypes } from '../../jdl/jhipster/index.mjs';
import { generateEntityClientEnumImports as getClientEnumImportsFormat, generateEntityClientFields as getHydratedEntityClientFields, generateEntityClientImports as formatEntityClientImports, generateTestEntityId as getTestEntityId, generateTestEntityPrimaryKey as getTestEntityPrimaryKey, } from '../client/support/index.mjs';
import { isTranslatedReactFile, translateReactFilesTransform } from './support/index.mjs';
import { createNeedleCallback, upperFirstCamelCase } from '../base/support/index.mjs';
const { CommonDBTypes } = fieldTypes;
const TYPE_BOOLEAN = CommonDBTypes.BOOLEAN;
const { REACT } = clientFrameworkTypes;
export default class ReactGenerator extends BaseApplicationGenerator {
    async beforeQueue() {
        if (!this.fromBlueprint) {
            await this.composeWithBlueprints(GENERATOR_REACT);
        }
        if (!this.delegateToBlueprint) {
            await this.dependsOnJHipster(GENERATOR_CLIENT);
            await this.dependsOnJHipster(GENERATOR_LANGUAGES);
        }
    }
    get loading() {
        return this.asLoadingTaskGroup({
            loadPackageJson({ application }) {
                this.loadNodeDependenciesFromPackageJson(application.nodeDependencies, this.fetchFromInstalledJHipster(GENERATOR_REACT, 'resources', 'package.json'));
            },
        });
    }
    get [BaseApplicationGenerator.LOADING]() {
        return this.asLoadingTaskGroup(this.delegateTasksToBlueprint(() => this.loading));
    }
    get preparing() {
        return this.asPreparingTaskGroup({
            prepareForTemplates({ application, source }) {
                application.webappEnumerationsDir = `${application.clientSrcDir}app/shared/model/enumerations/`;
                source.addWebpackConfig = args => {
                    const webpackPath = `${application.clientRootDir}webpack/webpack.common.js`;
                    const ignoreNonExisting = this.sharedData.getControl().ignoreNeedlesError && 'Webpack configuration file not found';
                    this.editFile(webpackPath, { ignoreNonExisting }, createNeedleCallback({
                        needle: 'jhipster-needle-add-webpack-config',
                        contentToAdd: `,${args.config}`,
                    }));
                };
            },
        });
    }
    get [BaseApplicationGenerator.PREPARING]() {
        return this.asPreparingTaskGroup(this.delegateTasksToBlueprint(() => this.preparing));
    }
    get preparingEachEntity() {
        return this.asPreparingEachEntityTaskGroup({
            react({ application, entity }) {
                prepareEntity({ entity, application });
            },
        });
    }
    get [BaseApplicationGenerator.PREPARING_EACH_ENTITY]() {
        return this.asPreparingEachEntityTaskGroup(this.delegateTasksToBlueprint(() => this.preparingEachEntity));
    }
    get writing() {
        return {
            cleanupOldFilesTask,
            writeFiles,
            queueTranslateTransform({ control, application }) {
                if (!application.enableTranslation) {
                    this.queueTransformStream(translateReactFilesTransform(control.getWebappTranslation), {
                        name: 'translating webapp',
                        streamOptions: { filter: file => isFilePending(file) && isTranslatedReactFile(file) },
                    });
                }
            },
        };
    }
    get [BaseApplicationGenerator.WRITING]() {
        return this.delegateTasksToBlueprint(() => this.writing);
    }
    get writingEntities() {
        return {
            cleanupEntitiesFiles,
            writeEntitiesFiles,
        };
    }
    get [BaseApplicationGenerator.WRITING_ENTITIES]() {
        return this.delegateTasksToBlueprint(() => this.writingEntities);
    }
    get postWritingEntities() {
        return {
            postWriteEntitiesFiles,
        };
    }
    get [BaseApplicationGenerator.POST_WRITING_ENTITIES]() {
        return this.delegateTasksToBlueprint(() => this.postWritingEntities);
    }
    get end() {
        return this.asEndTaskGroup({
            end({ application }) {
                this.log.ok('React application generated successfully.');
                this.log.log(chalk.green(`  Start your Webpack development server with:
  ${chalk.yellow.bold(`${application.nodePackageManager} start`)}
`));
            },
        });
    }
    get [BaseApplicationGenerator.END]() {
        return this.asEndTaskGroup(this.delegateTasksToBlueprint(() => this.end));
    }
    addEntityToMenu(routerName, enableTranslation, entityTranslationKeyMenu = _.camelCase(routerName), entityTranslationValue = _.startCase(routerName)) {
        this.needleApi.clientReact.addEntityToMenu(routerName, enableTranslation, entityTranslationKeyMenu, entityTranslationValue);
    }
    addEntityToModule(entityInstance = this.entityInstance, entityClass = this.entityClass, entityName = this.entityAngularName, entityFolderName = this.entityFolderName, entityFileName = this.entityFileName, { applicationTypeMicroservice, clientSrcDir }) {
        this.needleApi.clientReact.addEntityToModule(entityInstance, entityClass, entityName, entityFolderName, entityFileName, {
            applicationTypeMicroservice,
            clientSrcDir,
        });
    }
    generateEntityClientFieldDefaultValues(fields) {
        const defaultVariablesValues = {};
        fields.forEach(field => {
            const fieldType = field.fieldType;
            const fieldName = field.fieldName;
            if (fieldType === TYPE_BOOLEAN) {
                defaultVariablesValues[fieldName] = `${fieldName}: false,`;
            }
        });
        return defaultVariablesValues;
    }
    generateEntityClientFields(primaryKey, fields, relationships, dto, customDateType = 'dayjs.Dayjs', embedded = false) {
        return getHydratedEntityClientFields(primaryKey, fields, relationships, dto, customDateType, embedded, REACT);
    }
    generateEntityClientImports(relationships, dto) {
        return formatEntityClientImports(relationships, dto, REACT);
    }
    generateEntityClientEnumImports(fields) {
        return getClientEnumImportsFormat(fields, REACT);
    }
    generateTestEntityId(primaryKey, index = 0, wrapped = true) {
        return getTestEntityId(primaryKey, index, wrapped);
    }
    generateTestEntityPrimaryKey(primaryKey, index) {
        return getTestEntityPrimaryKey(primaryKey, index);
    }
    addAppSCSSStyle(style, comment) {
        this.needleApi.clientReact.addAppSCSSStyle(style, comment);
    }
    upperFirstCamelCase(value) {
        return upperFirstCamelCase(value);
    }
}
