#!/usr/bin/env node

const fs = require('fs');
const path = require('path');

// Function to generate a timestamp for the migration filename
function generateTimestamp() {
  const now = new Date();
  const year = now.getFullYear();
  const month = String(now.getMonth() + 1).padStart(2, '0');
  const day = String(now.getDate()).padStart(2, '0');
  const hours = String(now.getHours()).padStart(2, '0');
  const minutes = String(now.getMinutes()).padStart(2, '0');
  const seconds = String(now.getSeconds()).padStart(2, '0');
  
  return `${year}${month}${day}${hours}${minutes}${seconds}`;
}

// Function to parse SQL CREATE TABLE statement
function parseCreateTable(sql) {
  // Extract table name
  const tableNameMatch = sql.match(/CREATE TABLE `([^`]+)`/i);
  if (!tableNameMatch) {
    throw new Error('Could not find table name in SQL statement');
  }
  const tableName = tableNameMatch[1];
  
  // Extract column definitions
  const columnsSection = sql.match(/\(([^)]+)\)/)[1];
  
  // Split by commas, but be careful with commas inside parentheses (for default values)
  let depth = 0;
  let columns = [];
  let currentColumn = '';
  
  for (let i = 0; i < columnsSection.length; i++) {
    const char = columnsSection[i];
    if (char === '(') depth++;
    if (char === ')') depth--;
    
    if (char === ',' && depth === 0) {
      columns.push(currentColumn.trim());
      currentColumn = '';
    } else {
      currentColumn += char;
    }
  }
  if (currentColumn.trim()) {
    columns.push(currentColumn.trim());
  }
  
  // Filter out non-column definitions (like PRIMARY KEY)
  const columnDefs = columns.filter(col => col.trim().startsWith('`'));
  
  // Extract primary key
  const primaryKeyMatch = columnsSection.match(/PRIMARY KEY \(`([^`]+)`\)/i);
  const primaryKey = primaryKeyMatch ? primaryKeyMatch[1] : null;
  
  // Extract table options
  const engineMatch = sql.match(/ENGINE=(\w+)/i);
  const engine = engineMatch ? engineMatch[1] : null;
  
  const charsetMatch = sql.match(/CHARSET=([^\s]+)/i);
  const charset = charsetMatch ? charsetMatch[1] : null;
  
  const collateMatch = sql.match(/COLLATE=([^\s]+)/i);
  const collate = collateMatch ? collateMatch[1] : null;
  
  const commentMatch = sql.match(/COMMENT='([^']+)'/i);
  const comment = commentMatch ? commentMatch[1] : null;
  
  return {
    tableName,
    columns: columnDefs,
    primaryKey,
    engine,
    charset,
    collate,
    comment
  };
}

// Function to convert SQL column definition to Knex column builder
function convertColumnToKnex(columnDef) {
  // Extract column name
  const nameMatch = columnDef.match(/`([^`]+)`/);
  if (!nameMatch) return null;
  const name = nameMatch[1];
  
  // Determine column type
  let type = '';
  let knexType = '';
  
  if (columnDef.includes('varchar')) {
    const sizeMatch = columnDef.match(/varchar\((\d+)\)/i);
    const size = sizeMatch ? parseInt(sizeMatch[1]) : 255;
    type = `varchar(${size})`;
    knexType = `string('${name}', ${size})`;
  } else if (columnDef.includes('datetime')) {
    type = 'datetime';
    knexType = `datetime('${name}')`;
  } else if (columnDef.includes('tinyint')) {
    type = 'tinyint';
    knexType = `boolean('${name}')`;
  } else {
    // Default to string if type is not recognized
    knexType = `string('${name}')`;
  }
  
  // Check for NOT NULL
  const isNullable = !columnDef.includes('NOT NULL');
  if (isNullable) {
    knexType += '.nullable()';
  }
  
  // Check for DEFAULT value
  const defaultMatch = columnDef.match(/DEFAULT\s+(?:'([^']+)'|(\d+))/i);
  if (defaultMatch) {
    const defaultValue = defaultMatch[1] || defaultMatch[2];
    if (type === 'tinyint') {
      knexType += `.defaultTo(${defaultValue})`;
    } else {
      knexType += `.defaultTo('${defaultValue}')`;
    }
  }
  
  // Check for character set and collation
  if (columnDef.includes('CHARACTER SET') || columnDef.includes('COLLATE')) {
    const charsetMatch = columnDef.match(/CHARACTER SET\s+([^\s]+)/i);
    const collateMatch = columnDef.match(/COLLATE\s+([^\s]+)/i);
    
    if (charsetMatch) {
      knexType += `.charset('${charsetMatch[1]}')`;
    }
    
    if (collateMatch) {
      knexType += `.collate('${collateMatch[1]}')`;
    }
  }
  
  return knexType;
}

// Function to generate Knex migration file content
function generateKnexMigration(parsedTable) {
  const { tableName, columns, primaryKey, engine, charset, collate, comment } = parsedTable;
  
  let knexColumns = columns.map(convertColumnToKnex).filter(Boolean);
  
  let migrationContent = `exports.up = function(knex) {
  return knex.schema.createTable('${tableName}', function(table) {
${knexColumns.map(col => `    table.${col};`).join('\n')}
`;

  if (primaryKey) {
    migrationContent += `    table.primary(['${primaryKey}']);\n`;
  }

  if (engine || charset || collate || comment) {
    migrationContent += `    // Table options\n`;
    
    if (comment) {
      migrationContent += `    table.comment('${comment}');\n`;
    }
  }

  migrationContent += `  })`;

  if (engine || charset || collate) {
    migrationContent += `.options({`;
    
    const options = [];
    if (engine) options.push(`engine: '${engine}'`);
    if (charset) options.push(`charset: '${charset}'`);
    if (collate) options.push(`collate: '${collate}'`);
    
    migrationContent += `\n    ${options.join(',\n    ')}\n  })`;
  }

  migrationContent += `;\n};

exports.down = function(knex) {
  return knex.schema.dropTable('${tableName}');
};
`;

  return migrationContent;
}

// Main function
function main() {
  // Get SQL from command line argument or stdin
  let sql = '';
  
  if (process.argv.length > 2) {
    // Read from file if provided
    const filePath = process.argv[2];
    sql = fs.readFileSync(filePath, 'utf8');
  } else {
    return console.log('No file provided');
  }
  
  try {
    const parsedTable = parseCreateTable(sql);
    const migrationContent = generateKnexMigration(parsedTable);
    
    // Generate filename with timestamp
    const timestamp = generateTimestamp();
    const filename = `${timestamp}_create_${parsedTable.tableName}_table.js`;
    
    // Write to file
    fs.writeFileSync(filename, migrationContent);
    console.log(`Migration file created: ${filename}`);
    
    // Also output to console
    console.log('\nMigration content:');
    console.log(migrationContent);
  } catch (error) {
    console.error('Error:', error.message);
  }
}

main();