/**
 * ts-xsd Codegen Configuration for adt-plugin-abapgit
 *
 * 3-Step Pipeline:
 * 1. rawSchema() - Generate raw schema literals with `as const`
 * 2. flattenedInterfaces() - Generate TypeScript interfaces from XSD
 * 3. indexBarrel() - Generate typed index exports
 *
 * Usage:
 *   npx nx codegen adt-plugin-abapgit
 */

import {
  defineConfig,
  rawSchema,
  interfaces,
  indexBarrel,
} from '@abapify/ts-xsd/generators';

export default defineConfig({
  // Use extensionless imports for bundler compatibility
  importExtension: '',
  // Clean output directories before generation
  clean: true,
  sources: {
    abapgit: {
      xsdDir: 'xsd',
      outputDir: 'src/schemas/generated/schemas',
      // Only object schemas - base schemas (asx, abapgit) are included via xs:import/xs:include
      // and their types get merged into each object schema during resolution
      schemas: [
        'clas',
        'devc',
        'doma',
        'dtel',
        'intf',
        'prog',
        'fugr',
        'tabl',
        'ttyp',
        'bdef',
        'srvd',
        'srvb',
      ],
    },
  },
  generators: [
    // Generate raw schema literals with default export
    // Using resolve: true to merge imports, expand extensions and substitution groups
    rawSchema({
      defaultExport: true,
      $xmlns: true,
      $imports: false, // Not needed when resolve is enabled - schema is self-contained
      resolve: true, // Merge imports, expand extensions and substitution groups
    }),
    // Generate flattened TypeScript types to ../types/ directory
    interfaces({
      filePattern: '../types/{name}.ts',
      flatten: true, // Flatten all types into single file with root type alias
      addJsDoc: true,
    }),
    // Generate index.ts barrel file for schemas
    indexBarrel({
      namedExports: true,
      importExtension: '', // Extensionless - tsx loader handles resolution
    }),
  ],

  // Generate aggregate index files after all sources are processed
  afterAll(ctx) {
    // Get all schemas from context
    const schemas = Object.values(ctx.sources).flatMap((s) => s.schemas);

    // Helper to capitalize first letter
    const capitalize = (s: string) => s.charAt(0).toUpperCase() + s.slice(1);

    // Types index file - each schema has its own type, export with renamed alias
    // When flatten: true, the root type is {Schema}Schema (e.g., ClasSchema)
    // When flatten: false, it's AbapGitType
    const typesIndex = [
      '/**',
      ' * Auto-generated types index',
      ' * ',
      ' * DO NOT EDIT - Generated by ts-xsd codegen',
      ' */',
      '',
      `// Object types - flattened root types renamed per schema to avoid conflicts`,
      ...schemas.map(
        (s) =>
          `export type { ${capitalize(s)}Schema as ${capitalize(s)}AbapGitType } from './${s}';`,
      ),
      '',
    ].join('\n');

    // Generate typed AbapGit schemas file
    // This replaces the manual src/lib/handlers/schemas.ts
    const schemasFile = [
      '/**',
      ' * AbapGit Typed Schemas',
      ' * ',
      ' * Auto-generated by ts-xsd codegen - DO NOT EDIT',
      ' * ',
      ' * Each schema provides:',
      ' * - _type: Full AbapGitType (for XML build/parse)',
      ' * - _values: Inner values type (for handler mapping)',
      ' * - parse(xml) → fully typed object',
      ' * - build(data) → XML string',
      ' * - schema → raw schema literal',
      ' */',
      '',
      `import { abapGitSchema } from '../../lib/handlers/abapgit-schema';`,
      '',
      '// Raw schemas',
      ...schemas.map((s) => `import _${s} from './schemas/${s}';`),
      '',
      '// Full AbapGit types - using flattened root types',
      '// Note: Generated types may be unions, we import the raw schema type',
      ...schemas.map(
        (s) =>
          `import type { ${capitalize(s)}Schema as _${capitalize(s)}Schema } from './types/${s}';`,
      ),
      '',
      '// Extract the abapGit variant from union types (generated types may be unions)',
      ...schemas.map(
        (s) =>
          `type ${capitalize(s)}AbapGitType = Extract<_${capitalize(s)}Schema, { abapGit: unknown }>;`,
      ),
      '',
      '// AbapGit schema instances - using flattened types with values extracted from abapGit.abap.values',
      ...schemas.map(
        (s) =>
          `export const ${s} = abapGitSchema<${capitalize(s)}AbapGitType, ${capitalize(s)}AbapGitType['abapGit']['abap']['values']>(_${s});`,
      ),
      '',
      '// Re-export types and utilities',
      `export { abapGitSchema, type AbapGitSchema, type InferAbapGitType, type InferValuesType } from '../../lib/handlers/abapgit-schema';`,
      '',
    ].join('\n');

    return [
      { path: 'src/schemas/generated/types/index.ts', content: typesIndex },
      { path: 'src/schemas/generated/index.ts', content: schemasFile },
    ];
  },
});
