const chalk = require('chalk')
const ora = require('ora')
const { getCodeLibrary, createCodeLibrary, listCodeLibraries } = require('../lib/api')
const { getVersions } = require('../lib/version')

async function copyCommand(templateId, options) {
  try {
    const { from, to } = options

    if (!from || !to || !Array.isArray(to) || to.length === 0) {
      console.error(chalk.red('Error: --from and --to are required'))
      process.exit(1)
    }

    const spinner = ora(`Copying ${templateId} from ${from}...`).start()

    // Find source template by templateId/snippetId
    spinner.text = `Finding template in ${from}...`
    const templateLibs = await listCodeLibraries(from)
    const items = Array.isArray(templateLibs) ? templateLibs : Object.values(templateLibs || {})
    const sourceLib = items.find((lib) => lib.templateId === templateId || lib.snippetId === templateId)

    if (!sourceLib) {
      spinner.fail(`Template ${templateId} not found in app ${from}`)
      process.exit(1)
    }

    // Get full template details using its ID
    spinner.text = `Fetching template details from ${from}...`
    const fullSourceLib = await getCodeLibrary(from, sourceLib.id)

    if (!fullSourceLib) {
      spinner.fail(`Template ${templateId} not found in app ${from}`)
      process.exit(1)
    }

    // Get versions if they exist
    let versions = {}
    try {
      versions = await getVersions(from, fullSourceLib.id)
    } catch (error) {
      spinner.warn('Could not fetch versions')
    }

    spinner.succeed(`Found template: ${fullSourceLib.name || templateId}`)

    // Copy to each target app
    let successCount = 0
    let failCount = 0
    for (const targetAppId of to) {
      const copySpinner = ora(`Copying to ${targetAppId}...`).start()

      try {
        // Prepare template payload (exclude id and version-specific fields)
        const libData = { ...fullSourceLib }
        delete libData.id
        delete libData.createdAt
        delete libData.updatedAt
        delete libData.createdBy
        delete libData.updatedBy
        delete libData.versionCount

        // Ensure code is a string (not an object with raw/compiled)
        if (libData.code && typeof libData.code === 'object') {
          libData.code = libData.code.raw || libData.code.compiled || JSON.stringify(libData.code)
        }

        // Ensure all string fields are actually strings
        const stringFields = ['name', 'description', 'snippetId', 'type', 'codeType', 'appType', 'image']
        for (const field of stringFields) {
          if (libData[field] !== undefined && libData[field] !== null && typeof libData[field] !== 'string') {
            libData[field] = String(libData[field])
          }
        }

        // Create in target app
        copySpinner.text = `Creating template in ${targetAppId}...`
        await createCodeLibrary(targetAppId, libData)

        // Copy versions if they exist
        if (Object.keys(versions).length > 0) {
          copySpinner.text = `Copying versions to ${targetAppId}...`
          // Note: Version copying would need direct CMS/database access
          // For now, we'll just create the template
          copySpinner.warn('Version history copying requires direct CMS/database access')
        }

        copySpinner.succeed(`Successfully copied to ${targetAppId}`)
        successCount++
      } catch (error) {
        copySpinner.fail(`Failed to copy to ${targetAppId}: ${error.message}`)
        failCount++
      }
    }

    // Show summary
    if (failCount === 0 && successCount > 0) {
      console.log(chalk.green(`\n✓ Successfully copied ${templateId} to ${successCount} app(s)`))
    } else if (successCount > 0 && failCount > 0) {
      console.log(chalk.yellow(`\n⚠ Partially copied: ${successCount} succeeded, ${failCount} failed`))
      process.exit(1)
    } else {
      console.log(chalk.red(`\n✗ Failed to copy ${templateId} to any app`))
      process.exit(1)
    }
  } catch (error) {
    console.error(chalk.red(`\n✗ Copy failed: ${error.message}`))
    process.exit(1)
  }
}

module.exports = copyCommand

