import type { DepKind, DepRef } from './analyze-source';

export interface DependencyEntry {
  id: string;
  source: string;
  target: string;
  version: string;
  notes: string;
  status: 'auto' | 'modified' | 'added' | 'removed';
  /** What this dependency is — drives how it's migrated (internal vs external package). */
  kind?: DepKind;
  /** True when target/version is a guess that must be verified against a registry. */
  verify?: boolean;
}

function pascal(name: string): string {
  return name
    .toLowerCase()
    .split(/[-_.\s]+/)
    .filter(Boolean)
    .map((w) => w.charAt(0).toUpperCase() + w.slice(1))
    .join('');
}

/** Map a non-external (legacy/internal) dependency to its in-project target representation. */
function internalProposal(dep: DepRef): { target: string; version: string; notes: string } {
  const p = pascal(dep.name);
  switch (dep.kind) {
    case 'copybook':
      return { target: `${p} (record/class)`, version: 'internal', notes: 'Copybook → generated target data class; not an external package.' };
    case 'called-program':
      return { target: `${p}`, version: 'internal', notes: 'Called program → internal module/service in the target.' };
    case 'cics-program':
      return { target: `${p}`, version: 'internal', notes: 'CICS LINK/XCTL target → internal service call.' };
    case 'cics-map':
      return { target: `${p}View`, version: 'internal', notes: 'BMS map → target UI/DTO.' };
    case 'sql-table':
      return { target: `${p} (entity)`, version: 'internal', notes: 'DB2 table → JPA entity / repository.' };
    case 'dataset':
      return { target: `${dep.name}`, version: 'internal', notes: 'Dataset/VSAM file → file or DB-backed access in the target.' };
    default:
      return { target: dep.name, version: 'n/a', notes: 'Manual review required.' };
  }
}

const KNOWN_MAPPINGS: Record<string, Record<string, { target: string; version: string; notes: string }>> = {
  'python:typescript': {
    requests: { target: 'axios', version: '^1.6.0', notes: 'HTTP client' },
    flask: { target: 'express', version: '^4.18.0', notes: 'Web framework' },
    django: { target: 'express', version: '^4.18.0', notes: 'Web framework (consider NestJS for full-stack)' },
    sqlalchemy: { target: 'typeorm', version: '^0.3.0', notes: 'ORM' },
    pandas: { target: 'danfojs', version: '^1.1.2', notes: 'Data manipulation library' },
    numpy: { target: 'numjs', version: '^0.16.1', notes: 'Numerical computing' },
    pytest: { target: 'jest', version: '^29.0.0', notes: 'Testing framework' },
    celery: { target: 'bull', version: '^4.11.0', notes: 'Task queue' },
    redis: { target: 'ioredis', version: '^5.3.0', notes: 'Redis client' },
    pydantic: { target: 'zod', version: '^3.22.0', notes: 'Schema validation' },
  },
  'python:java': {
    requests: { target: 'okhttp', version: '4.12.0', notes: 'HTTP client' },
    flask: { target: 'spring-boot-starter-web', version: '3.2.0', notes: 'Web framework' },
    django: { target: 'spring-boot-starter-web', version: '3.2.0', notes: 'Web framework' },
    sqlalchemy: { target: 'spring-data-jpa', version: '3.2.0', notes: 'JPA/Hibernate ORM' },
    pandas: { target: 'tablesaw', version: '0.43.1', notes: 'Data manipulation' },
    pytest: { target: 'junit-jupiter', version: '5.10.0', notes: 'Testing framework' },
    celery: { target: 'spring-kafka', version: '3.1.0', notes: 'Message-driven tasks' },
    redis: { target: 'spring-data-redis', version: '3.2.0', notes: 'Redis client' },
    pydantic: { target: 'jakarta.validation', version: '3.0.2', notes: 'Bean Validation' },
  },
  'java:kotlin': {
    'spring-boot': { target: 'spring-boot', version: '3.2.0', notes: 'Kotlin-first Spring Boot' },
    'spring-data-jpa': { target: 'spring-data-jpa', version: '3.2.0', notes: 'Direct equivalent' },
    'spring-security': { target: 'spring-security', version: '6.2.0', notes: 'Direct equivalent' },
    junit: { target: 'kotest', version: '5.8.0', notes: 'Idiomatic Kotlin testing' },
    'junit-jupiter': { target: 'kotest', version: '5.8.0', notes: 'Idiomatic Kotlin testing' },
    gson: { target: 'kotlinx-serialization', version: '1.6.2', notes: 'Kotlin-native JSON' },
    jackson: { target: 'jackson-module-kotlin', version: '2.16.0', notes: 'Jackson Kotlin extension' },
    lombok: { target: 'data-classes', version: 'built-in', notes: 'Kotlin data classes replace Lombok' },
  },
  'java:typescript': {
    'spring-boot-starter-web': { target: 'express', version: '^4.18.0', notes: 'Web framework' },
    'spring-data-jpa': { target: 'typeorm', version: '^0.3.0', notes: 'ORM' },
    hibernate: { target: 'typeorm', version: '^0.3.0', notes: 'ORM' },
    gson: { target: 'JSON.parse/stringify', version: 'built-in', notes: 'Native JSON support' },
    jackson: { target: 'JSON.parse/stringify', version: 'built-in', notes: 'Native JSON support' },
    junit: { target: 'jest', version: '^29.0.0', notes: 'Testing framework' },
    'junit-jupiter': { target: 'jest', version: '^29.0.0', notes: 'Testing framework' },
    slf4j: { target: 'winston', version: '^3.11.0', notes: 'Logging library' },
    log4j: { target: 'winston', version: '^3.11.0', notes: 'Logging library' },
    lombok: { target: 'none', version: 'n/a', notes: 'TypeScript interfaces replace Lombok POJOs' },
  },
  'java:go': {
    'spring-boot-starter-web': { target: 'gin', version: 'v1.9.1', notes: 'HTTP web framework' },
    'spring-data-jpa': { target: 'gorm', version: 'v1.25.5', notes: 'ORM' },
    hibernate: { target: 'gorm', version: 'v1.25.5', notes: 'ORM' },
    gson: { target: 'encoding/json', version: 'stdlib', notes: 'Standard library JSON' },
    jackson: { target: 'encoding/json', version: 'stdlib', notes: 'Standard library JSON' },
    junit: { target: 'testing', version: 'stdlib', notes: 'Standard library testing' },
    slf4j: { target: 'zap', version: 'v1.26.0', notes: 'High-performance logger' },
    log4j: { target: 'zap', version: 'v1.26.0', notes: 'High-performance logger' },
  },
  'php:java': {
    'guzzlehttp/guzzle': { target: 'okhttp', version: '4.12.0', notes: 'HTTP client' },
    'symfony/symfony': { target: 'spring-boot-starter-web', version: '3.2.0', notes: 'Web framework' },
    laravel: { target: 'spring-boot-starter-web', version: '3.2.0', notes: 'Web framework' },
    'doctrine/dbal': { target: 'spring-data-jpa', version: '3.2.0', notes: 'ORM' },
    phpunit: { target: 'junit-jupiter', version: '5.10.0', notes: 'Testing framework' },
    monolog: { target: 'slf4j-api', version: '2.0.9', notes: 'Logging facade' },
    'illuminate/database': { target: 'spring-data-jpa', version: '3.2.0', notes: 'ORM (Eloquent → JPA)' },
  },
  'php:typescript': {
    'guzzlehttp/guzzle': { target: 'axios', version: '^1.6.0', notes: 'HTTP client' },
    'symfony/symfony': { target: 'express', version: '^4.18.0', notes: 'Web framework' },
    laravel: { target: 'express', version: '^4.18.0', notes: 'Web framework' },
    'doctrine/dbal': { target: 'typeorm', version: '^0.3.0', notes: 'ORM' },
    phpunit: { target: 'jest', version: '^29.0.0', notes: 'Testing framework' },
    monolog: { target: 'winston', version: '^3.11.0', notes: 'Logging library' },
    'illuminate/database': { target: 'typeorm', version: '^0.3.0', notes: 'ORM (Eloquent → TypeORM)' },
  },
  'cobol:java': {
    ERRHAND: { target: 'spring-boot-starter', version: '3.2.0', notes: 'Error handling via Spring exception management' },
    WSCOMM: { target: 'spring-messaging', version: '6.1.0', notes: 'Message/communication utilities' },
    DBCONN: { target: 'spring-data-jpa', version: '3.2.0', notes: 'Database connectivity' },
    RPTUTIL: { target: 'jasperreports', version: '6.21.0', notes: 'Report generation' },
    DATEUTIL: { target: 'java.time', version: 'stdlib', notes: 'Date/time utilities (JDK built-in)' },
    STRUTIL: { target: 'apache-commons-lang3', version: '3.14.0', notes: 'String utilities' },
    FILEIO: { target: 'java.nio', version: 'stdlib', notes: 'File I/O (JDK built-in)' },
    MATHLIB: { target: 'java.math', version: 'stdlib', notes: 'Math utilities (JDK built-in)' },
  },
  'cobol:typescript': {
    ERRHAND: { target: 'express-async-errors', version: '^3.1.1', notes: 'Async error handling' },
    WSCOMM: { target: 'axios', version: '^1.6.0', notes: 'Communication utilities' },
    DBCONN: { target: 'typeorm', version: '^0.3.0', notes: 'Database connectivity' },
    RPTUTIL: { target: 'pdfkit', version: '^0.14.0', notes: 'Report generation' },
    DATEUTIL: { target: 'date-fns', version: '^3.3.1', notes: 'Date/time utilities' },
    STRUTIL: { target: 'lodash', version: '^4.17.21', notes: 'String/utility library' },
    FILEIO: { target: 'fs/promises', version: 'stdlib', notes: 'File I/O (Node.js built-in)' },
    MATHLIB: { target: 'mathjs', version: '^12.3.0', notes: 'Math utilities' },
  },
  'cobol:python': {
    ERRHAND: { target: 'logging', version: 'stdlib', notes: 'Error handling via Python logging' },
    WSCOMM: { target: 'requests', version: '^2.31.0', notes: 'Communication utilities' },
    DBCONN: { target: 'sqlalchemy', version: '^2.0.0', notes: 'Database connectivity' },
    RPTUTIL: { target: 'reportlab', version: '^4.1.0', notes: 'Report generation' },
    DATEUTIL: { target: 'datetime', version: 'stdlib', notes: 'Date/time utilities' },
    STRUTIL: { target: 'string', version: 'stdlib', notes: 'String utilities (standard library)' },
    FILEIO: { target: 'pathlib', version: 'stdlib', notes: 'File I/O (standard library)' },
    MATHLIB: { target: 'math', version: 'stdlib', notes: 'Math utilities (standard library)' },
  },
  'rpg:java': {
    QUSRTOOL: { target: 'spring-boot-starter', version: '3.2.0', notes: 'AS/400 utility toolset → Spring runtime' },
    QCMDEXC: { target: 'spring-shell', version: '3.2.0', notes: 'Command execution → Spring Shell' },
    QDBOPEN: { target: 'spring-data-jpa', version: '3.2.0', notes: 'DB2/AS400 file access → JPA' },
    QSNDDTAQ: { target: 'spring-kafka', version: '3.1.0', notes: 'Data queue → Kafka messaging' },
    QRCVDTAQ: { target: 'spring-kafka', version: '3.1.0', notes: 'Data queue receive → Kafka consumer' },
    QDCXLATE: { target: 'apache-commons-codec', version: '1.16.0', notes: 'Character translation utilities' },
    QUSRJOBI: { target: 'spring-actuator', version: '3.2.0', notes: 'Job info → Actuator health/info' },
  },
  'csharp:java': {
    'System.Net.Http': { target: 'okhttp', version: '4.12.0', notes: 'HTTP client' },
    'Microsoft.AspNetCore': { target: 'spring-boot-starter-web', version: '3.2.0', notes: 'Web framework' },
    'Microsoft.EntityFrameworkCore': { target: 'spring-data-jpa', version: '3.2.0', notes: 'ORM' },
    'Newtonsoft.Json': { target: 'jackson-databind', version: '2.16.0', notes: 'JSON library' },
    'System.Text.Json': { target: 'jackson-databind', version: '2.16.0', notes: 'JSON library' },
    xunit: { target: 'junit-jupiter', version: '5.10.0', notes: 'Testing framework' },
    nunit: { target: 'junit-jupiter', version: '5.10.0', notes: 'Testing framework' },
    'Microsoft.Extensions.Logging': { target: 'slf4j-api', version: '2.0.9', notes: 'Logging facade' },
    AutoMapper: { target: 'mapstruct', version: '1.5.5.Final', notes: 'Object mapping' },
  },
  'csharp:typescript': {
    'System.Net.Http': { target: 'axios', version: '^1.6.0', notes: 'HTTP client' },
    'Microsoft.AspNetCore': { target: 'express', version: '^4.18.0', notes: 'Web framework' },
    'Microsoft.EntityFrameworkCore': { target: 'typeorm', version: '^0.3.0', notes: 'ORM' },
    'Newtonsoft.Json': { target: 'JSON.parse/stringify', version: 'built-in', notes: 'Native JSON support' },
    'System.Text.Json': { target: 'JSON.parse/stringify', version: 'built-in', notes: 'Native JSON support' },
    xunit: { target: 'jest', version: '^29.0.0', notes: 'Testing framework' },
    nunit: { target: 'jest', version: '^29.0.0', notes: 'Testing framework' },
    'Microsoft.Extensions.Logging': { target: 'winston', version: '^3.11.0', notes: 'Logging library' },
    AutoMapper: { target: 'class-transformer', version: '^0.5.1', notes: 'Object transformation' },
  },
  'vb6:csharp': {
    ADODB: { target: 'Microsoft.EntityFrameworkCore', version: '8.0.0', notes: 'ADO DB → EF Core' },
    MSXML2: { target: 'System.Xml', version: 'stdlib', notes: 'MSXML → System.Xml / XDocument' },
    Scripting: { target: 'System.IO', version: 'stdlib', notes: 'FileSystemObject → System.IO' },
    WinHttp: { target: 'System.Net.Http', version: 'stdlib', notes: 'WinHttp → HttpClient' },
    DAO: { target: 'Microsoft.EntityFrameworkCore', version: '8.0.0', notes: 'DAO → EF Core' },
    Crystal: { target: 'FastReport.Core', version: '2024.1.0', notes: 'Crystal Reports → FastReport' },
    'Microsoft.VisualBasic': { target: 'Microsoft.VisualBasic', version: '6.0.0', notes: 'VB compatibility runtime (NuGet)' },
  },
  'javascript:typescript': {
    react: { target: 'react', version: '^18.0.0', notes: 'Add @types/react for type definitions' },
    'react-dom': { target: 'react-dom', version: '^18.0.0', notes: 'Add @types/react-dom' },
    lodash: { target: 'lodash', version: '^4.17.21', notes: 'Add @types/lodash' },
    axios: { target: 'axios', version: '^1.6.0', notes: 'Typings included in package' },
    express: { target: 'express', version: '^4.18.0', notes: 'Add @types/express' },
    jest: { target: 'jest', version: '^29.0.0', notes: 'Add @types/jest' },
    webpack: { target: 'webpack', version: '^5.90.0', notes: 'Add ts-loader for TypeScript support' },
    moment: { target: 'dayjs', version: '^1.11.0', notes: 'Lighter alternative with built-in TS types' },
    vue: { target: 'vue', version: '^3.4.0', notes: 'Vue 3 has first-class TypeScript support' },
    next: { target: 'next', version: '^14.0.0', notes: 'TypeScript is first-class in Next.js' },
  },
  'php5:php8': {
    'guzzlehttp/guzzle': { target: 'guzzlehttp/guzzle', version: '^7.8.0', notes: 'PHP 8 compatible release' },
    'symfony/symfony': { target: 'symfony/symfony', version: '^7.0.0', notes: 'Symfony 7 requires PHP 8.2+' },
    'doctrine/dbal': { target: 'doctrine/dbal', version: '^3.8.0', notes: 'PHP 8 compatible release' },
    'doctrine/orm': { target: 'doctrine/orm', version: '^3.1.0', notes: 'PHP 8 compatible release' },
    'phpunit/phpunit': { target: 'phpunit/phpunit', version: '^11.0.0', notes: 'PHPUnit 11 for PHP 8.2+' },
    phpunit: { target: 'phpunit/phpunit', version: '^11.0.0', notes: 'PHPUnit 11 for PHP 8.2+' },
    'monolog/monolog': { target: 'monolog/monolog', version: '^3.5.0', notes: 'PHP 8 compatible release' },
    monolog: { target: 'monolog/monolog', version: '^3.5.0', notes: 'PHP 8 compatible release' },
    'illuminate/database': { target: 'illuminate/database', version: '^11.0.0', notes: 'Laravel 11 for PHP 8.2+' },
  },
  'php:php8': {
    'guzzlehttp/guzzle': { target: 'guzzlehttp/guzzle', version: '^7.8.0', notes: 'PHP 8 compatible release' },
    'symfony/symfony': { target: 'symfony/symfony', version: '^7.0.0', notes: 'Symfony 7 requires PHP 8.2+' },
    'doctrine/dbal': { target: 'doctrine/dbal', version: '^3.8.0', notes: 'PHP 8 compatible release' },
    'phpunit/phpunit': { target: 'phpunit/phpunit', version: '^11.0.0', notes: 'PHPUnit 11 for PHP 8.2+' },
    phpunit: { target: 'phpunit/phpunit', version: '^11.0.0', notes: 'PHPUnit 11 for PHP 8.2+' },
    monolog: { target: 'monolog/monolog', version: '^3.5.0', notes: 'PHP 8 compatible release' },
    'illuminate/database': { target: 'illuminate/database', version: '^11.0.0', notes: 'Laravel 11 for PHP 8.2+' },
  },
  'objectivec:swift': {
    Foundation: { target: 'Foundation', version: 'stdlib', notes: 'Direct Swift equivalent in stdlib' },
    UIKit: { target: 'UIKit', version: 'stdlib', notes: 'Use SwiftUI or UIKit — both available in Swift' },
    CoreData: { target: 'CoreData', version: 'stdlib', notes: 'Direct Swift equivalent' },
    AFNetworking: { target: 'Alamofire', version: '5.9.0', notes: 'Idiomatic Swift HTTP networking' },
    Masonry: { target: 'SnapKit', version: '5.7.0', notes: 'Swift AutoLayout DSL' },
    SDWebImage: { target: 'Kingfisher', version: '7.11.0', notes: 'Swift image caching library' },
    Mantle: { target: 'Codable', version: 'stdlib', notes: 'Mantle JSON mapping → Swift Codable' },
  },
  'cpp:rust': {
    boost: { target: '(multiple crates)', version: 'n/a', notes: 'No single equivalent — use specific crates' },
    'boost.asio': { target: 'tokio', version: '1.36.0', notes: 'Async I/O runtime' },
    openssl: { target: 'openssl', version: '0.10.64', notes: 'OpenSSL bindings' },
    libcurl: { target: 'reqwest', version: '0.12.0', notes: 'HTTP client' },
    gtest: { target: 'built-in', version: 'stdlib', notes: 'Rust has a built-in test framework' },
    spdlog: { target: 'tracing', version: '0.1.40', notes: 'Structured logging' },
    'nlohmann/json': { target: 'serde_json', version: '1.0.114', notes: 'JSON serialization' },
    fmt: { target: 'std::fmt', version: 'stdlib', notes: 'Formatting built into the standard library' },
    sqlite3: { target: 'rusqlite', version: '0.31.0', notes: 'SQLite bindings' },
    protobuf: { target: 'prost', version: '0.12.3', notes: 'Protocol Buffers for Rust' },
  },
  'delphi:csharp': {
    Indy: { target: 'System.Net.Http', version: 'stdlib', notes: 'Indy networking → .NET HttpClient' },
    FireDAC: { target: 'Microsoft.EntityFrameworkCore', version: '8.0.0', notes: 'FireDAC → EF Core' },
    UniDAC: { target: 'Dapper', version: '2.1.0', notes: 'Universal DAC → Dapper micro-ORM' },
    FastReport: { target: 'FastReport.Core', version: '2024.1.0', notes: 'FastReport for .NET Core' },
    DevExpress: { target: 'DevExpress.WindowsForms', version: '24.1.0', notes: 'DevExpress .NET component' },
    SynEdit: { target: 'AvalonEdit', version: '6.3.0', notes: 'Syntax-highlighting editor for WPF' },
  },
  'bash:python': {
    curl: { target: 'requests', version: '^2.31.0', notes: 'curl HTTP calls → requests library' },
    wget: { target: 'requests', version: '^2.31.0', notes: 'wget downloads → requests library' },
    jq: { target: 'json', version: 'stdlib', notes: 'jq → stdlib json module' },
    awk: { target: 'csv', version: 'stdlib', notes: 'awk text processing → csv / re modules' },
    sed: { target: 're', version: 'stdlib', notes: 'sed → re (regex) module' },
    grep: { target: 're', version: 'stdlib', notes: 'grep → re (regex) module' },
    find: { target: 'pathlib', version: 'stdlib', notes: 'find → pathlib.Path.rglob()' },
    ssh: { target: 'paramiko', version: '^3.4.0', notes: 'SSH → paramiko library' },
    rsync: { target: 'shutil', version: 'stdlib', notes: 'rsync-like copy → shutil.copytree()' },
    tar: { target: 'tarfile', version: 'stdlib', notes: 'tar → tarfile module' },
  },
  'plsql:java': {
    DBMS_OUTPUT: { target: 'slf4j-api', version: '2.0.9', notes: 'DBMS_OUTPUT → SLF4J logging' },
    DBMS_JOB: { target: 'spring-batch', version: '5.1.0', notes: 'DBMS_JOB scheduler → Spring Batch' },
    DBMS_SCHEDULER: { target: 'spring-batch', version: '5.1.0', notes: 'DBMS_SCHEDULER → Spring Batch' },
    UTL_FILE: { target: 'java.nio', version: 'stdlib', notes: 'UTL_FILE → java.nio.file' },
    UTL_HTTP: { target: 'okhttp', version: '4.12.0', notes: 'UTL_HTTP → OkHttp' },
    APEX_MAIL: { target: 'spring-boot-starter-mail', version: '3.2.0', notes: 'APEX_MAIL → Spring Mail' },
    DBMS_SQL: { target: 'spring-data-jpa', version: '3.2.0', notes: 'Dynamic SQL → JPA criteria API' },
    UTL_SMTP: { target: 'spring-boot-starter-mail', version: '3.2.0', notes: 'UTL_SMTP → Spring Mail' },
  },
  'perl:python': {
    Moose: { target: 'attrs', version: '^23.2.0', notes: 'Moose OO system → attrs / dataclasses' },
    DBI: { target: 'sqlalchemy', version: '^2.0.0', notes: 'DBI → SQLAlchemy' },
    'LWP::UserAgent': { target: 'requests', version: '^2.31.0', notes: 'LWP → requests HTTP library' },
    Carp: { target: 'logging', version: 'stdlib', notes: 'Carp → Python logging module' },
    'List::Util': { target: 'functools', version: 'stdlib', notes: 'List::Util → functools / itertools' },
    'Scalar::Util': { target: 'typing', version: 'stdlib', notes: 'Scalar::Util → Python built-ins + typing' },
    'File::Basename': { target: 'pathlib', version: 'stdlib', notes: 'File::Basename → pathlib.Path' },
    'File::Path': { target: 'pathlib', version: 'stdlib', notes: 'File::Path → pathlib.Path' },
    POSIX: { target: 'os', version: 'stdlib', notes: 'POSIX → os module' },
    'Getopt::Long': { target: 'argparse', version: 'stdlib', notes: 'Getopt::Long → argparse' },
  },
};

function normalizeLang(lang: string): string {
  const normalized = lang.toLowerCase().replace(/[^a-z0-9]/g, '');
  if (normalized === 'cobolas400' || normalized === 'cobol400') return 'cobol';
  return normalized;
}

function suggestUnknownTarget(
  source: string,
  sourceLanguage: string,
  targetLanguage: string,
): { target: string; version: string; notes: string } {
  const src = normalizeLang(sourceLanguage);
  const tgt = normalizeLang(targetLanguage);

  // Same ecosystem — keep the name (e.g. Java → Kotlin)
  if (src === tgt || (src === 'java' && tgt === 'kotlin') || (src === 'kotlin' && tgt === 'java')) {
    return { target: source, version: 'latest', notes: 'Verify compatibility in target ecosystem' };
  }

  // COBOL copybooks are uppercase — convert to PascalCase as a class/module name hint
  if (src === 'cobol' && source === source.toUpperCase()) {
    const pascal = source.charAt(0).toUpperCase() + source.slice(1).toLowerCase();
    return { target: pascal, version: 'n/a', notes: 'Manual review required — copybook → module mapping' };
  }

  return { target: source, version: 'n/a', notes: 'Manual review required' };
}

export function proposeDependencyMappings(
  sourceLanguage: string,
  targetLanguage: string,
  detectedDeps: DepRef[],
  existing?: DependencyEntry[] | null,
): DependencyEntry[] | null {
  // Preserve user edits from a previous session
  if (existing && existing.length > 0) return existing;
  if (detectedDeps.length === 0) return null;

  const src = normalizeLang(sourceLanguage);
  const tgt = normalizeLang(targetLanguage);
  const pairKey = `${src}:${tgt}`;
  const mappings = KNOWN_MAPPINGS[pairKey] ?? {};

  return detectedDeps.map((dep) => {
    const kind: DepKind = dep.kind ?? 'external-lib';

    // Non-external dependencies (copybooks, programs, maps, tables, datasets) are
    // internal to the migration — never an external package with a version.
    if (kind !== 'external-lib') {
      const p = internalProposal(dep);
      return {
        id: crypto.randomUUID(),
        source: dep.name,
        target: p.target,
        version: p.version,
        notes: p.notes,
        status: 'auto' as const,
        kind,
        verify: false,
      };
    }

    // External libraries — map to a known target package, or flag for registry verification.
    const name = dep.name;
    const match = mappings[name] ?? mappings[name.toLowerCase()];
    if (match) {
      return {
        id: crypto.randomUUID(),
        source: name, target: match.target, version: match.version, notes: match.notes,
        status: 'auto' as const, kind, verify: false,
      };
    }
    const prefixMatch = Object.entries(mappings).find(([key]) => name.toLowerCase().startsWith(key.toLowerCase()));
    if (prefixMatch) {
      const [, val] = prefixMatch;
      return {
        id: crypto.randomUUID(),
        source: name, target: val.target, version: val.version, notes: `${val.notes} (prefix match)`,
        status: 'auto' as const, kind, verify: false,
      };
    }
    // No known mapping — this is a guess. Mark it for verification (do not present as authoritative).
    const fallback = suggestUnknownTarget(name, sourceLanguage, targetLanguage);
    return {
      id: crypto.randomUUID(),
      source: name, target: fallback.target, version: fallback.version,
      notes: `${fallback.notes} — verify the package exists in the target registry`,
      status: 'auto' as const, kind, verify: true,
    };
  });
}
