"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.configureFrontendGenerator = exports.frontendGeneratorId = exports.toComponentImport = exports.all = exports.spreadsheet = exports.charts = exports.base = void 0;
const Path = __importStar(require("node:path"));
const Generator = __importStar(require("@postxl/generator"));
const generator_1 = require("@postxl/generator");
const tsconfig_generator_1 = require("./generators/tsconfig.generator");
const ROOT_ROUTE_FILENAME = '__root.tsx';
// CONTEXT REGISTRATION --------------------------------------------------------
exports.base = {
    components: ['color-mode-toggle'],
    hooks: ['useFontsLoaded.ts'],
    contextProviders: ['auth-context-provider.tsx', 'theme-context-provider.tsx'],
    packageJson: {
        // We set name and description with the context's slug in the register function as we do not have access to the schema here yet
        name: (0, generator_1.toPostXlPackageName)(`@postxl/template-frontend`),
        description: `Frontend for the template project`,
        type: 'module',
        dependencies: [
            { packageName: Generator.toPostXlPackageName('@postxl/ui-components') },
            { packageName: Generator.toPostXlPackageName('@postxl/utils') },
            { packageName: '@radix-ui/react-icons', version: '1.3.2' },
            { packageName: '@tailwindcss/vite', version: '4.1.16' },
            { packageName: '@tanstack/react-devtools', version: '0.7.9' },
            { packageName: '@tanstack/react-router', version: '1.131.34' },
            { packageName: '@tanstack/react-router-devtools', version: '1.131.34' },
            { packageName: '@tanstack/react-table', version: '8.21.3' },
            { packageName: '@visx/responsive', version: '3.12.0' },
            { packageName: 'class-variance-authority', version: '0.7.1' },
            { packageName: 'clsx', version: '2.1.1' },
            { packageName: 'date-fns', version: '4.1.0' },
            { packageName: 'keycloak-js', version: '26.2.1' },
            { packageName: 'lucide-react', version: '0.554.0' },
            { packageName: 'react', version: '19.1.1' },
            { packageName: 'react-day-picker', version: '9.11.1' },
            { packageName: 'react-dom', version: '19.1.1' },
            { packageName: 'sonner', version: '2.0.7' },
            { packageName: 'superjson', version: '1.13.1' },
            { packageName: 'tailwind-merge', version: '3.3.1' },
            { packageName: 'tailwindcss', version: '4.1.16' },
            { packageName: 'tw-animate-css', version: '1.4.0' },
            { packageName: 'use-local-storage-state', version: '19.5.0' },
            { packageName: 'use-session-storage-state', version: '19.0.1' },
            { packageName: 'zod', version: '4.3.5' },
        ],
        devDependencies: [
            { packageName: '@chromatic-com/storybook', version: '4.1.2' },
            { packageName: '@eslint/js', version: '9.39.1' },
            { packageName: 'eslint-plugin-react', version: '7.37.5' },
            { packageName: '@storybook/addon-docs', version: '10.0.0' },
            { packageName: '@storybook/addon-onboarding', version: '10.0.0' },
            { packageName: '@storybook/addon-vitest', version: '10.0.0' },
            { packageName: '@storybook/react-vite', version: '10.0.0' },
            { packageName: '@tanstack/devtools-ui', version: '0.4.4' },
            { packageName: '@tanstack/devtools-vite', version: '0.3.10' },
            { packageName: '@tanstack/router-plugin', version: '1.131.34' },
            { packageName: '@tanstack/router-cli', version: '1.131.34' },
            { packageName: '@types/geojson', version: '7946.0.16' },
            { packageName: '@types/react', version: '19.1.10' },
            { packageName: '@types/react-dom', version: '19.1.7' },
            { packageName: '@vitejs/plugin-basic-ssl', version: '2.1.0' },
            { packageName: '@vitejs/plugin-react', version: '5.1.0' },
            { packageName: '@vitest/browser', version: '3.2.4' },
            { packageName: '@vitest/coverage-v8', version: '3.2.4' },
            { packageName: 'eslint', version: '9.39.1' },
            { packageName: 'eslint-plugin-react-hooks', version: '7.0.1' },
            { packageName: 'eslint-plugin-react-refresh', version: '0.4.24' },
            { packageName: 'globals', version: '16.4.0' },
            { packageName: 'playwright', version: '1.56.1' },
            { packageName: 'storybook', version: '10.0.0' },
            { packageName: 'typescript', version: '~5.8.3' },
            { packageName: 'typescript-eslint', version: '8.50.0' },
            { packageName: 'vite', version: '7.1.12' },
            { packageName: 'vite-bundle-analyzer', version: '1.2.3' },
            { packageName: 'vite-plugin-svgr', version: '4.5.0' },
            { packageName: 'vite-tsconfig-paths', version: '5.1.4' },
            { packageName: 'vitest', version: '3.2.4' },
            { packageName: 'vitest-browser-react', version: '1.0.1' },
        ],
        scripts: [
            { name: 'build', command: 'pnpm test:types && vite build' },
            { name: 'build:analyze', command: 'vite build' },
            { name: 'debug', command: 'pnpm vite build --debug' },
            { name: 'dev', command: 'VITE_ENABLE_DEV_TOOLS=true vite' },
            { name: 'dev:noAuth', command: 'VITE_AUTH=false VITE_ENABLE_DEV_TOOLS=true vite' },
            {
                name: 'e2e:build',
                command: 'VITE_PUBLIC_API_URL=http://host.docker.internal:3001 VITE_PUBLIC_API_URL_2=http://host.docker.internal:3001 VITE_PUBLIC_BASE_URL=http://host.docker.internal:3000 NODE_V8_COVERAGE=.v8-coverage VITE_PUBLIC_MAPBOX_DISABLE_TRANSITIONS=true VITE_PUBLIC_USE_TEST_ASSETS=true VITE_AUTH=false vite build && vite preview --port 3000',
            },
            {
                name: 'e2e:ci',
                command: 'NODE_V8_COVERAGE=.v8-coverage VITE_PUBLIC_MAPBOX_DISABLE_TRANSITIONS=true VITE_PUBLIC_USE_TEST_ASSETS=true VITE_AUTH=false vite build && vite preview --port 3000',
            },
            { name: 'lint', command: 'eslint .' },
            { name: 'preview', command: 'vite preview' },
            { name: 'storybook:build', command: 'storybook build' },
            { name: 'storybook:start', command: 'storybook dev -p 6006' },
            { name: 'test:storybook', command: 'vitest run --project=storybook' },
            { name: 'test:types', command: 'tsc --noEmit -p tsconfig.json' },
            { name: 'test:types', command: 'tsc --noEmit' },
        ],
    },
    tsConfigReferences: new Map(),
};
/**
 * TODO backport charts from portfolex (when ready)
 */
exports.charts = {
    components: ['chart'],
    packageJson: { dependencies: [{ packageName: 'recharts', version: '2.13.3' }] },
};
exports.spreadsheet = {
    components: ['spreadsheet'],
    packageJson: {
        dependencies: [],
    },
};
/**
 *
 */
const all = (config) => {
    return (config
        //
        .with(exports.charts)
        .with(exports.spreadsheet));
};
exports.all = all;
// CODE GENERATION -------------------------------------------------------------
const toComponentImport = (name, exposing) => exposing.length === 0
    ? `import * as ${name
        .split('-')
        .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
        .join('')} from '@components/${name}'`
    : `import { ${exposing.join(', ')} } from '@components/ui/${name}/${name}'`;
exports.toComponentImport = toComponentImport;
exports.frontendGeneratorId = Generator.toGeneratorInterfaceId('frontend-core');
const configureFrontendGenerator = (into) => ({
    id: exports.frontendGeneratorId,
    implementsInterface: [exports.frontendGeneratorId],
    requires: [],
    register: (context) => {
        const packageName = (0, generator_1.toPostXlPackageName)(`@postxl/${context.schema.slug}-frontend`);
        const frontend = into ? into(new generator_1.ConfigBuilder(exports.base)).done() : exports.base;
        frontend.packageJson.name = packageName;
        frontend.packageJson.description = `Frontend for the ${context.schema.slug} project`;
        frontend.packageJson.isInPostXlWorkspace = context.schema.projectType === 'workspace';
        frontend.packageJson.scripts.push({ name: 'generate:tsr', command: 'tsr generate' });
        context.base.packageJson.scripts.push({
            name: 'generate:tsr',
            command: `pnpm --filter ${packageName} exec tsr generate`,
        });
        // replace the generate script to also run tsr generate
        const generateScript = context.base.packageJson.scripts.find((s) => s.name === 'generate:project');
        if (generateScript) {
            generateScript.command += ' && pnpm run generate:tsr';
        }
        else {
            context.base.packageJson.scripts.push({ name: 'generate:project', command: 'pnpm run generate:tsr' });
        }
        return { ...context, frontend };
    },
    // TODO @Peter: context type <Context extends ContextResult>(context: Context): void => {
    afterRegistrations: (context) => {
        for (const backendModule of context.backend.modules) {
            context.frontend.tsConfigReferences.set(backendModule.name, {
                name: backendModule.name,
                filePath: Generator.toFilePath(`../../backend/libs/${backendModule.name}/src`),
                hasIndex: backendModule.hasIndex ?? false,
            });
        }
    },
    generate: async (context) => {
        const template = Path.join(__dirname, './template');
        const target = '/frontend';
        const copyToRelativeLocation = (path) => {
            const diskPath = Path.join(template, path);
            const targetPath = Path.join(target, path);
            return { diskPath, targetPath };
        };
        context.vfs.write(Path.join(target, 'package.json'), (0, generator_1.generatePackageJson)(context.frontend.packageJson));
        await context.vfs.loadFolder({ ...copyToRelativeLocation('./'), recursive: false });
        await context.vfs.loadFolder(copyToRelativeLocation('public'));
        await context.vfs.loadFolder(copyToRelativeLocation('.storybook'));
        await context.vfs.loadFolder({ ...copyToRelativeLocation('src'), recursive: false });
        await context.vfs.loadFolder(copyToRelativeLocation('src/pages'));
        await context.vfs.loadFolder({
            ...copyToRelativeLocation('src/routes'),
            filter: (filePath) => !filePath.endsWith(ROOT_ROUTE_FILENAME),
        });
        // Load __root.tsx with template substitution for schema.name
        const rootRouteContent = await (0, generator_1.generateFromTemplate)({
            file: Path.join(template, 'src/routes', ROOT_ROUTE_FILENAME),
            context: { schema: context.schema },
        });
        if (rootRouteContent.isErr()) {
            throw new Error(`Failed to generate ${ROOT_ROUTE_FILENAME}: ${rootRouteContent.unwrapErr().message}`);
        }
        context.vfs.write(Path.join(target, 'src/routes', ROOT_ROUTE_FILENAME), rootRouteContent.unwrap());
        await context.vfs.loadFolder(copyToRelativeLocation('src/stories'));
        // await context.vfs.loadFolder(copyToRelativeLocation('src/i18n'))
        await context.vfs.loadFolder(copyToRelativeLocation('src/lib'));
        await context.vfs.loadFolder(copyToRelativeLocation('src/styles'));
        for (const hook of new Set(context.frontend.hooks)) {
            await context.vfs.loadFile(copyToRelativeLocation(`src/hooks/${hook}`));
        }
        await context.vfs.loadFolder(copyToRelativeLocation('src/components/admin'));
        for (const component of new Set(context.frontend.components)) {
            await context.vfs.loadFolder(copyToRelativeLocation(`src/components/ui/${component}`));
        }
        for (const contextProvider of new Set(context.frontend.contextProviders)) {
            await context.vfs.loadFile(copyToRelativeLocation(`src/context-providers/${contextProvider}`));
        }
        context.vfs.write(Path.join(target, 'tsconfig.json'), (0, tsconfig_generator_1.generateTsConfig)(context));
        context.vfs.write(Path.join(target, '.env'), context.vfs.get(Path.join(target, '.env.example')) ?? '');
        return context;
    },
});
exports.configureFrontendGenerator = configureFrontendGenerator;
//# sourceMappingURL=frontend.generator.js.map