const shell = require('shelljs')
const {
  requireValue,
  execShell
} = require('./services/utils')

const getVersion = require("./services/version");

module.exports = async (options, logger) => {
  if (!shell.which('git')) {
    logger('This script requires git'.red);
    return 1
  }

  const versionInfo = getVersion(options, logger)

  let {
    branch = process.env.TARGET_BRANCH || versionInfo.branch || requireValue('branch'),
    build_id = process.env.BUILD_ID || versionInfo.build_id || requireValue('build'),
    version = process.env.VERSION || versionInfo.version || requireValue('version'),
    email = process.env.NPM_EMAIL || requireValue('email'),
    registry = process.env.NPM_REGISTRY || 'https://registry.npmjs.org/',
    npm_user = process.env.NPM_APP_USERNAME || requireValue('npm_user'),
    npm_token = process.env.NPM_APP_TOKEN || requireValue('npm_token'),
    bb_user = process.env.BITBUCKET_APP_USERNAME || requireValue('bb_user'),
    bb_token = process.env.BITBUCKET_APP_TOKEN || requireValue('bb_token'),
    tag_prefix = process.env.TAG_PREFIX || '',
    debug = process.env.DEBUG || false
  } = options


  // Retrieve the Git remote URL associated with the repository
  const gitRemoteUrl = execShell('git config --get remote.origin.url').toString().trim();
  // Extract the repository name from the remote URL
  const repoName = gitRemoteUrl.split('/').pop().replace('.git', '');

  // Add tags based on the branch name and version number
  let tags = [`@${version}`];
  if (branch === 'main') {
    tags.push('@latest');
  } else if (branch === 'develop') {
    tags.push('@next');
  }

  if (tag_prefix) {
    tags.push(tag_prefix);
  }

  // Determine if the repository uses workspaces
  const rootPackageJsonPath = path.join(process.cwd(), 'package.json');
  const hasWorkspaces = fs.existsSync(rootPackageJsonPath) && fs.existsSync(rootPackageJsonPath) && JSON.parse(fs.readFileSync(rootPackageJsonPath)).workspaces;

  logger(`Attempting to log into npm registry ${registry}: User: ${npm_user} Email: ${email} & Token: ${npm_token.substring(0, 5) + "..."}`.gray)

  // Set the npm registry to the specified registry
  execShell(`npm config set registry ${registry}`);
  // Login to npm using the environment variables
  execShell(`npm login --registry=${registry} --scope=@${npm_user} --username=${npm_user} --password=${npm_token} --email=${email}`);

  if (!debug) {
    // Publish the packages to npm with the specified tags and the --workspaces flag if necessary
    const publishCommand = `npm publish --tag ${tags.join(' ')} --access public${hasWorkspaces ? ' --workspaces' : ''}`;
    execShell(publishCommand);

    logger(`Tagging git with: Version ${version}; Build-Id ${build_id} - "${tags.join(' ')}"`.gray)

    // Push the tags back to the remote repository
    execShell(`git tag  -f -a ${tags.join(' ')} -m "Version:${version} Build:${build_id} [skip ci]"`)

    // Construct the Git remote URL using the repository slug and Bitbucket username
    const gitRemoteUrl = `https://bitbucket.org/${bb_user}/${repoName}.git`

    logger(`Attempting to push tags back to origin using: ${gitRemoteUrl} + "..."}`.gray)

    execShell(`git push origin --tags --quiet --force ${gitRemoteUrl}:${bb_token}`)
  }
}

